OpenCode is React Router v7 with streaming SSR; loader data is inlined in the
HTML as JS resource objects (e.g. rollingUsage:$R[n]={status,resetInSec,
usagePercent}). There is no separate JSON HTTP endpoint. parse the embedded
records first (exact resetInSec integers + a status field), and fall back to the
data-slot DOM when the embedded path finds nothing.
Add optional status field to UsageFrame (serde default, schema-compatible).
embedded_usage_frame scans every key occurrence so a billing-record
'monthlyUsage:null' sibling does not shadow the real usage object. embedded_balance
scans past 'balance:null'. Verified live: all three frames parse, month no
longer blank, status captured, resets_at driven by resetInSec.
Go page (/workspace/{id}/go): parse three [data-slot=usage-item] frames
(Rolling/Weekly/Monthly) into usage percentages + computed resets_at from the
relative reset-duration text. Zen page (/workspace/{id}): parse
[data-slot=balance] b into remaining + currency unit. Add an offline unit test
against tmp/ captures. Fix pretty renderer (percent display, money format,
day-aware relative times). Update DESIGN.md, README, examples and config
template to the real wrk_ workspace ids.
Rust CLI with clap subcommands (pretty/raw json/raw plain/fetch/cache/config).
Per-workspace dual HTTP (Zen balance + Go limits) run with tokio::join,
500 ms workspace pacing, TTL-180s file cache, retry/backoff for transient
failures. scrape.rs holds the only OpenCode-coupled HTML selectors (placeholders
until the real Zen/Go pages are captured). Unicode blitter-block bars in
pretty mode; stable JSON/plain raw output for widgets and agent plugins.