10 — Agent Session Stores
Five supported runtimes expose capturable local session state; Amp is the exception that requires live structured-stream capture for complete evidence.
Summary
Maps session paths, formats, schemas, access methods, and stability risks across supported coding-agent runtimes. Verification cutoff: 2026-07-03. Evidence combines official docs, upstream source, and 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 versus reverse-engineered status determines the maintenance-risk rating. jackin❯'s roster gets full records; other agents get summaries at the end.
Question and scope
Where does each supported runtime persist session evidence, and how stable is each capture surface?
Method
The inventory combines official documentation, upstream source, and inspected local layouts for the versions recorded at the verification cutoff.
Findings
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) |
Implications for jackin❯
Implement provider-specific adapters with explicit evidence and stability labels, plus a structured-stream capture path for Amp.
Limitations and unknowns
Local layouts and undocumented schemas can change between releases; Kimi and Grok paths require in-container verification before relying on them.