Expand description
OpenCode: sessions in a SQLite database, not a JSONL log.
Format notes (verified on OpenCode 1.18.15, 2026-09-05, against the live
opencode.db on this machine):
- The store is
$XDG_DATA_HOME/opencode/opencode.db(or~/.local/share/opencode/opencode.db), a WAL SQLite database. agent-top opens it read-only and never writes, which honours the observe-only rule and does not block OpenCode’s own writes. sessionis one row per conversation and already carries the accounting:directory,agent(the agent type,build/explore/plan),model(a JSON blob{"id","providerID","variant"}),cost(US dollars, computed by OpenCode),tokens_input,tokens_output,tokens_reasoning,tokens_cache_read,tokens_cache_write,time_created,time_updated(epoch ms),parent_idandversion. A subagent is asessionrow whoseparent_idis the parent’s id.- Because OpenCode has already priced the session, its
costis used directly rather than re-priced from agent-top’s table: OpenCode runs third-party models (DeepSeek, and so on) that the table does not carry, and the harness’s own figure is the real one. So an OpenCode row’s cost is exact and never a floor, andunpriced_tokensis zero. messageis one row per message,dataJSON withrole(user/assistant) andtime{created, completed}in epoch ms. Ausermessage opens a turn; eachassistantmessage is one inference, fromcreatedtocompleted, and extends the turn it belongs to, which ends at the last reply before the next prompt. A reply with nocompletedis still in flight, so its inference and turn stay open. Assistant messages are also the turn count.partis one row per message part,dataJSON withtype. Atoolpart hastool(the name),callIDandstatewithstatus(completed/error/ …) andtime{start,end}in epoch ms, which is one tool span.step-start/step-finish,reasoning,textandpatchparts are not read.- MCP tool naming was not observable here (no MCP server is configured), so per-server MCP counts are not produced for OpenCode yet; every tool part is counted as a tool call and a span.
A session has no file of its own, so a tracker is addressed by a virtual
path <db>/<session id>: unique, stable, and with the session id as its
file stem, which is all the collector and the trace resolver need.
Structs§
- Open
Code Adapter - The OpenCode adapter. See the module notes for the store it reads.
- Open
Code Transcript - One OpenCode session as a
SessionSummary, read from the database. - Session
- One top-level conversation, enough to attribute it to a process and list it.
Functions§
- data_
dir $XDG_DATA_HOME/opencode, or~/.local/share/opencode.- db_path
- The session database, when it exists.
- recent_
sessions - Top-level sessions (no parent) written since
since, newest activity first. - session_
id_ of - The session id in a virtual path.
- session_
path - The virtual path that stands for a session on disk: the database path with the session id appended. Never opened as a file; only its stem is read.