Skip to content
djbclarkPublic

About

CLI that ranks which AI coding subscription quotas to burn before they reset (use-it-or-lose-it)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

620 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

aiuse

PyPI Python Tests License: MIT

Your AI subscriptions reset unused capacity you already paid for. Claude, Codex, Copilot, Cursor, Grok, Gemini, OpenCode, and more each carve your usage into 5-hour / weekly / monthly windows — and whatever you don't burn by the reset is just gone. aiuse polls every plan you have from one terminal command and tells you, in plain language, what to use right now before it resets, and what's about to run out early so you can pace yourself.

CLI command: aiuse (stub ai → same entrypoint)

Which vendor CLI is which

Every report line's vendor name is grep-able (case-insensitive, substring OK) for the actual agent CLI whose quota it tracks:

Vendor CLI tracked
Claude claude
Codex codex
Cursor cursor-agent
GitHub Copilot copilot
Grok / SuperGrok grok (Grok Build)
Gemini / Google Antigravity agy
OpenCode (Go + Zen) opencode
Z.ai zcode
QwenCloud / Alibaba Bailian qwen (Qwen Code)
Muse (Meta) muse
Devin devin
ClinePass cline
DeepSeek, OpenRouter no CLI — per-token $ API only

aiuse --json exposes this same mapping per account row as cli_binary (null when there is no local CLI) — see docs/json-contract.md. Note the trap this table exists for: the quota CLIs (qwencloud, bl, caut, caam, tokscale, openusage, cswap, codexbar) measure usage; they are not how you burn it.

See it in action

This is real aiuse output from synthetic demo accounts, not a screenshot. It's the exact table printed by plain aiuse, read bottom → top: the pools most worth using right now sort to the bottom.

        ## SERVICE    ACCT  SCOPE           5H              WEEK              MONTH           PACE
- error ?? oc-zen     gmail —                                                                    — No available fetch strategy for op…
- empty  0 oc-go      gmail —                          — 100u/0l/4d12h                      —    — <- EXHAUSTED
  n/a   -- deepseek   gmail —                                                                    — $4.15 (counts down)
  n/a   -- openrouter gmail —                                                                    — $18.55 (counts down)
  slow  38 agy        gmail claude/gpt                 — 78u/22l/1d5h                       —    — <-
  mid   50 claude     gmail —          12u/88l/3h7m -68% 77u/23l/3d2h +38%                  — +38% <-
  mid   50 grok       gmail —                          —  6u/94l/6d14h                      —    — <-
  mid   63 codex      gmail —                          — 54u/46l/2d7h -20%                  — -20% <-
  mid   66 cursor     gmail —                          —                  — 71u/29l/3d7h -20% -20%
  mid   66 agy        gmail gemini      4u/96l/4h5m -78% 16u/84l/4d -63%                    — -63% <-
+ use   91 copilot    —     —                          —                  — 58u/42l/~1d -39%  -39%
                              2d14h = until this clock resets · bold = largest unit
                        u/l = percent used / percent left — l is what you can still spend
      +N%/-N% = pace: ahead (+) or behind (-) of an even spend across the window · PACE = the row’s highest · ~ = early: under 10% of the window has elapsed
                               AI: Use `aiuse --json` for machine-readable output

Every row is measured on the same three clocks, so a column reads top to bottom. An em-dash means that service has no window on that clock at all. Each cell displays used% u / left% l / reset_span pace%: u/l = percent used / percent left (l is what you can still spend). For example, 12u/88l/3h7m -68% means 12% consumed, 88% remaining, resetting in 3 hours 7 minutes, and burning 68% slower than an even spend across the window.

A sub-day rolling window (the 5-hour kind) that has not been used yet sends no reset time — its clock starts on first use — so its cell shows the window's full length and a ↻ marker instead of a countdown, e.g. 0u/100l/5h↻. Unused windows of a day or longer get no span. The legend line ↻ = clock starts on first use appears only when at least one such cell is on the board. The marker is screen-only; --json is unchanged.

