Metadata-Version: 2.5
Name: ccpace
Version: 0.8.0
Summary: Pace your Claude quota: multi-account usage monitor with a countable 5h-window budget, weekday forecasts, and push notifications
Project-URL: Homepage, https://thevibeworks.github.io/ccpace/
Project-URL: Repository, https://github.com/thevibeworks/ccpace
Project-URL: Changelog, https://github.com/thevibeworks/ccpace/blob/main/CHANGELOG.md
Author: thevibeworks
License: MIT
License-File: LICENSE
Keywords: claude,claude-code,monitor,quota,rate-limit,usage
Classifier: Environment :: Console
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Requires-Dist: httpx[socks]
Description-Content-Type: text/markdown

# ccpace

Pace your Claude quota. Multi-account usage monitor for Claude
subscriptions: real utilization from the official usage endpoint — not
estimates from transcripts — a countable 5h-window budget, weekday
forecasts learned from your own history, and push notifications.

```
── [20x] work · period ends ~Aug 11 ────────────────────────────────
5h     7% █▒░░░░░░░░  3h 48m   @19:00              0.3x
7d     3% █░░░░░░░░░  6d 8h    @Thu 13 00:00       0.3x
fable  3% █░░░░░░░░░  6d 8h    @Thu 13 00:00       0.3x
           ▁▁▂▮▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯▯┤
           budget: ~23 windows left · 4.2%/window stays even · period ends ~Aug 11
```

## Install

```sh
uvx ccpace                 # one glance, all discovered accounts
uvx ccpace --watch         # live TUI: r=refresh, q=quit
```

Or grab the single file — it is the whole tool:

```sh
curl -fsSLO https://raw.githubusercontent.com/thevibeworks/ccpace/main/ccpace.py
uv run --script ccpace.py
```

As a Claude Code plugin (`/ccpace` inside Claude Code):

```
/plugin marketplace add thevibeworks/ccpace
/plugin install ccpace@ccpace
```

