Expand description
A reader with no discovery half, and so no Source of its own — the
shape is unverified, which is fine for a file a hook hands us and not fine
for an unattended sweep. See the module docs.
Gemini CLI chat sessions.
§Why this exists
Gemini ships gemini hooks migrate --from-claude, which copies Claude
Code’s hook commands into Gemini’s own settings. A recall-echo user who runs
it gets recall-echo archive-session wired into Gemini’s SessionEnd —
where it is handed a JSON document, not the JSON Lines transcript
crate::jsonl parses. Every line of that document fails to parse, the
conversation comes out empty, and the session is silently not archived.
So this module reads the shape Gemini writes, and archival sniffs the file rather than assuming its own. A migrated hook then works instead of quietly doing nothing.
§This shape is unverified
It was read off Gemini’s type declarations, not off a file produced by a
real session: one document, {sessionId, projectHash, startTime, lastUpdated, messages[], summary?}, with messages[].type in
user | gemini | info | error | warning, a content of Gemini’s
PartListUnion (a string, a part, or a list of parts), and toolCalls[]
and thoughts[] on model messages.
Everything here is therefore written to decline rather than guess: a
document without a messages array is not recognised, a message of an
unknown type is dropped, and content in an unexpected shape reads as empty.
The cost of being wrong is a session that is not archived — never a session
archived as something it was not.
There is no discovery half to this adapter for the same reason. Sweeping unverified transcripts into memory unattended is a different risk from parsing one a hook explicitly handed us, and it can be added the day someone confirms the format against a real file.
§What is dropped, and why
thoughts[] is the model’s private reasoning. Like Grok’s reasoning and
Codex’s developer role, it is not something the model asserted, so it
must not enter the graph as self-authored evidence — see the contract in
crate::transcript. info, error and warning messages are the
harness talking to the user; they are not turns at all.
Functions§
- is_
session_ document - Whether a JSON document looks like a Gemini chat session.
- parse_
session - Read a Gemini chat session into the universal conversation format.