An in-use window whose source stops sending its reset time (CodexBar sends none for Antigravity's 5-hour windows; OpenUsage does) keeps its countdown: aiuse carries forward the last reset an earlier reading measured for that window, from any source, while that reset is still ahead and the window's usage has not fallen since (a fall means it reset). A carried time is an estimate, so it renders with ~ like any estimated reset (~3h), and --json marks it with resets_at_carried_from (docs/json-contract.md). A window that has not been used yet is never carried: its reported reset only slides with every query.

Pace and the PACE column

  • Window pace % (+N% / -N%) compares consumption against an even spend across the window (round((pace_ratio - 1) * 100) with pace_ratio = used_fraction / elapsed_fraction; elapsed floored at 5%). + means burning faster than an even spend (will run out early); - means burning slower (capacity will remain at reset). Early in a window (under 10% elapsed), readings are noisy and marked with ~ (e.g. +1351%~). Exhausted windows and windows with no reset time leave pace blank.
  • PACE column reports the row's overall pace = the highest window pace in the row (the window furthest ahead of spend that will run out first), marked with ~ if that highest window is early. It shows an em-dash (—) when no window has a pace reading or when any window in the row is exhausted (since the row is locked out until that reset).
  • Column alignment: all free text notes (<-, EXHAUSTED, extra credits, prepaid notes) appear after all fixed columns so columns align on every row. Narrow terminals shed PACE first, then individual cell pace suffixes.

The colored ## score is the action queue from 0 (empty) to 99 (use as soon as possible). Its action-state boundaries are contiguous: slow ends at 49, mid runs from 50–74, and an active use recommendation starts at 75. ?? means usage could not be fetched; -- means rolling prepaid/PAYG inventory has no use-or-lose urgency.

Inside each live band (slow 25-49, mid 50-74, use 75-99) the score is how much money is at risk in the pool's window, log-scaled onto the band's range (6 points per decade, $0.01 at the band's floor to $100 at its ceiling). A window is priced from the plan's monthly_price in [plans.<provider>], spread over the window's refills per waking month (16 waking hours a day by default, so a 5-hour window is 1/97 of the month and a weekly one about a third) and scaled by the plan's value_multiplier. Two figures come out of that price:

  • Capacity is what is still unspent now: the refill's value times the percent still left — the figure --json reports as value_at_risk_usd. slow rows rank by capacity, so 5% left of a $200 plan's weekly window ($3.45) outranks 1% left of a $20 one ($0.07), and a weekly window outranks the same percent of a 5-hour one.
  • Projected waste is what the window's pace says will still be unspent when it resets: the pace's projected_waste_fraction times a full refill (for a priced account, --json's pace.projected_waste_usd). mid and use rows rank by it, so an imminent reset with real waste outranks a big window with days left: a $20 Claude plan's 5-hour window with 20 minutes to go and two thirds of it unspent ($0.20) outranks a weekly window that is exactly on pace ($0), though that weekly window holds $3.45. A window with no pace to project (no reset time) keeps its capacity, the most it could lose. A window the analyzer raised no alert for is paced by the board the same way.

The band's older signal only breaks ties: recovery speed in slow, the analyzer score in mid and use. A window whose length is neither reported nor named in its label has no refill to price and sits at its band's floor. Plan tier is not detected, so each provider defaults to its lowest tier: set [plans.claude] monthly_price = 200 for Max, or [plans.claude."me@x.com"] monthly_price = 200 for one account (the account value wins). For ordering, a provider with no price is valued at the cheapest configured plan; it still shows no dollar figure.

aiuse suggest, the JSON suggestion and the use: head of aiuse status name the burn the board ranks last — the bottom use row, else the bottom mid row a burn alert backs — not the loudest analyzer score.

Green (use) is capacity to burn now before it resets; red is capacity already lost (empty, including a zero/negative prepaid balance) or a source that failed to fetch (error); everything else is informational (n/a positive prepaid balances that never expire, slow windows you should pace yourself on, mid windows on track — nothing to do).

Services are named for the CLI you actually type, so the name doubles as something to grep for. The two OpenCode services are the exception — they abbreviate to an oc- family prefix (oc-go, oc-zen) to stay narrow.

Try it in 60 seconds

pipx install aiuse
aiuse doctor   # see which data-source tools are already on your PATH
aiuse          # usage table for everything aiuse can see right now

No config file is required to start — aiuse doctor tells you exactly which of the optional data-source tools (below) it found, and aiuse works with however many you already have installed. See Install below for Homebrew, git-tip, and editable-dev options.

AI agents: start at AGENTS.md for a map of this repo, active priorities, and contributor guidance.

Data sources

Tool Purpose Authority
cswap cswap list --json Live Claude Code quota for every configured email/account Canonical multi-account Claude source
CodexBar codexbar usage --format json Live quotas and balances for enabled providers Preferred for non-Claude providers; keep its Claude source disabled on macOS until its Keychain prompting is fixed
caut caut usage --json Independent multi-provider usage (CodexBar-class probes) Cross-check peer, but leave disabled on macOS until its repeated Keychain prompting is fixed
caam caam limits --format json Vault-profile limits for claude / codex / grok / cursor Last-resort cross-check peer behind every direct source; needs vault profiles (see docs/caam.md)
OpenUsage.ai openusage / 127.0.0.1:6736/v1/limits Quiet macOS menu-bar companion + live limits API Cross-check peer; distinct collector key: openusage_ai
OpenUsage.sh openusage-sh export --output - --format json Terminal dashboard, local telemetry, and quota export Lowest-priority backup; distinct collector key: openusage_sh; only explicit quota metrics affect ranking
tokscale tokscale usage --json Independent live subscription quota measurement Cross-checked against peers; preferred for Copilot; fill-in when others lack a live row

This project shells out to tools already on your PATH (and optionally hits OpenUsage’s loopback API); it does not scrape billing dashboards itself. For more on collector setup, reliability, and source selection, see the documentation index.

macOS source policy (current)

Use cswap as the Claude source and CodexBar for every other provider. Keep CodexBar's Claude source disabled, even as a fallback. tokscale, OpenUsage.ai, OpenUsage.sh, and other available collectors are useful independent backup and cross-check sources. All collectors are enabled by default, whether installed now or prepared for later; disable any source in config.toml when it is not appropriate for your machine. On macOS, consider disabling caut and CodexBar's Claude integration if their Keychain-prompting bugs affect you.

Install

End users (pipx):

pipx install aiuse
# or from git tip:
# pipx install 'git+https://github.com/djbclark/aiuse.git'
aiuse doctor

(ai is installed as a stub that runs the same CLI.)

Homebrew (personal tap):

brew tap djbclark/aiuse
brew trust djbclark/aiuse
brew install aiuse

Developers (editable):

cd /path/to/aiuse
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Optional config (standard location: ~/.config/aiuse/, or $XDG_CONFIG_HOME/aiuse/):

# Create the canonical config.toml (never overwrites)
aiuse --generate-config

# Or copy the example by hand:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse"
cp config/config.example.toml "${XDG_CONFIG_HOME:-$HOME/.config}/aiuse/config.toml"
File Purpose
~/.config/aiuse/config.toml All user settings: collectors, plans, analysis, timeouts, and macOS options

aiuse --generate-config creates missing parent directories and writes the TOML starter without overwriting it. Provider credentials stay with cswap, CodexBar, caut, OpenUsage, and tokscale — this file does not hold tokens or emails.

Optional OpenCode Zen balance

OpenCode Zen prepaid balance is a distinct service from OpenCode Go quota. CodexBar can report it, and aiuse can independently cross-check the live OpenCode billing response when a signed-in browser session is available. This is opt-in and normal collection never opens a browser or reads its cookie database.

# One-time optional browser reader for a pipx install.
pipx inject aiuse browser-cookie3

# Validate the OpenCode session, then save only the validated cookie through
# SecretSpec. The default manifest is ~/.config/aiuse/secretspec.toml.
aiuse credential refresh opencode-zen --from chrome --profile Default

The command reads only opencode.ai cookies, validates an authenticated workspace and a live Zen balance before saving, and never prints the cookie. Use --dry-run to validate without saving. aiuse credential refresh --help lists its confirmation, profile, timeout, and manifest options. See the OpenCode Zen balance guide for the source model and SecretSpec details.

aiuse normally unifies source-local account names automatically when each identifying source reports exactly one account for a provider. For a genuinely multi-account provider, map a local name explicitly instead of letting aiuse guess:

[account_aliases.codex.openusage_sh]
"codex-cli" = "me@example.com"

aiuse --full prints this exact table when a multi-account source cannot be matched safely. Explicit mappings take precedence over automatic normalization.

Some vendors rate-limit quota probes. aiuse reads agy's (Antigravity's) quota at most once every 15 minutes across every aiuse process (CLI, LaunchAgent, watch, serve), reusing the last reading in between. Tune or disable it per provider, in seconds. See Antigravity pools: query rate limit:

[query_min_interval]
antigravity = 900 # 0 disables

Daily workflow

# Once: create defaults under ~/.config/aiuse/ (never overwrites)
aiuse --generate-config
aiuse doctor                 # PATH tools + config presence + timeouts
# Once per machine: install the data-source tools you intend to use
# (normally cswap, CodexBar, tokscale, and either or both distinct OpenUsage tools)
./packaging/install-deps.sh
# or: just -f ~/ops/site-djbclark/justfile install-aiuse-deps
# macOS: follow the trust guide from the documentation index when needed
aiuse trust setup            # caut: stable codesign + guide
aiuse trust sign-caut        # re-run after every cargo install
aiuse trust fix-codexbar-cache --dry-run   # CodexBar#679: trust CLI on cache items

# Optional: refresh the separately reported OpenCode Zen prepaid balance.
aiuse credential refresh opencode-zen --from chrome --profile Default

# Morning / before a long coding block
aiuse                        # usage table on stdout (use-soon at bottom); meta on stderr
aiuse --full                 # long report: per-provider, tips, History, detailed plan
aiuse --brief                # same as default (compat alias)
aiuse --no-tui               # classic plain-text report (also used when piping)
aiuse -q                     # table only (no stderr meta / Collecting…)
aiuse suggest                # single best burn pool (or “nothing urgent”)
aiuse status                 # one line for shell prompts / status bars
aiuse prompt                 # synonym of status

# Shell completion (bash or zsh)
eval "$(aiuse --print-completion bash)"
# or: source completions/ai.bash

# Tighter thresholds for “only what resets soon”
aiuse --min-remaining 50 --max-days 7

Usage

# Pretty human-readable report (default)
aiuse
aiuse --format pretty
aiuse --no-color          # plain text, no ANSI
aiuse -q / --quiet        # suppress progress on stderr

# or without install:
PYTHONPATH=src python -m ai

# Machine-readable JSON on stdout (progress on stderr unless -q)
aiuse --json
aiuse --format json
aiuse --json --alerts-only
aiuse suggest --json
aiuse --save ~/tmp/ai-snapshot.json   # also write JSON file

# Decision helpers
aiuse suggest              # single best burn pool
aiuse status               # one line for prompts / status bars
aiuse prompt               # synonym of status
aiuse serve                # loopback HTTP API for agents
aiuse watch                # full-screen board (q/esc quit · u update now · a all providers; default 10m)
aiuse watch -i 2m          # faster refresh
aiuse watch --once         # one frame on stdout (scripts / tmux)
aiuse watch --all-providers  # OPERATOR-ONLY: every provider once, screen only (see below)
aiuse attribute            # what spent the quota: points burned beside tokens per client
aiuse attribute --since 7d --provider clinepass --intervals
aiuse sample               # scheduled entry point: samples faster while quota is moving

# Faster / partial
aiuse --providers copilot,grok,codex   # query these separately
aiuse --no-tokscale
aiuse --min-remaining 50 --max-days 10

# Subprocess timeout for external tools (default 45s; also in config.toml)
aiuse --timeout 45
aiuse -t45

# Environment check (tools on PATH, config files, timeouts) — no usage collection
aiuse doctor
aiuse --doctor

Programmatic use and AI orchestration

aiuse turns the many local authenticated quota sources into one normalized, machine-readable snapshot. An agent can call it once instead of opening billing pages, finding credentials, or independently interpreting each provider’s reset bars — saving tokens and avoiding inconsistent conclusions.

# Full live snapshot, ranked alerts, and the best next action.
aiuse -q --json

# Only actionable alerts for a short agent/tool call.
aiuse -q --json --alerts-only

# The single best pool to use next, or null when there is nothing urgent.
aiuse suggest --json

JSON is written to stdout; -q keeps progress off stderr. Exit 0 means a successful run with no burn/conserve alert, 1 is a hard collection failure, and 2 is a successful run with an actionable alert. The stable fields and exit-code contract are in docs/json-contract.md.

For a long-lived local agent, aiuse serve provides the same decisions through a loopback HTTP API; see the documentation index.

aiuse watch --all-providers (and the watch a key) is operator-only. AI agents and automation must not run it without explicit permission from the human operator. It polls every provider, deliberately overriding [disabled_services] and collector disable flags — providers are disabled for reasons (vendor rate limits, cost, opt-outs) that this sweep ignores. Its output is display-only: nothing is written to snapshots, the token ledger, or sampler state, though the shared cross-process query throttle still applies so the sweep cannot hammer a vendor.

Projects that want the ranking logic without depending on this CLI can reuse the language-neutral shared quota semantics: JSON Schemas, enums, pace rules, and golden fixtures are designed to be copied or validated from any language. aiuse uses those fixtures itself, but they do not require importing its Python package.

Flag Effect
(none) / --format pretty Clock matrix on stdout (empty→n/a→slow→mid→use); meta on stderr; plain when piped
--full Long pretty report: per-provider, cross-checks, tips, History, detailed plan
--json / --format json Full snapshot + alerts + suggestion + history as JSON (schema 1.2: state, usable_now, pool_family, pace_percent, pace_ratio, pace_early, overall_pace_percent, overall_pace_early, summary_lines, semantics)
--available / --live Routing shortlist: only pools usable now, per vendor + model family, sorted by headroom; reads the cache by default, --live forces a collect
usage-sources / --usage-sources Which quota tools and ACP context logs are active for each vendor. No collect, no ACP turn. [usage_sources] pins one source; the default still blends. See docs/acp-usage.md.
--brief Alias of the default pretty report
--no-tui Force classic plain-text pretty report
--no-color Disable ANSI colors in plain-text pretty mode
-q / --quiet Suppress progress messages on stderr
--alerts-only Recommendations only (respects pretty vs json)
suggest / --suggest Single best burn pool (or nothing urgent); pair with --json for structured
status / prompt / --status One-line status for shell prompts / status bars
serve / --serve Loopback HTTP API for agents (127.0.0.1)
--port / --max-age Serve bind port (default 28787; fails loudly if a non-aiuse server holds it) and snapshot cache max age
--print-completion bash|zsh Print shell completion script to stdout
--no-<collector> flags: tokscale, cswap, codexbar, caut, openusage-ai, openusage-sh, muse, qwencloud, bailian Skip specific collectors
--providers copilot,grok Query specific CodexBar providers (CSV, one per subprocess)
-t / --timeout SECONDS Force subprocess timeout for all external tools (default 45)
--generate-config Write default ~/.config/aiuse/config.toml; never overwrites existing
--show-config-path Print the active config path
watch / --watch -i SECONDS --once Full-screen board; keys: q/esc quit, u collect now (bypasses the cached snapshot), a one-time all-providers sweep (screen only). No collect ever overlaps another (a queues behind a running refresh); u/a share a 2min minimum; u within 90s of a is covered by that run
watch --all-providers Operator-only one-shot: every provider incl. [disabled_services] and disabled collectors, printed once, nothing recorded (no snapshot/ledger/sampler writes; query throttling still applies)
doctor / --doctor Check tools on PATH, config presence, effective timeouts; no collect
note-exhausted <provider> [--family F] --resets-in 4h53m|--resets-at ISO [--reason T] Record an agent-reported exhaustion override (advisory, expires at reset; honoured by --json/--available labelled source: agent-reported)
trust … macOS: codesign status, sign caut, and Keychain grant guide
credential refresh opencode-zen Validate a Chrome OpenCode session and save it through SecretSpec
--min-remaining 50 --max-days 10 Override alert thresholds
--save PATH Also write full JSON snapshot to PATH

Exit codes

Code When
0 Collect succeeded (or nothing to report) and there are no burn/conserve alerts. INFO-only notes still count as 0.
1 Hard failure: collectors reported errors and no accounts were collected. Also used by aiuse doctor when an enabled tool is missing from PATH, and by --generate-config when nothing was written / overwrite refused.
2 Collect succeeded and at least one burn or conserve alert is present. Cross-check disagreements alone do not set 2. Bad --timeout values also use 2.
3 --available only: the run succeeded but zero pools are usable right now (everything measured is exhausted or unknown). The data is fine; the quota is not.

aiuse doctor checks config file presence, config validation (unknown keys, bad timeouts, dead plan aliases), all seven data-source tools on PATH (and OpenUsage.ai loopback HTTP when the CLI is missing), and a light version probe (cswap --version, codexbar -V, caut --version, caam --version, tokscale --version). It does not call usage APIs or verify login sessions.

What “use it or lose it” means

Most subscription coding plans (Claude Pro/Max, ChatGPT Plus/Codex, Cursor, Copilot, SuperGrok, Google AI Pro, …) grant windows of usage (5-hour, weekly, monthly). When the window resets, unused capacity disappears — you still paid for the month.

This tool:

  1. Pulls remaining % and reset times from cswap (Claude multi-account), CodexBar (broad live quotas), caut, caam, OpenUsage.ai, OpenUsage.sh (cross-check peers / fill-in), and tokscale (independent measurement; preferred for Copilot).
  2. Scores windows with pace-based logic (default): compare how far through the cycle you are vs how much you've used, then project waste or early lockout.
  3. Classifies each window as Burn (will leave capacity unused), Conserve (on track to exhaust before reset — slow down), or On pace (no alert).
  4. For shared-allotment providers (Claude, Gemini by default), scores the longest governing window only so a fresh 5-hour bar does not outrank the weekly budget it draws from — but genuinely independent pools are never merged into that governing window: Cursor's Included+Auto pool and its separate Other Models pool are scored on their own, so an exhausted Other Models pool raises its own alert instead of being masked by a healthy Included. Claude's Fable cap is within the shared weekly pool (up to 50%, not additional quota): the main row shows overall usage, with an indented cap underneath. Fable at 100% does not exhaust other Claude models; shared exhaustion blocks Fable too.
  5. Qualifies Conserve alerts with overage awareness: if the account has a real or config-confirmed overage/extra-usage wallet (Claude's usage credits, Cursor's on-demand balance, or a manually confirmed OpenCode Go overage state), the message says so — the real risk there is unplanned $ spend, not lockout, which is a different situation from a genuinely hard ceiling.
  6. Default pretty output is a clock matrix on stdout — one row per account/pool, one column per reset clock (5H/WEEK/MONTH) plus a PACE column for the row's highest pace, each cell displaying used% u / left% l / reset_span pace% (75u/25l/4h -10%, 89u/11l/2d14h +180%; depleted → prepaid n/a → conserve → mid → use-soon at bottom; read bottom→top). Meta goes to stderr. Use aiuse --full for per-provider detail.
  7. On --full, keeps the trailing plan within ~23 lines × console width when possible; if the detailed plan is taller, both detailed and at a glance are printed (glance last). Forecast fragments (~lockout …, projected waste %) appear on table/status lines when pace can project them.
  8. Cross-checks all live sources pairwise; Claude multi-account stays canonical in cswap.
  9. Optional surfaces: aiuse suggest (single burn winner), aiuse status / prompt (one-liner), and aiuse serve (loopback ranking API for agents). Snapshot history can blend into pace when enabled.

This command intentionally does not report historical local-token usage or API-equivalent cost estimates (use ccusage-class tools for local burn, not plan %).

Example output

================================================================================
AI USAGE — USE IT OR LOSE IT
Collected at … · 3 accounts · 2 alerts
================================================================================

## Per-provider usage
--------------------------------------------------------------------------------
Codex · account=you@example.com · plan=plus · selected live source: CodexBar
  quota: Codex weekly quota
    [============] 100% left   0% used   resets in 6.4d (Tue Jul 28 9:59pm)
    flex:▒ semi · pace -100%

## Cross-checks (informational)
--------------------------------------------------------------------------------
  Tools poll at different times; multi-account Claude is cswap-only. …

## Tips
--------------------------------------------------------------------------------
  • …

## Action plan — use these before they reset
--------------------------------------------------------------------------------
  6 windows with unused capacity across 5 providers.

  THIS WEEK (start now — capacity will reset or needs lead time)
  ─────────────────────────────────────────────────────────────
  .   Codex · you@example.com · Codex weekly quota: 88% left · use within 6.4 days · pace -40% — projected 52% unused@reset
      Semi-throttled — steady usage will exhaust it.
  .   OpenCode Go · default · OpenCode Go weekly quota: 98% left · use within 4.5 days · pace -95% — projected 91% unused@reset
      Burstable — one heavy session will cover it.

Project layout

src/aiuse/
  cli.py                 # entrypoint
  collectors/            # cswap, codexbar, caut, caam, openusage, tokscale
  analysis/use_or_lose.py
  report.py
config/config.example.toml
tests/

Tests

just test
just check # tests plus deterministic lint, type, spelling, and format checks
just lint  # full check plus Bandit, Semgrep, and Gitleaks
just format

The quality suite mirrors the applicable tools from stayturgid: pytest, Ruff, mypy, yamllint, markdownlint, Prettier (including TOML support), typos, Bandit, Semgrep, Gitleaks, pre-commit, and just. Ansible, shell, JavaScript/CSS, dotenv, Caddy, and browser-page checks are omitted because this repository contains none of those corresponding inputs.

Pace settings

Pace knobs (in config.toml under [analysis.pace]):

  • waste_alert_fraction (default 0.30) — project this much unused → Burn
  • min_elapsed_fraction (default 0.15) — too early in the window → On pace unless history says otherwise
  • conserve_min_lead_hours (default 4) — exhaust this far before reset → Conserve

Shared allotment: analysis.provider_overrides.<provider>.shared_allotment: true (Claude/Gemini default) scores only the longest window per account.

Lapsed subscriptions: analysis.lapsed_accounts maps "provider/account" to a reason (e.g. "claude/me@mit.edu" = "not renewed"). A not-renewed plan keeps serving stale collector cache that looks like usable quota; the entry makes that account show as empty instead of on-pace.

Excluded pools: analysis.excluded_pools maps "provider" or "provider/pool_family" to a reason (e.g. "grok" = "reserved for another agent"). The quota stays in every report, but aiuse --available leaves the pool out of its shortlist and lists it under excluded (JSON) or on stderr (text), so orchestrators never route to it.

Disabled services: top-level [disabled_services] maps "provider" to a reason (e.g. "grok" = "vendor shelved until its reset"). Stronger than an exclusion — for TUIs that must temporarily not be used even though they have headroom: provider-only collectors skip the service entirely (no subprocess/authenticated fetch), its rows are dropped from every report, snapshot and history entry, --available never lists it (even from a cache written before the entry), and the reason travels on the snapshot as disabled_services so readers know why the provider is absent. aiuse doctor warns when a provider-only collector override for a disabled provider silently has no effect.

Notes / limitations

  • Live quota accuracy depends on each tool's auth (browser cookies, OAuth, keychain). Errors are reported per account rather than aborting the whole run.
  • All enabled collectors (cswap, CodexBar, caut, caam, OpenUsage.ai, OpenUsage.sh, tokscale, qwencloud, bailian, sipb) run concurrently; each CodexBar provider is its own subprocess. Default tool timeout is 45s; CodexBar OpenCode Go is 60s ([collectors.codexbar] provider_timeouts); cswap, caam, and openusage_sh are 90s; the opt-in sipb probe defaults to 120s (the MIT server is slow) (-t / config.toml [timeouts]).
  • Per-window detail still shows $ value, flexibility class, and a pace ratio when computable.
  • Duplicate live measurements are retained for cross-checking but only one copy drives recommendations.
  • Dollar values use plan monthly_price (a per-account [plans.<provider>."<account>"] price beats the provider's) with waking-hours correction (default 16h/day). A provider with no price shows no dollar figure.

Further documentation

About

CLI that ranks which AI coding subscription quotas to burn before they reset (use-it-or-lose-it)

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages