10 — Agent Session Stores
10 — Agent Session Stores
Research conducted: 2026-07-03. Method: official docs + upstream source + live-disk inspection on macOS (versions inspected: Claude Code 2.1.199, codex-cli 0.142.5, opencode 1.17.10, amp 0.0.1783038096, grok 0.2.67, kimi 0.21.1; Gemini via docs/source). Facts observed only on disk are marked [observed]; documented vs reverse-engineered status is called out per agent — that distinction is the maintenance-risk rating for any capture feature. jackin❯'s roster (Claude, Codex, Amp, Kimi, OpenCode, Grok) gets full records; other agents get summaries at the end.
Claude Code (Anthropic)
- Store:
~/.claude/projects/<project-slug>/<session-uuid>.jsonl; subagents under<session>/subagents/; oversized tool outputs under<session>/tool-results/— paths officially documented (claude-directory). Slug = cwd with/and.→-[observed], undocumented. XDG variant~/.config/claude/projects/**exists on some installs — jackin❯'s usage monitor already watches both (crates/jackin-usage/src/token_monitor/claude.rs). Also:~/.claude/history.jsonl(prompt history),file-history/<session>/(pre-edit snapshots),stats-cache.json(cost aggregates). - Format: append-only JSONL, one file per session, plaintext incl. tool I/O.
- Schema: records carry
type,uuid/parentUuid(thread tree),sessionId,timestamp,cwd,gitBranch,version,isSidechain; assistant records embed the API-shapedmessagewithmodel, content blocks (text/tool_use/tool_result/thinking),usageincl. cache-creation/cache-read tokens [observed]. Record schema itself undocumented and evolving (each record self-stamps CLIversion). - Native features:
--continue,--resume <id|name>,--fork-session,/export(plain text),/rewind,/rename. Retention hazard:cleanupPeriodDaysdefault 30 auto-deletes transcripts;--no-session-persistenceexists. - Observer access: best-in-class — hooks deliver
transcript_pathpush-style on every event (hooks);-p --output-format stream-json; OTel with opt-in content up to raw API bodies (monitoring). - Stability: paths documented, schema not; the healthiest capture target of the six regardless — largest ecosystem parses it daily.
Codex CLI (OpenAI)
- Store:
$CODEX_HOME/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl(default~/.codex), archived sessions toarchived_sessions/; source-defined (recorder.rs). Plushistory.jsonl(0600) and a rebuildable SQLite metadata indexstate_5.sqlite[observed] — index name implies 5 schema iterations already. - Format: JSONL
RolloutLine {timestamp, type, payload}; first linesession_meta(id, cwd, cli_version, git info); thenresponse_item(messages, function calls/outputs, reasoning),turn_context,event_msg(token counts),compacted; 2026 additionsInterAgentCommunication,WorldState. - Native features:
codex resume [id|--last],codex exec resume;--ephemeralskips persistence. No export command — the rollout is the export. - Observer access:
codex exec --jsonevent stream;notifyhook;[otel]config (log events; only user prompts opt-in, no assistant bodies). - Stability: vendor explicitly treats the format as internal; Apache-2.0 source is the documentation. Déjà Vu's "pair with a vendor-blessed hedge" stance is right.
Amp (Sourcegraph)
- Store: threads are server-authoritative (Postgres on GCP — security) — but, new finding: a full local materialization exists:
~/.local/share/amp/threads/T-<uuid>.json, one pretty-printed JSON per thread with avrevision counter, plushistory.jsonlandsession.json[observed, undocumented]. Same XDG path family on macOS as Linux. - Schema [observed]:
messages[]with role, content blocks (text,thinkingincl. provider/signature,tool_use, tool results), per-messageusage(model, input/output/cache tokens, credits),usageLedger. - Native features: the richest thread CLI of any agent —
amp threads list|continue|fork|share|rename|archive|compactand native exports:amp threads markdown|export|raw(manual). Visibility tiers workspace/unlisted/private; public sharing retired 2026-06. - Observer access:
amp -x --stream-json("Claude Code-compatible stream JSON" — announcement),--stream-json-thinking; plugin event hooks (session.start,tool.call,tool.result); SDK. No OTel. - Stability: cloud store durable; local
threads/*.jsonis an undocumented sync surface on near-daily releases. Capture options are better than Déjà Vu assumed (local JSON + native markdown export exist), but all unblessed except stream-json.
Kimi Code (Moonshot)
- Store:
~/.kimi-code/sessions/<workDirKey>/<sessionId>/whereworkDirKey = wd_<slug>_<sha256(cwd)[:12]>— officially documented (data-locations), algorithm in MIT source (workdir-key.ts). Per-session:state.json+agents/main/wire.jsonl(+ per-subagentagents/<id>/wire.jsonl); globalsession_index.jsonl(append-only{sessionId, sessionDir, workDir}). Legacy Python-era~/.kimi/sessions/<md5>/<uuid>/still read by jackin❯'s monitor (crates/jackin-usage/src/token_monitor/kimi.rs) — the layouts differ; capture must handle the new one. - Format:
wire.jsonl= versioned append-only event log (first line{"type":"metadata","protocol_version":"1.4",…}[observed]) that the agent itself replays on resume — "use records, not state.json, when correctness depends on order" (source comment). Event vocabulary (complete, fromrecords/types.ts):turn.prompt/steer/cancel,context.append_message/append_loop_event/clear/apply_compaction/undo,usage.record {model, usage}(per-turn tokens incl. cache read/creation),permission.*,plan_mode.*,full_compaction.*,goal.*,forked. Thinking persists as plaintextthinkparts. Migration machinery ships in-tree (records/migration/). - Native features:
--continue,--session [id],/fork,/rename,kimi export [sessionId](ZIP),/export-md,kimi vis(browser visualizer). - Observer access:
--print --output-format stream-json; ACP server (kimi acp, ACP 0.23,session/updatenotifications);kimi server(REST/WS + OpenAPI); hooks (13 events, Beta,[[hooks]]in config.toml — notranscript_path, so the store must be located by recomputingworkDirKey). No OTel (vendor analytics only, opt-out). - Stability: strongest of the six — documented layout, MIT source, self-versioned protocol with in-tree migrations. Churn risk = the Python→TS transition itself (three doc hosts, layouts coexisting).
OpenCode (sst)
- Store: single SQLite DB
~/.local/share/opencode/opencode.dbsince v1.2.0 (2026-02-14, auto-migrated from the earlier per-file JSONstorage/tree) — release notes; Drizzle schema in source;OPENCODE_DBoverride;opencode db pathprints it [observed on 1.17.10]. - Schema:
sessionrows carryparent_id(forks/subagents),directory,title,share_url,cost(USD!) and token columns (input/output/reasoning/cache read/write),model;message.data/part.dataJSON blobs; part kinds text/reasoning/tool/file/patch/snapshot/compaction. The only store of the six with native dollar cost. - Native features:
--continue,--session <id>,--fork;opencode export [sessionID](JSON,--sanitize),opencode import <file|share URL>,opencode stats;/sharepublic links,share: manual|auto|disabled. - Observer access:
opencode serve— HTTP + OpenAPI + SSEGET /eventbus (message/part deltas live); plugin events (message.part.updated,tool.execute.before/after,session.*);opencode db [query]SQL shell; typed SDK. Undocumented OTLP trace wiring in source (Effect spans, no transcripts). - Stability: CLI/server/plugins documented; DB schema source-only, 38 migrations Jan–Jun 2026. One mutable DB means no per-session file to archive — capture should prefer the server API/plugin events or export command, exactly the "E-ish" path Déjà Vu named.
Grok (xAI "Grok Build")
The blank spot in prior research, now mapped. Official CLI (grok, beta since 2026-05-14, closed source); the npm/GitHub "grok-cli" projects are unaffiliated community wrappers that also write ~/.grok/ — a collision capture must not trip over.
- Store: officially only "
~/.grok/sessions" is documented (headless docs, enterprise). Fine layout [observed 0.2.67] + bundled~/.grok/README.md:~/.grok/sessions/<url-encoded-cwd>/<uuidv7-session-id>/containingchat_history.jsonl(typed records; assistant lines carrymodel_id,tool_calls; thinking stored encrypted —reasoning.encrypted_contentwith readable summary only),updates.jsonl(ACPsession/updatestream —agent_thought_chunkhere carries readable thinking,tool_call/tool_call_update, message chunks),summary.json(incl.chat_format_version, git root/branch/commit, counts),signals.json(token/latency metrics),rewind_points.jsonl,events.jsonl(undocumented telemetry-grade log),subagents/; per-cwdprompt_history.jsonl; FTS indexsessions/session_search.sqlite[observed]. - Native features:
-c/--continue,-r/--resume [id],-s/--session-id,/fork,/rewind,/share(remote URL);grok sessions list|search|delete;grok export <SESSION_ID>— Markdown transcript export, present in 0.2.67 help though absent from docs;grok trace <id>(tarball; uploads remotely by default,--localto keep on disk). - Observer access:
--output-format streaming-json(NDJSON of the same ACP vocabulary); ACP servergrok agent stdio; hooks withGROK_SESSION_ID/GROK_WORKSPACE_ROOTenv (Claude-compatible config shape; Grok even auto-reads Claude Code hooks/CLAUDE.md per llms.txt); no OTel. - Stability: weakest guarantees — beta, closed source, rapid churn (0.2.59→0.2.73 in June 2026), layout undocumented beyond the top dir; but the format self-declares
chat_format_version, andupdates.jsonl+ACP give a vendor-shaped event vocabulary. Déjà Vu's open question "verify in a live container" stands, now with a concrete checklist.
Cross-cutting: what a capture layer can watch (host side)
| Agent | Watch target | Kind |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl | append-only JSONL; hooks push transcript_path |
| Codex | ~/.codex/sessions/**/rollout-*.jsonl | append-only JSONL |
| Amp | ~/.local/share/amp/threads/T-*.json | rewritten JSON (v counter), cloud-authoritative; stream-json is the blessed live path |
| Kimi | ~/.kimi-code/sessions/wd_*/<id>/agents/*/wire.jsonl | append-only JSONL, versioned protocol |
| OpenCode | ~/.local/share/opencode/opencode.db (WAL) | SQLite; prefer SSE /event / plugins / export |
| Grok | ~/.grok/sessions/<enc-cwd>/<uuidv7>/{chat_history,updates}.jsonl | append-only JSONL, undocumented, chat_format_version stamped |
Retention hazards any archive must beat: Claude auto-deletes after 30 days by default; Gemini (if ever added) keeps 30 days/50 sessions; Amp's local files are a cloud sync surface; OpenCode is one mutable DB; Grok is beta-churning. jackin❯'s own eject/prune is currently the biggest hazard of all — it deletes the restored homes wholesale (30).
OTel reality check (full table in the source survey): only Claude Code, Codex, and Gemini export OTel at all, and only Gemini (prompts on by default, gen_ai.input/output.messages in traces, direct telemetry.outfile sink) plus fully-opted-in Claude carry reconstructable content. For Amp, OpenCode, Kimi, Grok — two-thirds of jackin❯'s roster — OTel does not exist as a capture channel. File/API surfaces are the only fleet-wide answer, confirming Déjà Vu's vector ranking empirically.
Other agents (context, summary records)
| Agent | Store | Status |
|---|---|---|
| Gemini CLI | ~/.gemini/tmp/<sha256(project)>/chats/session-*.jsonl — ConversationRecord + MessageRecord lines with per-message tokens, thoughts, tool calls; /chat share file.md native export; richest OTel of any agent (prompts default-on, telemetry.outfile file sink) | docs + source (session-management, telemetry); 30-day/50-session retention |
| Cursor IDE | state.vscdb SQLite (cursorDiskKV: composerData:*, bubbleId:*) in globalStorage | reverse-engineered only; churns with releases (01) |
| Cursor CLI | ~/.cursor/chats/<md5(cwd)>/<uuid>/store.db SQLite blob DAG | reverse-engineered; SpecStory reads it via topological sort (02) |
| Copilot (VS Code) | workspaceStorage/<hash>/chatSessions/*.json; native Chat: Export Chat... JSON | semi-documented |
| aider | .aider.chat.history.md — native markdown in-repo | documented; oldest native archive |
| Cline | VS Code globalStorage tasks + per-task markdown export | community-documented |
| Windsurf | encrypted protobufs | closed — SpecStory maintainer: "thrown away the key" (#26) |