Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
model aliases to priced Kimi K2 entries.

### Fixed (CLI)
- **OpenCode session cache keys now use real database paths.** Discovery now
emits one source per `opencode*.db` file and the parser iterates root sessions
inside that database, so shared session-cache fingerprinting stats the actual
SQLite file instead of a synthetic `<dbPath>:<sessionId>` identifier.
- **OpenCode child sessions are attributed to their root session.** The
OpenCode parser now walks the unarchived `session.parent_id` subtree so
child and grandchild agent sessions contribute token and tool usage under
Expand Down
19 changes: 10 additions & 9 deletions docs/providers/opencode.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ OpenCode (sst/opencode).

- **Source:** `src/providers/opencode.ts`
- **Loading:** lazy (`src/providers/index.ts:59-75`)
- **Test:** `tests/providers/opencode.test.ts` (676 lines, the largest provider test)
- **Test:** `tests/providers/opencode.test.ts` (868 lines)

## Where it reads from

Default `~/.local/share/opencode/` or `$XDG_DATA_HOME/opencode/`. The discovery walk picks up `opencode*.db` files (`opencode.ts:71-88`).
Default `~/.local/share/opencode/` or `$XDG_DATA_HOME/opencode/`. The discovery walk picks up `opencode*.db` files (`opencode.ts:99-108`).

## Storage format

SQLite.

## Caching

None.
Uses the shared session cache keyed by the real SQLite database file path.

## Deduplication

Expand All @@ -25,11 +25,12 @@ Per `<sessionId>:<messageId>`.
## Quirks

- **Schema validation is loud.** When a required table is missing, the parser logs an actionable warning telling the user which table is gone and what version of OpenCode it expects. This is the right behavior; do not silently swallow these.
- Source paths are encoded as `<dbPath>:<sessionId>`.
- Discovery only emits root sessions (`parent_id IS NULL`) to avoid double
counting. Parsing a root session walks the unarchived `session.parent_id`
subtree, so child and grandchild agent sessions contribute their message,
token, and tool usage back to the root session.
- Discovery emits one source per `opencode*.db` file so the shared cache can
fingerprint the actual SQLite file. The parser then iterates unarchived root
sessions (`parent_id IS NULL`) inside the database.
- Parsing a root session walks the unarchived `session.parent_id` subtree, so
child and grandchild agent sessions contribute their message, token, and tool
usage back to the root session without double counting.
- Each message's `parts` are indexed; preserving the order matters for reasoning-token correctness.
- Tokens are reported across `input`, `output`, `reasoning`, `cache.read`, and `cache.write`. Anthropic semantics.
- External MCP tools are stored as `<server>_<tool>` names (for example
Expand All @@ -39,6 +40,6 @@ Per `<sessionId>:<messageId>`.

## When fixing a bug here

1. The 558-line test suite catches a lot. Run `npm test -- tests/providers/opencode.test.ts` before and after any change.
1. The provider test suite catches a lot. Run `npm test -- tests/providers/opencode.test.ts` before and after any change.
2. If the bug is "missing table" warning, do not catch and silence it. Either upgrade the version expectation in the parser or document the breaking schema change.
3. If the bug is "reasoning tokens off by one", check the parts index ordering.
Loading
Loading