A zero-dependency, self-managed quota monitor for Codex, Claude, Grok, and Google AI Pro / Antigravity. Keep multiple accounts, check their quotas together, or watch them in a responsive full-screen terminal view.
Requires Node.js 18 or newer. Optional discovery from SQLite-backed harness stores
requires a Node version with node:sqlite.
npm install -g shuvquota
# or
bun add -g shuvquotashuvquota is also installed as cq and sq.
cq codex add personal
cq claude add work
cq # one-shot quota view
cq watch # live full-screen view
cq codex work # one provider/account
cq --compact # one line per metric
cq --json # redacted v2 snapshotBare cq always runs once. Cards fill the available terminal width; short
terminals try more, narrower columns, then fall back to one aligned line per
quota window.
cq watch is a full-screen app: provider tabs across the top, an account
sidebar with each account's lowest remaining quota, a detail pane for the
selected account (limits with reset countdowns, then details), and a status
bar. Press u to list the soonest upcoming resets across all accounts.
Terminals under 72 columns drop the sidebar. Watch mode uses 24-bit colour;
--no-color or NO_COLOR renders the same layout without colour.
| Key | Action |
|---|---|
q, Ctrl-C |
Quit and restore the terminal |
r |
Refresh now |
u |
Show or hide upcoming resets across all accounts |
e |
Toggle email visibility |
? |
Toggle help |
1 |
All providers |
2–5 |
Codex, Claude, Grok, Antigravity |
j/k, arrows |
Select the next/previous account |
| PgUp/PgDn | Jump several accounts |
+/- |
Increase/decrease refresh interval by 15 seconds |
The default interval is 3 minutes (180 seconds); the minimum is 15. cq tui and cq -w are
watch aliases. Use --once to force one-shot output. Redirected input or output
falls back to a static view. A failed scan preserves the last completed view and
shows a stale marker; individual account failures appear on their own cards.
When Anthropic rate-limits quota reads, Claude waits at least five minutes (or a
longer Retry-After) before another request. The card shows the remaining wait.
Grok quota access can differ between OAuth sessions for the same account. Native
Grok Build sessions in ~/.grok/auth.json (or $GROK_HOME/auth.json) are discovered
read-only. If a managed session gets a Code CLI permission denial, shuvquota can
query another unexpired session with the same verified account ID. It never
refreshes or modifies the native session. The quota card marks that fallback.
Every provider supports the same commands:
cq <provider> add [label]
cq <provider> reauth <label>
cq <provider> rename <old> <new>
cq <provider> remove <label>
cq accounts
cq sourcesadd obtains a new OAuth session through provider login. reauth replaces the
selected managed credential with a new login. Rename and remove affect only
shuvquota's store.
| Provider | Owned store |
|---|---|
codex |
~/.codex-accounts.json |
claude |
~/.claude-accounts.json |
grok |
~/.grok-accounts.json |
antigravity |
~/.antigravity-accounts.json |
Writes are atomic and use file mode 0600. Old activeLabel metadata is ignored
and removed on the next write. Legacy rows without independent-enrollment
provenance need reauth before shuvquota may refresh them.
Shuvquota refreshes independently enrolled credentials and persists rotated tokens only in its own stores. It never selects an active identity or writes credentials into Codex CLI, Claude Code, OpenCode, pi, Hermes, or other harness stores.
External stores and environment credentials are optional read-only quota sources.
Their usable access tokens can be queried; expired external credentials require
independent enrollment with cq <provider> add. Shuvquota does not refresh these
external sessions. cq sources lists every physical source, including duplicates;
quota views deduplicate account identities and prefer managed labels.
If you have exactly one account for a provider but older sessions lack matching
identity metadata, set SHUVQUOTA_SINGLE_ACCOUNT_PROVIDERS=claude,antigravity in
~/.shuvquota.env (list only providers where this is true). Quota views select one
session per listed provider, preferring an independently managed session or a
usable access token over expired copies. cq sources still lists every source.
Remove a provider from this setting when you add a second account.
cq accounts prints labels and ownership status, never credentials.
cq sources --json intentionally includes source paths; quota JSON and the web API
do not.
Optional environment settings can be loaded from ~/.shuvquota.env. Existing
process environment values take precedence. Keep this file private.
- Codex / Claude: use their provider login flows. Headless login presents a URL and the callback/code instructions appropriate to that provider.
- Grok: uses xAI OAuth PKCE. The known loopback client uses port
56121. - Antigravity: configure
ANTIGRAVITY_CLIENT_IDandANTIGRAVITY_CLIENT_SECRETfor the installed-app flow. No client secret is included in the package. The loopback redirect uses port36742. - proxx: optional read-only Codex quota source, configured through
PROXX_BASE_URLandPROXX_AUTH_TOKEN. It has no separate namespace or provider snapshot. Remote failures retain local results. - Grok display plan: existing
~/.grok-plan-override.jsonandplanOverridemetadata remain display-only; edit them directly if needed.
OAuth endpoints, source evidence, client assumptions, and unverified live checks are recorded in the OAuth validation notes. A successful login does not guarantee every subscription has access to every provider service.
Emails are masked by default. Use --show-email to reveal the email field in local
terminal/JSON output. The web API always applies its public projection. ANSI and
control characters from remote display text are sanitized.
cq --json
cq quota work --compact
cq watch --interval 90
cq --show-email
cq --no-colorNO_COLOR is also honored. Reset clocks use Pacific Time (America/Los_Angeles),
with PST/PDT as appropriate; machine timestamps are ISO 8601.
Completed quota snapshots use schemaVersion: 2, a generatedAt timestamp, and
an ordered providers array. Accounts contain labels, optional email/plan,
status (ok, error, or loading), windows, and optional extras. Window fields
are id, label, percentRemaining, resetsAt, and optional detail.
Quota snapshots do not contain raw provider responses, tokens, or source paths.
shuvquota-server
# development
bun run appThe dashboard defaults to http://127.0.0.1:4789. It uses the same in-process
quota loader as the CLI, with a public-data projection, a short cache, and
single-flight requests. The host allowlist, security headers, and static-file
path restrictions remain enabled. /api/health and /api/quota use schema v2.
v2 removes Factory, OpenCode Go, and Synthetic, the standalone proxx namespace,
and harness-switching/synchronization commands (switch, sync, set-plan).
Removed command forms exit 2 with a v1 migration hint.
The v1 command surface remains available through npx shuvquota@1 …. The local
v1.1.25-final tag preserves the pre-migration source.
--local, --native, --no-factory, --billing-day, --oauth, --manual,
--dry-run, --no-browser, --base-url, and --token are removed. Use the unified
ownership policy and environment configuration described above. Reauthenticate
legacy imported managed accounts before relying on automatic refresh.
The JSON shape is breaking: consume the v2 providers[].accounts[].windows[]
model, not v1's raw provider-keyed responses.
bun test
bun run preflight
bun run release:packTests use fixture credentials and mocked HTTP calls. lib/ contains the provider
adapters, owned credential store, snapshot pipeline, CLI, server, and terminal UI;
tests import modules directly. No runtime dependencies are required.
Cursor API keys can be read from a T3 Code state directory by setting
SHUVQUOTA_T3_STATE_DIR=/path/to/t3/userdata in ~/.shuvquota.env. Both inline
keys and T3's provider-env-*.bin secret references are supported. Each enabled
Cursor instance becomes an account; duplicate keys are fetched once. cq cursor
shows quota and cq cursor sources lists the physical sources. These accounts
are read-only: manage their keys and names in T3 Code, not cq add or reauth.
They do not use an owned shuvquota credential store.
The adapter exchanges each API key through Cursor's own API-key login endpoint, then reads the dashboard usage endpoint. It never rotates a harness refresh token, persists the returned session, or writes T3 configuration. Total usage, Auto, and API windows use Cursor's reported percentages, with the reported billing-cycle reset. These endpoints were verified with the installed Cursor CLI's protocol; they are not a guaranteed public quota API.
SHUVQUOTA_DISABLED_PROVIDERS=grok hides a provider from default CLI/dashboard
scans without deleting its credentials. Explicit commands such as cq grok
remain available. Multiple provider IDs may be separated by commas.
Set SHUVQUOTA_CURSORPROX_AUTH_DIR=/path/to/cursorprox/run/gateway/auths in
~/.shuvquota.env to read existing Cursor sessions. Disabled records are skipped.
No tokens are copied or written, and external refresh tokens are never used.
Each scan rereads the current access tokens maintained by cursorprox. If a session
expires, reauthenticate in cursorprox; shuvquota reports the authentication error.
When both sources are configured, matching Cursor JWT subjects merge into one card
with the T3 label. All physical sources remain visible through cq cursor sources.
Records without a known subject remain separate. Total usage is Cursor's reported
bonus-inclusive percentage, not the remaining purchased allowance.