OpenCode

OpenCode is a SQLite-backed conversation backend. agentgrep reconstructs turns from the relational session/message/part tables. No searched store carries a fast prompt log, so --exhaustive is required for user text; assistant and reasoning parts additionally require conversation scope. Targeted effort cannot route this backend.

OpenCode does write a prompt-history log, but outside its data root — at ${XDG_STATE_HOME:-~/.local/state}/opencode/prompt-history.jsonl — and no store row covers that path yet, so it does not shorten the search today.

Base path: ~/.local/share/opencode (env overrides: XDG_DATA_HOME, OPENCODE_DB).

observed_version: opencode v1.18.15 (observed 2026-08-08).

OpenCode (anomalyco/opencode) stores conversations in a single SQLite database, opencode.db, under its XDG data directory (${XDG_DATA_HOME:-~/.local/share}/opencode). Non-stable install channels use opencode-<channel>.db, and OPENCODE_DB can relocate the database (an absolute path is used directly).

Stores

default store
default store
Role:

primary_chat

Format:

sqlite

Coverage:

default_search

Adapter:

opencode.db_sqlite.v1

Role:

primary_chat

Format:

json_object

Coverage:

catalog_only

Adapter:

-

Role:

prompt_history

Format:

jsonl

Coverage:

catalog_only

Adapter:

-

catalog store
catalog store
Role:

app_state

Format:

json_object

Coverage:

catalog_only

Adapter:

-

private store
private store
Role:

app_state

Format:

json_object

Coverage:

private

Adapter:

-

catalog store
catalog store
Role:

source_tree

Format:

opaque

Coverage:

catalog_only

Adapter:

-

catalog store
catalog store
Role:

cache

Format:

opaque

Coverage:

catalog_only

Adapter:

-

catalog store
catalog store
Role:

app_state

Format:

text

Coverage:

catalog_only

Adapter:

-

Role:

cache

Format:

text

Coverage:

catalog_only

Adapter:

-

opencode.db

opencode.db
default store
default store
opencode.db

SQLite store (Drizzle). Tables session (id, project_id, directory = working dir, title, version, time_created/updated, model, cost, tokens_*), message (id, session_id FK, data JSON with role/time; assistant messages carry top-level modelID/providerID/path.cwd, while user messages nest the selected model under model.modelID), and part (id, message_id FK, session_id, data JSON with type + payload). Searchable text lives in part.data: type text/reasoning -> text, subtask -> prompt. A conversation turn is reconstructed by joining part -> message -> session. Channel installs use opencode-<channel>.db; OPENCODE_DB overrides the path (also :memory:/absolute). The same file also carries the v2 event-sourced tables session_input, session_message, event/event_sequence, and todo; event is now populated on stable installs and mirrors the part transcript text, so it is left unsearched to avoid duplicate hits — the canonical transcript stays in session/message/part. Secret-bearing account, account_state, control_account, and credential tables are present but never enumerated — the adapter reads only text-bearing part rows.

Agent:

OpenCode

Role:

primary_chat

Format:

sqlite

Coverage:

default_search

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/opencode.db

Adapter:

opencode.db_sqlite.v1

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

yes

SQLite tables observed (1.18.15, 2026-08-08)

__drizzle_migrations columns:

id, hash, created_at, name, applied_at

account columns:

id, email, url, access_token, refresh_token, token_expiry, time_created, time_updated

account_state columns:

id, active_account_id, active_org_id

control_account columns:

email, url, access_token, refresh_token, token_expiry, active, time_created, time_updated

credential columns:

id, integration_id, label, value, connector_id, method_id, active, time_created, time_updated

data_migration columns:

name, time_completed

event columns:

id, aggregate_id, seq, type, data

event_sequence columns:

aggregate_id, seq, owner_id

message columns:

id, session_id, time_created, time_updated, data

migration columns:

id, time_completed

part columns:

id, message_id, session_id, time_created, time_updated, data

permission columns:

id, project_id, action, resource, time_created, time_updated

project columns:

id, worktree, vcs, name, icon_url, icon_color, time_created, time_updated, time_initialized, sandboxes, commands, icon_url_override

project_directory columns:

project_id, directory, type, strategy, time_created

session columns:

id, project_id, parent_id, slug, directory, title, version, share_url, summary_additions, summary_deletions, summary_files, summary_diffs, revert, permission, time_created, time_updated, time_compacting, time_archived, workspace_id, path, agent, model, cost, tokens_input, tokens_output, tokens_reasoning, tokens_cache_read, tokens_cache_write, metadata

session_context_epoch columns:

session_id, baseline, snapshot, baseline_seq

session_input columns:

id, session_id, prompt, delivery, admitted_seq, promoted_seq, time_created

session_message columns:

id, session_id, type, time_created, time_updated, data, seq

session_share columns:

session_id, id, secret, url, time_created, time_updated

todo columns:

session_id, content, status, priority, position, time_created, time_updated

workspace columns:

id, type, name, branch, directory, extra, project_id, time_used

The sole searchable OpenCode store. kind is derived from the joined message role (user -> prompt, else history).

