█░░ ▄▀█ ▀█ █▄█ █░█ █▀ ▄▀█ █▀▀ █▀▀
█▄▄ █▀█ █▄ ░█░ █▄█ ▄█ █▀█ █▄█ ██▄
Know how much AI subscription capacity you have left, and put all of it to work.
lazyusage answers the questions you actually ask about your Claude and Codex subscriptions:
- "Am I overspending against my weekly capacity?" Pace bars compare allowance burned vs time elapsed, and flag
OVER BUDGETthe moment you burn faster than the window refills. - "Which of my projects is eating the tokens?" A per-project ledger (Daily / Weekly / Monthly) built from your local session history.
- "Can I give agents 50% of what's left, and have them go to sleep when it's spent?" A JSON capacity API plus copy-paste prompt templates let goal/loop agents budget themselves to a slice of remaining capacity and stop cleanly when it runs out.
- "How much will I have spare by the reset?" Recorded usage history feeds an end-of-window prediction you can plan unsupervised work against.
It serves two audiences with the same data:
- Humans, via a tmux-popup dashboard. Bind the TUI to a key and get a one-keystroke overlay over whatever you are doing, without leaving your editor or agent session.
- Agents, via a capacity API. Agents on a goal, workflow, or loop check how much capacity is left before expensive work, and layer capacity-management strategies on top of the JSON output.
# Install
bun add -g lazyusage
# Interactive dashboard
lazyusage
# One-shot JSON for agents/scripts
lazyusage --json
# Most compact burn-rate check
lazyusage --capacity
# Lightweight point-in-time check
lazyusage usage-check --jsonRequirements: Bun >= 1.3, plus the Claude CLI (claude) and/or Codex CLI (codex) in PATH. tmux is optional (PTY fallback and some end-to-end tests).
Each service is fetched through a fallback chain: the first source that answers wins, and every snapshot is stored locally so history and predictions survive restarts.
┌────────────────┐ ┌────────────────┐
│ Claude API │ │ Codex API │ data sources
│ (OAuth creds) │ │ (auth.json) │
└───────┬────────┘ └───────┬────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ fallback chain │ per service, in order:
│ │
│ API ─► token refresh ─► PTY (tmux) │ fresh API data, refreshed
│ ─► cache ─► fallback zeros │ creds, driving the real CLI,
│ │ last good data, safe zeros
└────────────────────┬────────────────────┘
│ snapshots
▼
┌─────────────────┐
│ SQLite store │◄────── collector daemon (optional,
└────────┬────────┘ always-on, samples on interval)
│
┌────────────────┼────────────────┬─────────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌─────────────┐ ┌───────────┐ ┌──────────────┐
│ TUI │ │ --text/json │ │ HTTP/SSE │ │ --predict │
│ (popup)│ │ (agents) │ │ server │ │ + planning │
└────────┘ └─────────────┘ └───────────┘ └──────────────┘
Every snapshot carries its provenance (source, stale, error), so consumers can tell fresh data from a cached or fallback answer.
The key derived metric is capacity_remaining: how far ahead of (or behind) pace you are within the current window.
time elapsed ▓▓▓▓▓▓▓▓▓░░░░░░░░░░░ 45%
allowance used ▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░ 50%
└────────── capacity_remaining = 45 - 50 = -5%
(negative: burning faster than time passes)
A positive value means you can speed up; a negative value means at the current pace you will hit the limit before the window resets. The TUI surfaces this as ⚡ OVER BUDGET warnings; agents read it from JSON.
- 2x2 grid: one row per service, usage bars on the left, per-project token ledger on the right
Tabcycles stats tabs (Daily, Weekly, Monthly, and Graph when the daemon is running)j/knavigate metrics,gfullscreen,ppause refresh,?help,qquitlazyusage claudeorlazyusage codexshows a single service
The TUI is designed to live in a tmux popup, a one-keystroke overlay on top of whatever you are doing. To set it up:
-
Make sure
lazyusageis on yourPATH(bun add -g lazyusage), or use the full path to the binary in the binding below. -
Add a binding to
~/.tmux.conf:# Open lazyusage in a popup with prefix + u bind-key u display-popup -E -w 90% -h 80% "lazyusage"
-
Reload your tmux configuration:
tmux source-file ~/.tmux.conf -
Press
prefix + u(default prefix isCtrl-b) to open the dashboard, andqto dismiss it.-Ecloses the popup automatically when the TUI exits.
Useful variants:
# Claude only, smaller popup
bind-key U display-popup -E -w 70% -h 50% "lazyusage claude"
# Bind without the prefix (root table), e.g. Alt+u
bind-key -n M-u display-popup -E -w 90% -h 80% "lazyusage"
# Running from a source checkout instead of a global install
bind-key u display-popup -E -w 90% -h 80% "cd /path/to/lazyusage && bun run lazyusage"This pairs well with long-running agent sessions: keep agents working in your panes, pop the dashboard over them when you want to see how much subscription headroom they have left.
lazyusage --capacity # most compact: capacity_remaining only
lazyusage --text # one line per service, all fields
lazyusage --json # structured snapshot
lazyusage --json --live # continuous NDJSON stream
lazyusage --json-only # machine-safe: errors as JSON on stdout
lazyusage claude --json # single service
lazyusage usage-check --json # fast point-in-time checkWhat the text modes look like:
$ lazyusage --capacity
Claude: Session: -5% | Weekly: -4% | Fable: +6% [Subscription: max]
Codex: Session: +19% | Weekly: +4% [Subscription: pro]
$ lazyusage --text
Claude: Session: 50% allowance used, 45% time elapsed, -5% capacity remaining (resets 1:20pm) | ...
Codex: Session: 5% allowance used, 24% time elapsed, 19% capacity remaining (resets 2:22pm) | ...
Snapshot responses include resource-awareness metadata so agents can distinguish fresh data from fallback or cached data.
{
"timestamp": "2026-03-22T12:00:00.000Z",
"available_services": ["claude", "codex"],
"services": [
{
"name": "claude",
"available": true,
"source": "api",
"stale": false,
"error": null,
"subscription_type": "Max",
"metrics": [
{
"name": "session",
"used_pct": 26,
"remaining_pct": 74,
"time_elapsed_pct": 61,
"capacity_remaining": 35,
"resets": "9:00pm"
}
]
}
]
}Important fields:
source: where the snapshot came from (api,pty,cache,fallback)stale: whether the last good result is being reusederror: fetch failure detail when the service could not return a fresh clean resultremaining_pct: hard limit headroomcapacity_remaining: burn-rate headroom relative to elapsed time
Treat remaining_pct as the hard gate. Treat source, stale, and error as confidence signals.
The canonical agent skill lives at skills/lazyusage/SKILL.md. It covers pre-flight capacity checks, adaptive throttling, stale/fallback-aware decision making, sleep-until-reset logic, service failover, and shared local server usage for multiple agents.
Copy-paste prompt templates for goal/loop agents:
skills/lazyusage/templates/claude-goal-capacity.prompt.md: Claude agent on a goal that may only spend a fixed share of remaining capacityskills/lazyusage/templates/codex-goal-capacity.prompt.md: the same capacity-budget protocol for Codex agents (5h/weeklymetric keys)skills/lazyusage/templates/claude-session-guard.prompt.md: Claude agent that pauses itself near the 5-hour session limit
Runnable examples:
A simple, robust pattern for agents on a goal/loop: give background work only a fixed share of the remaining capacity and stop when it is spent.
# Gate a work loop on a capacity budget:
# unsupervised work may use at most 40% of what currently remains.
START=$(lazyusage usage-check claude --json-only | jq '[.services[] | select(.name=="claude").metrics[] | select(.name=="week_all").remaining_pct] | first')
BUDGET=$(echo "$START * 0.4" | bc)
while true; do
NOW=$(lazyusage usage-check claude --json-only | jq '[.services[] | select(.name=="claude").metrics[] | select(.name=="week_all").remaining_pct] | first')
SPENT=$(echo "$START - $NOW" | bc)
if [ "$(echo "$SPENT >= $BUDGET" | bc)" -eq 1 ]; then
echo "capacity budget exhausted, stopping unsupervised work"
break
fi
run_one_unit_of_work
doneThe same logic works against the HTTP server (GET /claude) when several agents share one collector, and --predict can replace the static 40% with a dynamic budget derived from predicted end-of-window spare capacity.
For continuous history (and the TUI's Graph tab), run the always-on collector daemon. It samples usage on an interval and stores snapshots in the local SQLite database, so history accumulates even when the TUI is closed.
lazyusage daemon start TUI startup
│ │
▼ ▼ daemon healthy?
┌──────────────┐ snapshots ┌────────────────┐
│ collector │────────────────►│ SQLite store │──► Graph tab, history,
│ (60s cycle) │ └────────────────┘ predictions
└──────────────┘ TUI reads stored snapshots instead of
starting its own collection chain
lazyusage daemon start # start in the background
lazyusage daemon status # health, last collection, data freshness
lazyusage daemon logs # recent log output
lazyusage daemon stop # stop the daemon
# Run at login as a background service
lazyusage daemon install # launchd agent on macOS, systemd user unit on Linux
lazyusage daemon uninstallConfiguration is optional and lives at ~/.config/lazyusage/daemon.toml. When the daemon is healthy, the TUI hydrates from its stored snapshots instead of starting its own collection chain, and the stats panel gains a Graph tab (cycle with Tab: Daily, Weekly, Monthly, Graph).
lazyusage can project how much spare capacity you will have at the end of the current weekly window, based on your recorded usage history:
# Show predicted spare capacity at window end
lazyusage --predict
# Mark upcoming days with an expected work intensity (regime) to refine the prediction
lazyusage plan 2026-06-15 H # High, ~15%/day
lazyusage plan 2026-06-16 L # Low, ~3%/day
lazyusage plan list
lazyusage plan clear 2026-06-15
lazyusage plan clear --allRegimes: L (Low, 3%/day), M (Medium, 9%/day), H (High, 15%/day), B (Burst, 25%/day).
This is the foundation for capacity-management strategies: if the prediction says you will end the week with 30% spare, you can decide to dedicate that slice to unsupervised agent work and keep the rest for interactive sessions. The design document lives at docs/design/01-capacity_prediction.md.
The server is designed for local tooling. It binds to 127.0.0.1 by default and is intended for localhost browser or agent consumers.
lazyusage --serve
lazyusage --serve --port 3000
lazyusage --serve --host 0.0.0.0 --port 3000Endpoints:
GET /all configured servicesGET /claudeClaude onlyGET /codexCodex onlyGET /healthserver metadataGET /streamSSE stream for all configured servicesGET /stream/claudeSSE stream for Claude onlyGET /stream/codexSSE stream for Codex only
bunx lazyusage --helpbun add -g lazyusage
lazyusage --helpgit clone https://github.com/jayfarei/lazyusage.git
cd lazyusage
bun install
bun run build
bun run lazyusage --helpThe TUI ships with an intentional default theme instead of pretending to be fully themeable. An alternate monochrome palette is available for minimal terminals:
LAZYUSAGE_THEME=monochrome lazyusagepackages/
core/ data collection, parsing, storage, formatting (publishable library)
cli/ TUI application + CLI commands (publishable CLI)
e2e/ end-to-end tests via tmux (private)
tests/ unit tests (core, cli, tui)
skills/ canonical agent skill + prompt templates
examples/ agent integration examples + browser dashboard
docs/ design documents (docs/design/) and research notes (docs/research/)
scripts/ build tooling
See CONTRIBUTING.md for the full guide, and ROADMAP.md for planned work.
bun install
bun run build
bun run test:core
bun run test:cli
bun run test:tui
bun run test:smoke