OpenCode meters read the official account-wide usage API - #132
Conversation
anomalyco/opencode#16513 shipped GET /zen/go/v1/usage (2026-08-11) — the endpoint the code comment said to swap to when it existed. The card now shows Session/Weekly/Monthly percentages and resets counted on OpenCode servers (same numbers as the Zen dashboard, other devices and shared-subscription participants included), authenticated with the Go key Pane already reads from auth.json. The live wire shape differs from the merged PR draft — verified against the deployed endpoint with a real key and pinned in a test: usage.{rolling,weekly,monthly}.{status,percent,resetsAt}. The old local-window computation stays as the fallback when the API is unreachable; dollar spend remains local. README + providers.md drop the "no public usage API yet" story. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The monthly meter derives its window length from the server''s own reset boundary (one anchored month back, day clamped) instead of a fixed 30 days, which skewed the pace projection and went negative- fraction right after a 31-day cycle started. - The local fallback now labels itself: plan reads "Go - this PC only" when the account-wide API is unreachable, so the card never silently flips between scopes that look identical. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lback log - When the usage API fails AND the local fallback cannot run (fresh device, no opencode.db), the card now carries both causes instead of blaming a missing local file for what is really a network/key error. - parse_official rejects fractional (0-1) and out-of-range percents outright: the wire shape was captured empirically and already changed once between the upstream PR and deploy, so a changed encoding must fail into the labeled local fallback, never render wrong meters. - The fallback stderr line logs the transition only, not once per refresh for the lifetime of an offline machine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A blocked window must never vanish from the card because the server omitted or lagged its percent field — status == "rate-limited" is the answer by itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| if !(0.0..=100.0).contains(&percent) || (percent > 0.0 && percent < 1.0) { | ||
| return None; | ||
| } |
There was a problem hiding this comment.
🔍 Over-quota (>100%) usage silently forces this-PC-only fallback
In parse_official at src-tauri/src/providers/opencode.rs:179, any percent outside 0.0..=100.0 makes the entire parse return None, which propagates as an error through fetch_official and drops the card to the local opencode.db computation. If a user is over quota and the server reports a value like 101 for any single window (over-usage isn't necessarily capped at 100 server-side), all three account-wide meters get replaced by the this-PC-only fallback. This is at least labeled (plan = "Go — this PC only" at :122), so it isn't silent, and the author explicitly chose a fail-loud strategy — but it's worth confirming the deployed endpoint truly caps at 100 for over-quota accounts, otherwise heavy users lose the account-wide numbers exactly when they most need them.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
OpenCode finally shipped a public usage API — anomalyco/opencode#16513, merged 2026-08-11 — the endpoint this codebase has been waiting on since July (the old comment literally said "swap to the official API once it ships"). This swaps to it.
GET https://opencode.ai/zen/go/v1/usage, Bearer-authenticated with the Go key Pane already reads fromauth.json(no new credential surface).usage.{rolling,weekly,monthly}.{status,percent,resetsAt}) differs from the merged PR's draft code — parsing targets the deployed shape, pinned in a unit test with a verbatim capture.rate-limitedwindows render at 100%; a missing window is skipped rather than failing the card; unparseable responses fall through.opencode.dbsurvives as the fallback when the API is unreachable (offline, revoked key), clearly labeled this-PC-only. Dollar spend rows are unchanged — always local.Testing
New unit test pins the live wire shape (verbatim capture from the deployed endpoint queried with a real Go key: rolling 0% / weekly 6% / monthly 3%), the rate-limited case, and the junk-response fallback. Full suite 59/59.
🤖 Generated with Claude Code