opencode.storage_legacy

opencode.storage_legacy
catalog store
catalog store
opencode.storage_legacy

Pre-migration on-disk layout: one JSON file per session/message/part. A startup migration folds these into opencode.db; migrated installs keep a storage/session_diff/ of small per-session [] marker files and a storage/migration marker, with no searchable session/message/part JSON left. Documentary — relevant only to older, un-migrated installs.

Agent:

OpenCode

Role:

primary_chat

Format:

json_object

Coverage:

catalog_only

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/storage/{session,message,part}/**/*.json

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.prompt_history

opencode.prompt_history
catalog store
catalog store
opencode.prompt_history

Recalled prompt log, one JSON object per line with the key set {input, parts, mode}. input is the prompt text, parts holds {type, text, source} entries, and mode was only ever observed as normal. There is no timestamp and no session id, so a record here cannot be joined to a session in opencode.db. Not a duplicate of that database either: prompts present here can be absent from it entirely. Documented pending an adapter; wiring it would give OpenCode the fast prompt path it currently lacks.

Agent:

OpenCode

Role:

prompt_history

Format:

jsonl

Coverage:

catalog_only

Path:

${XDG_STATE_HOME or ${HOME}/.local/state}/opencode/prompt-history.jsonl

Adapter:

-

Data version:

-

Version strategies:

catalog_observation

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.config

opencode.config
catalog store
catalog store
opencode.config

Application config (opencode.json/opencode.jsonc): providers, agents, plugins, commands, UI settings. Configuration, not chat.

Agent:

OpenCode

Role:

app_state

Format:

json_object

Coverage:

catalog_only

Path:

${XDG_CONFIG_HOME or ${HOME}/.config}/opencode/opencode.{json,jsonc}

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.auth

opencode.auth
private store
private store
opencode.auth

Provider API keys and OAuth tokens. Documented but never enumerated.

Agent:

OpenCode

Role:

app_state

Format:

json_object

Coverage:

private

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/auth.json

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.snapshots

opencode.snapshots
catalog store
catalog store
opencode.snapshots

Per-project git repositories holding session file snapshots.

Agent:

OpenCode

Role:

source_tree

Format:

opaque

Coverage:

catalog_only

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/snapshot/

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.repos

opencode.repos
catalog store
catalog store
opencode.repos

Cache of cloned git repositories referenced during sessions.

Agent:

OpenCode

Role:

cache

Format:

opaque

Coverage:

catalog_only

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/repos/

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.logs

opencode.logs
catalog store
catalog store
opencode.logs

Timestamped application logs. Diagnostics, not chat content.

Agent:

OpenCode

Role:

app_state

Format:

text

Coverage:

catalog_only

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/log/

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

opencode.tool_output

opencode.tool_output
catalog store
catalog store
opencode.tool_output

Overflow storage for large tool output that exceeds inline limits.

Agent:

OpenCode

Role:

cache

Format:

text

Coverage:

catalog_only

Path:

${XDG_DATA_HOME or ${HOME}/.local/share}/opencode/tool-output/

Adapter:

-

Data version:

-

Version strategies:

-

Observed:

opencode v1.18.15 (2026-08-08)

Default search:

no

Record schema

Conversation database

opencode.db is a relational session message part schema (Drizzle). A conversation turn is reconstructed by joining a part row up to its message (for the role) and session (for the title and working directory). User text parts participate in prompt scope under --exhaustive; assistant and reasoning parts require --scope conversations or --scope all.

session table — one row per session:

Column

Type

Description

id

TEXT

Session id (primary key)

project_id

TEXT

Git remote/root hash, or global

directory

TEXT

Working directory, stored verbatim

title

TEXT

Session title

time_created / time_updated

INTEGER

Unix milliseconds

message table — id, session_id (FK), and a data JSON column. Assistant messages carry a top-level modelID/providerID/path.cwd; user messages instead nest the selected model under model.modelID, so agentgrep reads modelID and falls back to model.modelID:

{"role": "assistant", "modelID": "...", "providerID": "...",
 "time": {"created": 1779999665000}, "path": {"cwd": "..."}}

part table — id, message_id (FK), session_id, and a data JSON column holding one content part. The searchable text lives here:

Part type

Searchable field

text

text (user prompts and assistant replies)

reasoning

text (model thinking)

subtask

prompt

A part’s kind is derived from the joined message role (user → prompt, otherwise history). Tool, file, snapshot, patch, and step-marker parts are metadata and stay outside default search. Message timestamps are unix-milliseconds and are normalized to ISO-8601.

The same opencode.db file also carries OpenCode’s v2 event-sourced tables — session_input, session_message, event/event_sequence, and todo. The event table is now populated on stable installs and mirrors the part transcript text, so agentgrep leaves it unsearched to avoid duplicate hits; the canonical transcript stays in session/message/part. The secret-bearing account, account_state, control_account, and credential tables are present but never enumerated — the adapter reads only text-bearing part rows.

The legacy pre-migration layout (one JSON file per session, message, and part under storage/) is documented but no longer searched — current installs migrate it into opencode.db on startup.