OpenCode rejects a dead auth cookie with HTTP 302 to /auth/authorize (or
401/403). The HTTP client now disables redirect following so this surfaces
as a FetchError::Unauthorized instead of a 200 login page that fails to parse.
ocd health probes each account's cookie against its default workspace Zen
page and reports alive/dead/errored/misconfigured with a total count. Exit is
0 only when all accounts are alive.
The main walk (pretty/raw/fetch) also classifies a dead cookie as the new
ReportStatus::CookieDead, labels it [cookie dead] in pretty output and
cookie_dead in raw output, and continues with the valid accounts rather than
aborting. Verified live: valid account surfaces [ok], dead account surfaces
[cookie dead], unfilled account surfaces [cookie dead].
HttpClient.get_text now accepts etag/last_modified and sends
If-None-Match/If-Modified-Since; a 304 returns no body and the caller reuses
the cached parse. fetch_target recovers validators from the stale cache entry
(via new cache::read_raw, TTL-agnostic) and stores whatever the server emits.
Verified live: OpenCode/Cloudflare returns no ETag or Last-Modified on either
page, so the slots stay None, no headers go out, and 304 never fires. The
machinery is correct and ready for the day they add validators.
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.