fix: read OpenCode Go usage from local data#1021
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 751e680c6e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| nowComponents = calendar.dateComponents([.year, .month], from: previous) | ||
| start = self.anchoredMonth(calendar: calendar, month: nowComponents, anchor: anchorComponents) | ||
| } | ||
| let end = calendar.date(byAdding: .month, value: 1, to: start) ?? start |
There was a problem hiding this comment.
Re-anchor the monthly window end
When the first local OpenCode Go usage falls on the 29th–31st, anchoredMonth clamps shorter months to their last day, but this line then advances from that clamped date instead of from the original anchor. For example, with a Jan 31 anchor and now on Mar 29, the start becomes Feb 28 and adding one month makes the end Mar 28, so the monthly reset is reported as already expired and Mar 29–30 usage is excluded; compute the next boundary by anchoring the following calendar month with the original anchor components instead of adding a month to the clamped start.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 64d6b15c by computing the monthly reset from the original anchor applied to the following calendar month, plus a regression test for the Jan 31 -> Feb clamp -> Mar reset case.
|
@codex review |
|
Verified locally with a freshly built |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64d6b15c85
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if hasAuth { | ||
| return Self.emptySnapshot(now: now) |
There was a problem hiding this comment.
Fall back instead of accepting empty local usage
When auth.json exists but this hard-coded DB path is absent (for example a new local login with no history yet, or OpenCode using a channel/OPENCODE_DB database), this returns a successful zeroed snapshot. In auto mode the local strategy runs before the web strategy and the fetch pipeline stops on the first success, so users with valid dashboard cookies/current remote usage will now see 0% bars instead of the existing web result; treat missing/unreadable local history as fallback-eligible until the web path fails, rather than succeeding here.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 87169850. Missing, empty, or unreadable local history now throws a fallback-eligible local error, so automatic mode can still use the existing web-cookie strategy when valid remote usage is available. I also updated the tests to cover the fallback behavior and re-ran swift test --filter OpenCodeGo, make check, and a rebuilt CLI verification that still reports source: "local" when local history is present.
64d6b15 to
8716985
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 87169850d5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| FROM message | ||
| WHERE json_valid(data) | ||
| AND json_extract(data, '$.providerID') = 'opencode-go' | ||
| AND json_extract(data, '$.role') = 'assistant' | ||
| AND json_type(data, '$.cost') IN ('integer', 'real') |
There was a problem hiding this comment.
Read OpenCode step-finish usage rows
When OpenCode histories use the newer SQLite shape where usage/cost is emitted on part rows with data.type == 'step-finish' and the message row only contains metadata, this query returns no rows and auto mode falls through to the web-cookie strategy. That leaves the local-only users this change targets still seeing the cookie error despite having usable local usage in opencode.db; the local reader should also aggregate the step-finish part usage rather than only message.data.cost.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 8f403b74. The local reader now supports OpenCode part rows where data.type == "step-finish", joined back to assistant message metadata for providerID == "opencode-go". It keeps message-level data.cost as the source of truth when present and only uses step-finish part cost when the message does not already have cost, so mixed histories do not double-count. Added regression tests for part-only histories and mixed message+part histories; swift test --filter OpenCodeGo, swift test --filter OpenCodeGoLocalUsageReaderTests, make check, and a real local CLI check all pass.
8716985 to
8f403b7
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8f403b74f1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let snapshot = try OpenCodeGoLocalUsageReader().fetch() | ||
| return self.makeResult( | ||
| usage: snapshot.toUsageSnapshot(), | ||
| sourceLabel: "local") |
There was a problem hiding this comment.
Preserve Zen balance when local usage succeeds
When automatic mode has any local OpenCode Go history, this strategy succeeds and the fetch pipeline returns before OpenCodeGoUsageFetchStrategy runs. The local reader never uses context.includeOptionalUsage or fetches zenBalanceUSD, so users who enable optional extra usage lose the Zen balance section that the existing web strategy populated; this only shows up for local-history users in auto mode.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 7bdad24740. The local OpenCode Go strategy now preserves optional Zen balance when optional usage is enabled by reusing the existing cookie/workspace resolution and fetching the balance non-fatally after local SQLite usage succeeds. If cookies/workspace are unavailable or the optional fetch fails, local usage still returns normally so the original invalid-cookie failure does not reappear.
Validation:
swift test --filter OpenCodeGomake check.build/debug/CodexBarCLI usage --provider opencodego --source auto --format json --pretty --no-color
8f403b7 to
7bdad24
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7bdad24740
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let zenBalance = try await OpenCodeGoUsageFetcher.fetchOptionalZenBalance( | ||
| cookieHeader: cookieHeader, | ||
| timeout: context.webTimeout, | ||
| workspaceIDOverride: workspaceOverride) |
There was a problem hiding this comment.
Keep optional Zen lookup from blocking local usage
In auto mode with local history present, this path turns an otherwise synchronous SQLite read into a web-dependent refresh whenever optional usage is enabled and cookies are available. If no workspace override is configured, fetchOptionalZenBalance first resolves the workspace with context.webTimeout and then loads the balance page, so a slow/unreachable opencode.ai can delay the local result for the full web timeout (or at least the 5s balance timeout) before the error is swallowed. The web fetcher already bounds this optional lookup with completedOptionalZenBalance; the local strategy should apply the same grace/timeout behavior or skip it so local usage remains fast/offline.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in ff8057a6. The local strategy no longer resolves/imports browser cookies or waits on the full web timeout for optional Zen balance. It only uses an already manual or cached OpenCode Go cookie, starts the Zen balance lookup as optional work, and joins it through the existing completedOptionalZenBalance grace path. Non-cancellation failures return nil, so the SQLite usage result stays fast/offline.
Validation:
swift test --filter OpenCodeGomake check.build/debug/CodexBarCLI usage --provider opencodego --source auto --format json --pretty --no-color
7bdad24 to
ff8057a
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. Another round soon, please! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |

Summary
Fix OpenCode Go usage refreshes for local OpenCode Go users by reading OpenCode's local auth/history before falling back to the existing web-cookie dashboard fetch.
Affected users currently see
OpenCode Go cookie header is invalid.when CodexBar cannot import or reuse anopencode.aibrowser cookie, even though OpenCode Go usage is available locally. OpenUsage handles this successfully by reading OpenCode's localauth.jsonand SQLite history, so this PR adds the same local-first path to CodexBar without changing the UI.What changed
OpenCodeGoLocalUsageReader.~/.local/share/opencode/auth.json.~/.local/share/opencode/opencode.dband aggregate assistant messages whereproviderID == "opencode-go".data.costpartrows wheredata.type == "step-finish"and the message only stores metadata$12$30$60, anchored to the first local usage timestampScreenshots / Evidence
No UI changes. This is a provider data-source fix, so screenshots/GIFs are not applicable.
Before this change, an affected setup reports
OpenCode Go cookie header is invalid.in CodexBar while OpenUsage can still show Session, Weekly, and Monthly usage from local OpenCode data. After this change, automatic mode uses that local-data path first when local history is present.Local runtime verification with a freshly built app returns OpenCode Go usage from the local source:
{ "provider": "opencodego", "source": "local" }Issue
No matching open issue found; this PR is self-contained.
Validation
make checkswift test --filter OpenCodeGoswift test --filter OpenCodeGoLocalUsageReaderTests./Scripts/compile_and_run.sh.build/debug/CodexBarCLI usage --provider opencodego --source auto --format json --pretty --no-colorCodexBar.app/Contents/Helpers/CodexBarCLI usage --provider opencodego --source auto --format json --pretty --no-colorThe focused tests cover:
step-finishpart rows when message rows only store metadata