Requires [uv](https://docs.astral.sh/uv/) and a Claude subscription
you are logged into (`claude login`); credentials are discovered from
`~/.claude/.credentials*.json`. Multiple credential files = fleet view,
sorted by tier.

## What it shows

- One block per account: 5h window, 7d window, per-model caps, extra
  usage spend, prepaid credit balance when nonzero.
- Dual bars merge usage with window-elapsed time: `█` both passed, `▓`
  usage ahead (hot), `▒` time ahead (headroom), `░` untouched.
- The window ledger: the 7d period as its 5h slots, one cell each.
  `▂▃▄▅▆▇█` what a slot burned (from your sample history), `▁` the
  baseline (ran, cost under a point — the shortest bar of the same block,
  so the zero line and the bars share one font), `░` unknown, `▮` now,
  `▯` ahead, `┤` access ends there (a dry projection never overwrites a
  cell — the `7d dry` advice row states the wall with its exact time).
  An ahead-cell you'll sleep through most of draws dim once your hours are
  learned — same glyph, tint stepped back, so the week ahead reads as a
  shape and not a count. The cells are a grid anchored to the period start,
  so read them for shape; the budget line's count comes from the clocks.
- The advisor: walls (`!`) and one budget line — windows left, the ration
  that keeps you even, and where the week lands. The landing comes from
  your own weekday profile once there are two weeks of history (`on your
  pattern`), from linear pace before that (`at this pace`). One model per
  block, named, so two numbers on screen never describe the same week
  differently.
- The forecast learns the hours you keep, not just the days: burn is
  shaped by local hour, so a dry-out lands where you will see it instead
  of at 03:00, and `~6 awake` beside `~9 windows left` rations the pool
  across the windows you are actually up for.
- Two pools, one wall: when a model-scoped weekly cap drains slower than
  the account's 7d, the 7d ends the week first and the rest of that model
  strands. The row above the budget says what this week's mix can still
  reach (`fable: ~15% of its 37% left reachable at this mix`).
- Budget math truncates at the subscription period end (derived from
  the billing anniversary — the API exposes no cancel/renew date, so
  the boundary is assumed and marked with `~`).
- A spent 5h window is named separately from the week behind it:
  `5h capped · 47% of 7d left · back @Tue 2 04:00`. Current Claude Code
  may offer `/low-priority` at that wall, but eligibility and its separate
  allowance travel with the session request, not `/api/oauth/usage`.
  ccpace therefore reports the proven wall and weekly headroom without
  claiming the mode is available for an account it cannot see into.

## Notifications

System notifications (macOS/Linux) fire on threshold, quota-full,
pace, and reset events. Add push channels:

```sh
ccpace --watch --ntfy https://ntfy.sh/your-topic
ccpace --watch --bark https://api.day.app/YOUR_KEY
ccpace --watch --bark                        # bark CLI env: BARK_KEY on BARK_SERVER
ccpace --watch --notifier ~/bin/my-hook.sh   # JSON on stdin
```

Custom notifier payloads carry a stable, inspectable `id` plus canonical
`window`, `utilization`, `reset_at`, and `reset_time` fields in `data`.
For example, `full:work:5h:2026-09-02T11:00:00+00:00` identifies one
condition across custom-notifier restarts.

Env: `CCPACE_NTFY`, `CCPACE_BARK`, `CCPACE_NOTIFIER`, `CCPACE_INTERVAL`,
`CCPACE_THRESHOLD`, `CCPACE_TZ` (e.g. `America/New_York,Asia/Tokyo`).
Bare `--bark` reads the bark CLI's own `BARK_KEY` / `BARK_SERVER`
(default `api.day.app`), and `BARK_GROUP` / `BARK_ICON` ride along when set.

## Data

Samples append to a shared store compatible with
[claude-code-statusline](https://github.com/thevibeworks/claude-code-statusline)
(`~/.claude/statusline/accounts/<alias>/usage.jsonl`): both tools feed
one history, so the ledger and forecasts get richer whichever tool you
run. Contract in [docs/data.md](docs/data.md). `--no-log` disables
writing; `CCPACE_DATA_DIR` relocates the store.

## Honest caveats

- Uses the same undocumented OAuth endpoints as the Claude Code CLI,
  read-only, against your own account. Anthropic can change or gate
  them at any release; expect breakage, report it, don't build a
  business on it.
- One deliberate write: expired tokens are refreshed via the official
  OAuth flow and written back to the credentials file — the same thing
  Claude Code does on your behalf.
- Polling asks only when the answer can have changed: one fetch pool
  shared with claude-code-statusline (same account, same directory, one
  request serves both); in watch mode an account is not re-fetched while
  Claude Code has done nothing since the last fetch (its history and
  statusline session state, across every container sharing `~/.claude`)
  and no window has reset — the block says `(idle 12m)`, `r` asks anyway.
  Reset boundaries wake the loop; the 15 min interval (± jitter, min 60 s)
  is the ceiling. A failed fetch keeps the last good numbers on screen,
  badged `(stale 12m · !429)`, and the next poll is the retry — nothing
  is locked out.
- A 5h or model-scoped cap does not freeze the account: lower-priority
  service or another model can still move 7d. Only an exhausted aggregate
  week with no paid path is cached to its reset, and both `r` and a newer
  shared statusline cache break that optimization.
- The grammar — rows, ledger, provenance, requests — is one page:
  [DESIGN.md](DESIGN.md).
- Forecasts are your own history extrapolated, not a promise. Below two
  weeks of samples the learned walk stays silent and the line falls back
  to linear pace, saying which one spoke. It also stays silent on a 7d
  window younger than a day, and on a profile whose numbers are
  impossible — a projection you cannot check is worse than none.
- Not affiliated with Anthropic.

## Development

```sh
make check    # the test suite
make run      # this tree, once, against your real accounts
make build    # wheel + sdist
```

Tests use their own `CCPACE_DATA_DIR`; nothing in `t/` touches the real
store. The suite is where the burn model lives in readable form — if you
change how burn is counted, that is the file to argue with first.

## License

MIT
