Empirical. Every claim below came from running the binary, not from docs.
codex— source resolves tooauth, dataConfidenceexactclaude— sourcecli(explicitly pinned in config), dataConfidencepercentOnlyantigravity— token account (Google OAuth material stored in config), sourcecli
dashboard-v1 window objects contain ONLY: kind, label, remainingPercent, usedPercent, resetAt.
usage --format json additionally contains, per provider, a pace block:
stage, deltaPercent, expectedUsedPercent, willLastToReset, etaSeconds, summary
plus usage.*.windowMinutes, dataConfidence, codexResetCredits, extraRateWindows.
The brief mandates preserving pace/expectedUsedPercent/willLastToReset AND using dashboard
as the cron source. Those two requirements are incompatible. usage wins.
Live example (claude, session window): stage=farAhead deltaPercent=21 expectedUsedPercent=51 willLastToReset=false etaSeconds=3595 summary="21% in deficit | Expected 51% used | Projected empty in 1h" That sentence IS the primary use case. It does not exist in dashboard-v1.
/usagerepeated immediately -> identical updatedAt. CACHED./dashboard/v1/snapshotrepeated -> identical generatedAt. CACHED./usage?provider=codexAFTER a snapshot -> NEW upstream fetch (21:39:44 -> 21:40:10).
=> /usage and /dashboard/v1/snapshot are SEPARATE cache lanes. Polling both doubles the
upstream rate. Pick one. /usage is strictly richer at identical upstream cost.
/usageDOES include the pace block over HTTP. This is what makes serve viable as the single upstream-touching process.
- one-shot
codexbar dashboard: staleAfterSeconds=180, host.refreshIntervalSeconds=0 - under
codexbar serve: staleAfterSeconds=900, host.refreshIntervalSeconds=300 Under serve, 900 > the 300s poll, so it is NOT self-stale. Do not map it to HAexpire_afterregardless; 180 in one-shot mode would flap every entity to unavailable between polls.
/cost (local session-log scan, NO upstream fetch, cached unless --refresh) returns per provider:
provenance ("listPriceEstimate"), coverage {estimated, priced, unpriced, unmetered},
historyCoverageIsEstablished, source, projects[], daily[] with modelBreakdowns,
last30DaysCostUSD, sessionCostUSD, sessionTokens, historyDays, currencyCode
Observed: codex $301.55/30d (coverage priced=9 unpriced=1), claude $118.12/30d (priced=4).
Propagate CodexBar's own coverage/provenance rather than inventing a source-host field;
add host attribution ON TOP of it.
--provider all means all 69 providers, NOT the 3 enabled. It exits 1 and attempts fetches
against every configured provider. Never use it in a poll loop. dashboard honours enabled
providers only; per-provider usage calls are the safe equivalent.
guard --json returns only: decision, exitCode, provider, window, remainingPercent,
minimumRemainingPercent, unavailableReason. No pace, no eta.
--window accepts only session|weekly, so it CANNOT address antigravity's four
extraRateWindows (gemini-5h, gemini-weekly, 3p-5h, 3p-weekly).
=> Phase 2 MCP must read /usage, using guard only for the binary gate.
- antigravity has NO pace block at all, and its real quota lives in
extraRateWindows[]with dynamic ids (antigravity-quota-summary-*). Its primary/secondary are BOTH weekly windows (windowMinutes 10080) — there is no session window to guard on. - claude has no identity.accountEmail and dataConfidence=percentOnly under source=cli.
- codex exposes
codexResetCredits.availableCount=1— a free full rate-limit reset, planning-relevant and absent from dashboard-v1.
hooks list -> {"enabled": false, "events": []}. Nothing configured. Rules live in the
shared config file and must be authored before hooks watch does anything.