Skip to content

Add usage limits section to settings for Codex and Claude Code#281

Merged
SawyerHood merged 1 commit into
mainfrom
bb/usage-limits-settings-section-thr_fw8tbx4kpa
Jun 20, 2026
Merged

Add usage limits section to settings for Codex and Claude Code#281
SawyerHood merged 1 commit into
mainfrom
bb/usage-limits-settings-section-thr_fw8tbx4kpa

Conversation

@SawyerHood

Copy link
Copy Markdown
Collaborator

What

Adds a Usage limits section to Settings showing live Codex and Claude Code subscription usage — plan label, a 5h "Current session" window and a "Weekly limit" window per provider, each with a % bar and reset time — in one consistent style.

How

  • Daemon reads creds + provider APIs directly (apps/host-daemon/src/provider-usage.ts): Codex from ~/.codex/auth.jsonchatgpt.com/backend-api/wham/usage (reusing the existing ChatGPT token + Cloudflare-cookie handling); Claude from the macOS Keychain (Claude Code-credentials, fallback ~/.claude/.credentials.json) → api.anthropic.com/api/oauth/usage. Both normalized into one ProviderUsageResponse shape.
  • Tokens are used as-is, never refreshed — the CLIs own them, so refreshing could rotate their refresh token out from under them. Missing/expired creds surface unauthenticated/expired states instead of errors (matches how codexbar treats CLI-owned creds).
  • Routed through the server, not the browser→daemon loopback API. A host-daemon online-RPC command provider.usage is exposed via GET /api/v1/system/usage-limits (resolves the connected primary host + callHostRetryableOnlineRpc). The browser only talks to the server, so it works over non-loopback origins (e.g. Tailscale) where the daemon's local API is unreachable. Bumped HOST_DAEMON_PROTOCOL_VERSION 41→42.

Graceful states

Each provider resolves independently. Not signed in → "Run codex/claude to sign in"; token expired → "session expired, run … then refresh"; no host connected → "couldn't load usage"; network/parse error → per-provider message. A brand-new user sees the section with sign-in prompts, no errors.

Tests

  • New unit tests for the daemon normalization (codex/claude parsing, clamping, plan labels, malformed payloads).
  • Updated host-daemon-contract fixtures + protocol-version assertion for the new command.
  • typecheck + test green across host-daemon-contract, host-daemon, server-contract, server, app; lint + prettier clean.
  • Verified end-to-end against live accounts via the server route and the rendered Settings page.

🤖 Generated with Claude Code

Show live Codex and Claude Code subscription usage (5h session + weekly
windows, plan label, reset times) in a unified Settings section.

The host daemon reads each provider's own credentials (codex ~/.codex/auth.json;
claude macOS Keychain / ~/.claude/.credentials.json) and queries their usage
endpoints (backend-api/wham/usage, api/oauth/usage), normalizing both into one
shape. Tokens are used as-is and never refreshed; unauthenticated/expired states
are surfaced instead.

Usage is exposed as a host-daemon online-RPC command (provider.usage) behind a
server route (GET /api/v1/system/usage-limits) so the browser fetches it through
the server. That works over non-loopback origins (e.g. Tailscale) where the
daemon's loopback-only local API is unreachable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@SawyerHood SawyerHood merged commit 2046d41 into main Jun 20, 2026
6 checks passed
@SawyerHood SawyerHood deleted the bb/usage-limits-settings-section-thr_fw8tbx4kpa branch June 20, 2026 02:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant