You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(opencode): read OpenCode v2 usage from session_v2/session_message tables #1644
Extend the OpenCode adapter to also read the new tables that OpenCode v2 (npm dist-tag beta) writes, while keeping the legacy tables working for v1 installs, without double-counting messages that exist in both.
OpenCode v1 stores its data in ~/.local/share/opencode/opencode.db, in the session and message tables.
OpenCode v2 stores its data in the same database, however, in two new tables:
session_v2 for sessions, with cost and tokens_input/output/cache_read/cache_write directly on the row
session_message for messages, with id/session_id in columns and payload JSON in data, but only type='assistant' rows carry tokens and cost.
Why?
ccusage cannot detect sessions created by OpenCode v2 beta. For sessions initiated in v1 and later continued in v2, ccusage sees only the messages written in v1, but every new message written from v2 stays invisible.
Since v2 is the beta channel on its way to becoming the default, this will eventually affect every OpenCode user on ccusage.
How? (optional)
Check whether the v2 tables (session_v2, session_message) exist in the database. If not, nothing needs to change.
If they exist, read session_message rows with type='assistant' for usage, and session_v2 for ccusage opencode session.
Extend OpenCodeMessage in parser.rs to accept the v2 payload shape.
Union both sources and dedup by message id.
Notes:
Log a debug-level count when v2 rows exist but produce no entry, in case the beta changes shape.
This issue is actionable. The current OpenCode adapter only queries the legacy message table in rust/adapters/opencode/src/loader.rs and parses the v1 top-level payload fields in rust/adapters/opencode/src/parser.rs; it has no path for session_message, so v2 assistant usage is currently invisible. The existing DB/file ID deduplication is a useful foundation for the requested cross-source deduplication.
One schema detail needs to be confirmed before implementation: the issue calls the new session table session_v2, while the current upstream OpenCode beta schema I inspected uses a v2 session table alongside session_message and has no literal session_v2 table. The implementation should detect the actual tables/columns rather than assuming one name, while retaining legacy session/message compatibility.
Proposed Plan
Confirm and isolate the schemas. Establish a representative v1/v2 SQLite fixture and verify the physical session table name, column types, timestamp units, and whether v2 session rows are needed only for metadata or also for sessions lacking usable assistant messages. Detect optional tables before preparing queries so v1-only databases remain unchanged and beta schema drift fails open with debug diagnostics.
Add v2 database loading in loader.rs. Keep the legacy message query, add a session_message query restricted to type = 'assistant', and pass the row id and session_id separately from the JSON payload. Reuse the existing date-window pushdown plus authoritative payload filtering, with the v2 time_created/data.time.created shape handled explicitly. Preserve the existing JSON-file fallback and source ordering.
Normalize both payload versions in parser.rs. Extend the source-local types to accept v1 fields and the v2 nested model.id/model.providerID shape. Allow loader-supplied IDs and session IDs to fill fields absent from v2 JSON, retain positive stored costs and existing pricing fallback behavior, and ignore non-usage/malformed/zero-token rows. Decide the treatment of any v2 reasoning field against the existing extra_total_tokens convention rather than silently losing or double-counting it.
Integrate v2 session data without polluting other reports. Use session_message entries for daily, weekly, monthly, and ordinary session aggregation. If the v2 session table is required for ccusage opencode session metadata or aggregate-only sessions, carry that information through a session-specific metadata/aggregate path in report.rs instead of adding aggregate session rows to LoadedEntry, which would inflate date totals and double-count message usage. Preserve legacy session behavior and parent/session identifiers where available.
Add regression coverage. Extend parser tests for both payload shapes and loader fixture tests for v1-only, v2-only, mixed databases, missing optional tables, assistant filtering, date bounds, malformed rows, and duplicate IDs across legacy/v2/file sources. Add session-report assertions plus focused JSON/table snapshot coverage for totals and model/token/cost fields. Validate with cargo test -p ccusage opencode and the repository Rust formatting/check recipes.
Update source documentation if the confirmed schema changes the user-visible data-source description. At minimum review rust/adapters/opencode/src/README.md and docs/guide/opencode/index.md, which currently describe the legacy JSON layout and do not explain the v2 SQLite tables. No CLI option or schema artifact change is expected.
No implementation changes have been made; the worktree remains clean.
Task list (3/3 completed)
Read repository guidance and issue context
Trace OpenCode v1 and v2 storage/reporting code and tests
Assess actionability and publish an implementation plan
This issue was auto-closed. Issues from new contributors are auto-closed by default.
Maintainers review auto-closed issues and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md may not be reopened or receive a reply.
Keep the issue short, concrete, and written in your own voice.
If a maintainer replies lgtmi, your future issues will stay open. If a maintainer replies lgtm, your future issues and PRs will stay open.
@pullfrog Triage this issue using the repository standing issue-triage instructions. Inspect the full issue body, comments, current main branch, and related issues or pull requests. Choose exactly one priority label. If the issue is clearly unresolved and is priority:critical or priority:high with safe and well-scoped requirements, implement it and open a focused pull request. Otherwise, only triage it. Keep the explanation short and use simple English.
This is a real, unresolved bug. The current adapter reads legacy message rows, so OpenCode v2 usage can be missed. I am not opening a PR because the exact v2 schema and the required session-report behavior still need confirmation. A representative database or confirmed table/column details would make implementation safer.
A maintainer explicitly requested an implementation attempt. Clear, repository-scoped OpenCode compatibility bug with concrete affected tables, deduplication requirements, and implementation intent. The exact beta schema and session-report behavior still need maintainer confirmation, so no PR should be created yet.
Decision: kept open; Pullfrog will attempt a focused implementation PR.
Historical audit: this discussion was auto-closed by the legacy contributor gate. That closure did not assess technical importance.
Audit result: resolved. A later merged change or the current main implementation covers this request. This item is kept for history and does not need to be reopened.
Activity
pullfrog commentedon Aug 26, 2026
Assessment
This issue is actionable. The current OpenCode adapter only queries the legacy
messagetable inrust/adapters/opencode/src/loader.rsand parses the v1 top-level payload fields inrust/adapters/opencode/src/parser.rs; it has no path forsession_message, so v2 assistant usage is currently invisible. The existing DB/file ID deduplication is a useful foundation for the requested cross-source deduplication.One schema detail needs to be confirmed before implementation: the issue calls the new session table
session_v2, while the current upstream OpenCode beta schema I inspected uses a v2sessiontable alongsidesession_messageand has no literalsession_v2table. The implementation should detect the actual tables/columns rather than assuming one name, while retaining legacysession/messagecompatibility.Proposed Plan
Confirm and isolate the schemas. Establish a representative v1/v2 SQLite fixture and verify the physical session table name, column types, timestamp units, and whether v2 session rows are needed only for metadata or also for sessions lacking usable assistant messages. Detect optional tables before preparing queries so v1-only databases remain unchanged and beta schema drift fails open with debug diagnostics.
Add v2 database loading in
loader.rs. Keep the legacymessagequery, add asession_messagequery restricted totype = 'assistant', and pass the rowidandsession_idseparately from the JSON payload. Reuse the existing date-window pushdown plus authoritative payload filtering, with the v2time_created/data.time.createdshape handled explicitly. Preserve the existing JSON-file fallback and source ordering.Normalize both payload versions in
parser.rs. Extend the source-local types to accept v1 fields and the v2 nestedmodel.id/model.providerIDshape. Allow loader-supplied IDs and session IDs to fill fields absent from v2 JSON, retain positive stored costs and existing pricing fallback behavior, and ignore non-usage/malformed/zero-token rows. Decide the treatment of any v2 reasoning field against the existingextra_total_tokensconvention rather than silently losing or double-counting it.Integrate v2 session data without polluting other reports. Use
session_messageentries for daily, weekly, monthly, and ordinary session aggregation. If the v2 session table is required forccusage opencode sessionmetadata or aggregate-only sessions, carry that information through a session-specific metadata/aggregate path inreport.rsinstead of adding aggregate session rows toLoadedEntry, which would inflate date totals and double-count message usage. Preserve legacy session behavior and parent/session identifiers where available.Add regression coverage. Extend parser tests for both payload shapes and loader fixture tests for v1-only, v2-only, mixed databases, missing optional tables, assistant filtering, date bounds, malformed rows, and duplicate IDs across legacy/v2/file sources. Add session-report assertions plus focused JSON/table snapshot coverage for totals and model/token/cost fields. Validate with
cargo test -p ccusage opencodeand the repository Rust formatting/check recipes.Update source documentation if the confirmed schema changes the user-visible data-source description. At minimum review
rust/adapters/opencode/src/README.mdanddocs/guide/opencode/index.md, which currently describe the legacy JSON layout and do not explain the v2 SQLite tables. No CLI option or schema artifact change is expected.No implementation changes have been made; the worktree remains clean.
Task list (3/3 completed)
@v0or keep the SHA fresh with Dependabot | Implement plan ➔ | View workflow run | via Pullfrog | UsingGPT Luna(free via Pullfrog for OSS) | 𝕏github-actions commentedon Aug 26, 2026
This issue was auto-closed. Issues from new contributors are auto-closed by default.
Maintainers review auto-closed issues and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md may not be reopened or receive a reply.
Keep the issue short, concrete, and written in your own voice.
If a maintainer replies
lgtmi, your future issues will stay open. If a maintainer replieslgtm, your future issues and PRs will stay open.See CONTRIBUTING.md.
amirh-amini commentedon Aug 27, 2026
@ryoppippi can I work on this?
ryoppippi commentedon Aug 27, 2026
@pullfrog Triage this issue using the repository standing issue-triage instructions. Inspect the full issue body, comments, current main branch, and related issues or pull requests. Choose exactly one priority label. If the issue is clearly unresolved and is priority:critical or priority:high with safe and well-scoped requirements, implement it and open a focused pull request. Otherwise, only triage it. Keep the explanation short and use simple English.
pullfrog commentedon Aug 27, 2026
Triage:
priority:medium.This is a real, unresolved bug. The current adapter reads legacy
messagerows, so OpenCode v2 usage can be missed. I am not opening a PR because the exact v2 schema and the required session-report behavior still need confirmation. A representative database or confirmed table/column details would make implementation safer.@v0or keep the SHA fresh with Dependabot | View workflow run | via Pullfrog | UsingGPT Luna(free via Pullfrog for OSS) | 𝕏github-actions commentedon Aug 28, 2026
Pullfrog triage: priority:medium
A maintainer explicitly requested an implementation attempt. Clear, repository-scoped OpenCode compatibility bug with concrete affected tables, deduplication requirements, and implementation intent. The exact beta schema and session-report behavior still need maintainer confirmation, so no PR should be created yet.
Decision: kept open; Pullfrog will attempt a focused implementation PR.
ryoppippi commentedon Aug 31, 2026
Historical audit: this discussion was auto-closed by the legacy contributor gate. That closure did not assess technical importance.
Audit result: resolved. A later merged change or the current
mainimplementation covers this request. This item is kept for history and does not need to be reopened.