Skip to content

Repository files navigation

lazyusage

█░░ ▄▀█ ▀█ █▄█ █░█ █▀ ▄▀█ █▀▀ █▀▀
█▄▄ █▀█ █▄ ░█░ █▄█ ▄█ █▀█ █▄█ ██▄

CI License: MIT Runtime: Bun

Know how much AI subscription capacity you have left, and put all of it to work.

lazyusage TUI: Claude and Codex panels with pace bars, OVER BUDGET warnings, and a per-project token ledger

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 BUDGET the 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:

  1. 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.
  2. 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.

Quick start

# 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 --json

Requirements: 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).

How it works

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 capacity model

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.

The TUI

  • 2x2 grid: one row per service, usage bars on the left, per-project token ledger on the right
  • Tab cycles stats tabs (Daily, Weekly, Monthly, and Graph when the daemon is running)
  • j/k navigate metrics, g fullscreen, p pause refresh, ? help, q quit
  • lazyusage claude or lazyusage codex shows a single service

tmux popup

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:

  1. Make sure lazyusage is on your PATH (bun add -g lazyusage), or use the full path to the binary in the binding below.

  2. 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"
  3. Reload your tmux configuration:

    tmux source-file ~/.tmux.conf
  4. Press prefix + u (default prefix is Ctrl-b) to open the dashboard, and q to dismiss it. -E closes 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.

For agents

Output modes

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 check

What 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) | ...

JSON contract

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 reused
  • error: fetch failure detail when the service could not return a fresh clean result
  • remaining_pct: hard limit headroom
  • capacity_remaining: burn-rate headroom relative to elapsed time

Treat remaining_pct as the hard gate. Treat source, stale, and error as confidence signals.

Skill and prompt templates

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:

Runnable examples:

Capacity budgets for unsupervised work

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
done

The 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.

Collector daemon

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 uninstall

Configuration 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).

Capacity prediction and planning

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 --all

Regimes: 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.

Local server

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 3000

Endpoints:

  • GET / all configured services
  • GET /claude Claude only
  • GET /codex Codex only
  • GET /health server metadata
  • GET /stream SSE stream for all configured services
  • GET /stream/claude SSE stream for Claude only
  • GET /stream/codex SSE stream for Codex only

Install

Fastest path

bunx lazyusage --help

Global install

bun add -g lazyusage
lazyusage --help

From source

git clone https://github.com/jayfarei/lazyusage.git
cd lazyusage
bun install
bun run build
bun run lazyusage --help

Styling

The 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 lazyusage

Repository layout

packages/
  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

Development

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

License

MIT

About

Capacity monitoring for Claude and Codex subscriptions: a tmux-popup dashboard for humans, a JSON capacity API for agents

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages