Where opencode stores session history
The opencode layout supported here stores sessions in a SQLite database at ~/.local/share/opencode/opencode.db, or $XDG_DATA_HOME/opencode/opencode.db when configured:
~/.local/share/opencode/opencode.dbIt follows the XDG base directory spec, so $XDG_DATA_HOME/opencode/opencode.db wins if that variable is set. That applies on macOS too, where most apps would use ~/Library/Application Support.
In this supported layout, sessions are database rows rather than individual JSONL files. Query SQLite to inspect them instead of assuming a recursive text search can extract a conversation. Older file-based layouts are outside this adapter's scope.
The four tables that matter
project -- id (sha1), worktree (the project directory), vcs, time_*
session -- id ("ses_…"), project_id, parent_id, slug, title, directory,
-- model (JSON), tokens_* (5 columns), cost, time_created,
-- time_updated, time_archived
message -- id ("msg_…"), session_id, time_created, data (JSON envelope)
part -- id ("prt_…"), message_id, session_id, time_created, data (JSON body)The database has more tables (workspace, todo, permission, event, credential and migration bookkeeping), but a transcript is session → message → part.
message.data is a JSON envelope: role, modelID, providerID, tokens{input,output,reasoning,cache{read,write}}, cost, time{created,completed}. part.data is the body, with a type of text, reasoning, tool, file, step-start, step-finish and others.
Sub-agent sessions
A session with a non-null parent_id is a sub-agent run spawned by another session. The viewer hides these from the ordinary history list but includes their recorded work in statistics. They can contain usage and costs; a local model, provider pricing or missing fields can yield zero recorded cost. A sub-agent run is not proof of a separately billed API call.
Open it read-only
opencode's TUI may be writing while you inspect the database. Use a read-only connection to avoid accidental writes; busy or changing databases can still require retrying after activity settles. The command also respects a configured XDG data root:
sqlite3 "file:${XDG_DATA_HOME:-$HOME/.local/share}/opencode/opencode.db?mode=ro" ".tables"Reading an opencode transcript with SQL
List sessions with their project and cost, newest first:
SELECT s.id, p.worktree, s.title, s.cost,
datetime(s.time_created/1000, 'unixepoch') AS created
FROM session s
JOIN project p ON p.id = s.project_id
WHERE s.parent_id IS NULL
ORDER BY s.time_created DESC
LIMIT 20;Print one session's text, in order:
SELECT json_extract(m.data, '$.role') AS role,
json_extract(pt.data, '$.text') AS text
FROM message m
JOIN part pt ON pt.message_id = m.id
WHERE m.session_id = 'ses_...'
AND json_extract(pt.data, '$.type') = 'text'
ORDER BY m.time_created, pt.time_created;Sum session-recorded costs per project:
SELECT p.worktree, ROUND(SUM(s.cost), 2) AS usd, COUNT(*) AS sessions
FROM session s JOIN project p ON p.id = s.project_id
GROUP BY p.worktree ORDER BY usd DESC;The last query includes sub-agent rows on purpose. It sums session.cost, which is a stored value, not a provider invoice. Desktop statistics instead read assistant-message costs; the two aggregations need not agree if records are missing or inconsistent.
Why cost has to come from the database
opencode can use different providers or local models, so a price table keyed only by model name may not reflect that setup. The viewer reads modelID, tokens and cost from assistant-message records rather than repricing them with its catalog. Missing numeric message costs currently default to zero; this means unmeasured cost, not verified free work. Recorded cost is not an independently verified invoice. Compare financial decisions with the provider's actual usage report; see usage and cost boundaries.
How do I resume this session?
Run opencode --session SESSION_ID from the project's directory with opencode installed. The app offers terminal resume, not in-app opencode chat.
View and search opencode history
Install Sessions Viewer, select opencode, then choose a project to read its supported SQLite sessions. Use ⌘⇧F (macOS) or Ctrl+Shift+F (Windows/Linux) for session titles and saved user prompts across opencode projects, or switch to ID mode. This does not search assistant answers or tool output; see search scope.
Export Markdown, HTML or parsed-message JSON after reviewing private content; keep the native database for archival needs. Export limits include external/unreadable images. Continuing uses the installed opencode CLI in a terminal, not an opencode in-app chat. Sessions Viewer is an independent open-source project, not an official opencode product. Check privacy before resuming or sharing.
Source and limitations
Path, recorded-cost and viewer-operation wording reviewed on 2026-10-06 against the 0.6.0 opencode adapter and search implementation. This is source review and synthetic-test scope, not CLI runtime certification. Upstream: opencode documentation.
Reference scope: checked against the Sessions Viewer 0.6.0 adapters on 2026-10-05, not a compatibility guarantee for every CLI release. Shell examples use macOS/Linux paths and require
jq(orsqlite3for opencode). Replace placeholders with real values and use your configured data root. Text extraction does not replay tools, images or the active branch of a session tree. Command regressions use downloadable synthetic samples, not private sessions. Check the capability and evidence matrix for tested scope. Browsing is distinct from resuming or editing data; see privacy and data handling.
SQL examples target the database schema described above; they do not cover older file-based layouts. Read-only queries are distinct from explicit rename/trash/restore actions that write to the database. See missing-session troubleshooting.
Or open it in an app
Sessions Viewer queries this database read-only, hides sub-agent sessions from the list while still counting them in the stats, and shows opencode conversations next to your JSONL-based agents in the same view. It also reads Claude Code, Codex, Grok Build, Kimi Code, Pi and Antigravity CLI.
