Skip to main content

Module session

Module session 

Source
Expand description

Natively load — and continue — real Claude Code and Codex sessions.

Both tools persist their conversations as JSONL on disk:

  • Claude Code: ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl, one line per event in the Anthropic message format, linked by uuid/parentUuid.
  • Codex: ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl, where each line is a {timestamp, type, payload} envelope and the response_item lines form the canonical conversation.

Session::load auto-detects the format and normalizes either one into a provider-neutral Vec<ChatMessage> that can be handed straight back to a model (via OpenRouter or any OpenAI-compatible endpoint) to continue.

Provider-internal artifacts that don’t replay across vendors — Anthropic thinking blocks, Codex reasoning items — are dropped during normalization.

§Where this sits in supercode’s priorities

This module is the home of feature 1 (translate between session formats) and half of feature 2 (emulate-to-continue) — the load/emit surface for each harness (SessionFormat, from_*_str loaders, to_*_jsonl emitters). See AGENTS.md for the three ranked feature-priorities and the glue-tool positioning; the top priority is feature 3 (continue losslessly with massive token reduction), which this fidelity work exists to make trustworthy. opencode + pi loaders are built against the frozen docs/interop/opencode-pi-spec.md contract — OpenCode additionally reads its native SQLite store (opencode*.db, PARITY-3/PARITY-16) via rusqlite, reconstructing the same envelope form Session::from_opencode_str already parses for the JSON-tree surfaces.

Structs§

OpenCodeSqliteStoreStats
Cheap store-level counts — COUNT(*) only, no row hydration — for inspect’s “reports the audited real store’s sessions, messages, and parts” summary (PARITY-3 AC01).
Session
A normalized, replayable conversation loaded from a tool’s session log.
SessionMeta
Metadata recovered from a session log.

Enums§

OpenCodeStorageSurface
Which on-disk OpenCode storage surface is present under a data root (docs/interop/opencode-pi-spec.md §1.2/S9a): SQLite opencode*.db (or $OPENCODE_DB), legacy JSON tree generation B, or legacy JSON tree generation A. This is a filesystem classifier only — it answers “which generation is this?” for a corpus-discovery tool; it does not itself read/parse the surface. See Session::from_opencode_str’s docs for the envelope form any of these three surfaces synthesizes into, and Session::from_opencode_sqlite (PARITY-3/PARITY-16) for the rusqlite reader that reconstructs that same envelope form from Sqlite’s rows — JsonTreeA/JsonTreeB remain classifier-only (their session_diff round-trips via the JSON store per upstream’s own behavior even on a SQLite install, so nothing is silently lost by not reading the legacy trees directly).
SessionFormat
An on-disk session format supercode can both read and write.
SessionSource
Which tool produced a session log.

Constants§

OPENCODE_COMPACTED_TOOL_PLACEHOLDER
The placeholder opencode’s own replay substitutes for a tool part’s output once state.completed.time.compacted is set (message-v2.ts:293-296 @fd9ee43) — the REAL output is never actually erased from the record (S1); it survives in raw and in this loader’s metadata["oc_tool_output_compacted"].

Functions§

detect_opencode_storage_surface
Probe data_root (e.g. ~/.local/share/opencode) for the OpenCode storage surface present, per the discovery rules frozen in docs/interop/opencode-pi-spec.md §1.2/S9a: $OPENCODE_DB wins outright; otherwise glob opencode*.db (not just opencode.db — dev/beta channels suffix the filename, database.ts:43-55); otherwise look for the JSON tree generation-B marker (storage/migration); otherwise generation-A’s project/ subtree. Returns None if nothing is found.
looks_like_sqlite
Whether path should be routed to the OpenCode SQLite loader instead of the UTF-8 text path (PARITY-16): true when the file’s first 16 bytes are the SQLite magic, OR its extension is .db — the latter so a corrupted/truncated opencode*.db still gets rusqlite’s own “not a database” diagnostic (PARITY-3 AC03) instead of a confusing UTF-8 error. A non-existent path is NOT considered SQLite here — the missing-file diagnostic in that case comes from the normal load path (with_context at the CLI call sites), which already names the path clearly.
opencode_sqlite_corpus_envelope_text
Combined envelope text spanning every session in db_path (or up to limit_sessions) — for corpus-style scanning (the OpenCode SQLite corpus-audit path, PARITY-4). Safe to concatenate multiple sessions’ records into one text even though Session::from_opencode_str itself only keeps the LAST session line (single-session semantics) — the audit line-classifier (audit_opencode_line) scores each line independently and doesn’t care about session boundaries. Use Session::from_opencode_sqlite to load one session as a real Session.
opencode_sqlite_primary_id
D6: the same “most-recently-updated top-level session” selection Session::load/Session::from_opencode_sqlite make by default when no explicit session id is given — exposed so a CLI-level warning can name which one was chosen.
opencode_sqlite_session_ids
D6: list every session id in an OpenCode SQLite store (oldest first) — exposed so CLI callers (convert, inspect) can detect a multi-session store and warn before Session::load/Session::from_opencode_sqlite silently picks just the primary one. Previously nothing surfaced this: convert opencode.db --to X converted 1-of-N sessions with no warning and no way to name a different one.
opencode_sqlite_store_stats
Count sessions/messages/parts/todos in a real OpenCode SQLite store without loading any of them (PARITY-3 AC01).
resolve_opencode_parent_tool_use_ids
Resolve each opencode subagent (task) child session’s meta.parent_tool_use_id from its parent’s own task tool part callID (docs/interop/opencode-pi-spec.md §2.1 — the analogue of Claude Code’s agentId/parent_tool_use_id linkage, opencode-fields.md task.ts:145,171-176).