cc-underuse
A Claude Code plugin that enforces a soft quota on your subscription usage. It gives
ambient awareness of your 5-hour rolling window and weekly limit, and gently
discourages burning through them — it never hard-blocks. It surfaces, nudges, and adds a
single speed-bump near the top.
It also supports per-instance pacing profiles: run one Claude Code instance for real
work unrestricted, and another for hobby tinkering on a strict trailing/lagging budget
so it backs off and leaves weekly headroom for the important instance. Because the weekly
counter is account-wide and shared, a low-priority instance self-throttles just by watching
the shared number — no cross-process coordination.
Pure Node.js, zero dependencies.
How it works
| Surface | Behavior |
|---|
| Status line | Live ⚡5h 23% · 📅wk 41% bar, colored green/yellow/red by severity. Also the data pump — it writes the latest numbers to a shared cache the hooks read. |
| Session start | Injects a usage summary (with reset times + active profile) so the session starts informed. |
| Before each prompt | At warn severity, adds a non-blocking note nudging Claude to be concise. At confirm severity, blocks the submission once per window (a speed-bump) — re-send to proceed. |
Where the numbers come from (hybrid)
- Primary (documented, free): the status-line stdin payload includes
rate_limits.{five_hour,seven_day} (Pro/Max, after the first response). The status line
writes these to the cache on every render.
- Fallback (only when the cache is missing/stale):
GET /api/oauth/usage using the
token in ~/.claude/.credentials.json. Any failure degrades silently to the last cached
value.
Install (from a clone)
Plugin commands are namespaced under the plugin name, so they are
/cc-underuse:cc-usage and /cc-underuse:cc-underuse-setup.
Option A — --plugin-dir (recommended for a clone)
Loads the plugin straight from your checkout. Best for iteration, and the status-line path
stays stable (your clone, not the ephemeral plugin cache).
claude --plugin-dir /path/to/cc-underuse
To avoid passing the flag every time, wrap it in a shell alias/function.
Option B — permanent install via the bundled marketplace
The repo ships a .claude-plugin/marketplace.json declaring itself as a single-plugin
marketplace, so it can be installed persistently:
/plugin marketplace add /path/to/cc-underuse
/plugin install cc-underuse@cc-underuse
Caveat: a marketplace install copies the plugin into ~/.claude/plugins/cache/..., and
that path changes on every update. Because setup writes an absolute status-line path,
re-run /cc-underuse:cc-underuse-setup after each plugin update. Option A avoids this.
Then, with either option
- Run
/cc-underuse:cc-underuse-setup. It seeds ~/.claude/cc-underuse/config.json and
adds the status line to ~/.claude/settings.json:
"statusLine": { "type": "command", "command": "node \"<plugin>/scripts/statusline.js\"", "padding": 0 }
(An absolute path is used because the status line is not a plugin-managed process.)
- Run
/reload (or restart Claude Code) so the status line takes effect.
Use /cc-underuse:cc-usage any time to print current usage, the active profile, and
per-bucket severity.
Profiles & assignment
Each instance resolves its profile in this order (first match wins):
CC_UNDERUSE_PROFILE env var — $env:CC_UNDERUSE_PROFILE="hobby"; claude
<project>/.cc-underuse.json → { "profile": "hobby" }
projects glob map in config → "C:/play/**": "hobby"
defaultProfile in config
Pacing models (profiles.<name>.pace.mode)
none — no pacing (default for coding).
lagging (default for hobby) — spreads the weekly limit as dailyBudgetPct
(100/7 ≈ 14.28/day) and keeps your cumulative usage one trailingDays behind full
pace: cap = max(0, dayIndex − trailingDays) × dailyBudgetPct. With trailingDays: 1,
the cap is 14% on day 2, 29% on day 3, … 86% by day 7 — always a day of buffer.
linear — even pace line plus trailingDays of slack (sprint then throttle).
sliding — caps usage within the trailing window (burn-rate limit); uses the
sampled usage history.
When usage reaches the pace cap it is treated as confirm; within warnMarginPct of it,
warn. Static thresholds and the optional reserve ceiling also apply — the worst wins.
Configuration (~/.claude/cc-underuse/config.json)