{"id":50847791,"url":"https://github.com/jayfarei/lazyusage","last_synced_at":"2026-06-14T11:04:04.129Z","repository":{"id":364269876,"uuid":"1150783825","full_name":"JayFarei/lazyusage","owner":"JayFarei","description":"Capacity monitoring for Claude and Codex subscriptions: a tmux-popup dashboard for humans, a JSON capacity API for agents","archived":false,"fork":false,"pushed_at":"2026-06-12T10:21:38.000Z","size":2278,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T11:20:49.855Z","etag":null,"topics":["agents","bun","claude","cli","codex","rate-limits","tmux","tui"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JayFarei.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-05T17:27:15.000Z","updated_at":"2026-06-12T10:21:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/JayFarei/lazyusage","commit_stats":null,"previous_names":["jayfarei/lazyusage"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/JayFarei/lazyusage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JayFarei%2Flazyusage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JayFarei%2Flazyusage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JayFarei%2Flazyusage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JayFarei%2Flazyusage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JayFarei","download_url":"https://codeload.github.com/JayFarei/lazyusage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JayFarei%2Flazyusage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34318527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","bun","claude","cli","codex","rate-limits","tmux","tui"],"created_at":"2026-06-14T11:03:57.260Z","updated_at":"2026-06-14T11:04:04.122Z","avatar_url":"https://github.com/JayFarei.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lazyusage\n\n```text\n█░░ ▄▀█ ▀█ █▄█ █░█ █▀ ▄▀█ █▀▀ █▀▀\n█▄▄ █▀█ █▄ ░█░ █▄█ ▄█ █▀█ █▄█ ██▄\n```\n\n[![CI](https://github.com/jayfarei/lazyusage/actions/workflows/ci.yml/badge.svg)](https://github.com/jayfarei/lazyusage/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Runtime: Bun](https://img.shields.io/badge/runtime-bun%20%E2%89%A51.3-black)](https://bun.sh)\n\n**Know how much AI subscription capacity you have left, and put all of it to work.**\n\n\u003cimg src=\"docs/assets/tui.png\" alt=\"lazyusage TUI: Claude and Codex panels with pace bars, OVER BUDGET warnings, and a per-project token ledger\" width=\"843\"\u003e\n\n`lazyusage` answers the questions you actually ask about your Claude and Codex subscriptions:\n\n- **\"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.\n- **\"Which of my projects is eating the tokens?\"** A per-project ledger (Daily / Weekly / Monthly) built from your local session history.\n- **\"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.\n- **\"How much will I have spare by the reset?\"** Recorded usage history feeds an end-of-window prediction you can plan unsupervised work against.\n\nIt serves two audiences with the same data:\n\n1. **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.\n2. **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.\n\n## Quick start\n\n```bash\n# Install\nbun add -g lazyusage\n\n# Interactive dashboard\nlazyusage\n\n# One-shot JSON for agents/scripts\nlazyusage --json\n\n# Most compact burn-rate check\nlazyusage --capacity\n\n# Lightweight point-in-time check\nlazyusage usage-check --json\n```\n\nRequirements: Bun `\u003e= 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).\n\n## How it works\n\nEach 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.\n\n```text\n  ┌────────────────┐      ┌────────────────┐\n  │   Claude API   │      │   Codex API    │           data sources\n  │  (OAuth creds) │      │  (auth.json)   │\n  └───────┬────────┘      └───────┬────────┘\n          │                       │\n          ▼                       ▼\n  ┌─────────────────────────────────────────┐\n  │            fallback chain               │   per service, in order:\n  │                                         │\n  │  API ─► token refresh ─► PTY (tmux)     │   fresh API data, refreshed\n  │              ─► cache ─► fallback zeros │   creds, driving the real CLI,\n  │                                         │   last good data, safe zeros\n  └────────────────────┬────────────────────┘\n                       │ snapshots\n                       ▼\n              ┌─────────────────┐\n              │  SQLite store   │◄────── collector daemon (optional,\n              └────────┬────────┘        always-on, samples on interval)\n                       │\n      ┌────────────────┼────────────────┬─────────────────┐\n      ▼                ▼                ▼                 ▼\n  ┌────────┐    ┌─────────────┐   ┌───────────┐   ┌──────────────┐\n  │  TUI   │    │ --text/json │   │ HTTP/SSE  │   │  --predict   │\n  │ (popup)│    │  (agents)   │   │  server   │   │  + planning  │\n  └────────┘    └─────────────┘   └───────────┘   └──────────────┘\n```\n\nEvery snapshot carries its provenance (`source`, `stale`, `error`), so consumers can tell fresh data from a cached or fallback answer.\n\n### The capacity model\n\nThe key derived metric is `capacity_remaining`: how far ahead of (or behind) pace you are within the current window.\n\n```text\n  time elapsed     ▓▓▓▓▓▓▓▓▓░░░░░░░░░░░  45%\n  allowance used   ▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░  50%\n                            └──────────  capacity_remaining = 45 - 50 = -5%\n                                         (negative: burning faster than time passes)\n```\n\nA 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.\n\n## The TUI\n\n- 2x2 grid: one row per service, usage bars on the left, per-project token ledger on the right\n- `Tab` cycles stats tabs (Daily, Weekly, Monthly, and Graph when the daemon is running)\n- `j/k` navigate metrics, `g` fullscreen, `p` pause refresh, `?` help, `q` quit\n- `lazyusage claude` or `lazyusage codex` shows a single service\n\n### tmux popup\n\nThe TUI is designed to live in a tmux popup, a one-keystroke overlay on top of whatever you are doing. To set it up:\n\n1. Make sure `lazyusage` is on your `PATH` (`bun add -g lazyusage`), or use the full path to the binary in the binding below.\n\n2. Add a binding to `~/.tmux.conf`:\n\n   ```bash\n   # Open lazyusage in a popup with prefix + u\n   bind-key u display-popup -E -w 90% -h 80% \"lazyusage\"\n   ```\n\n3. Reload your tmux configuration:\n\n   ```bash\n   tmux source-file ~/.tmux.conf\n   ```\n\n4. 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.\n\nUseful variants:\n\n```bash\n# Claude only, smaller popup\nbind-key U display-popup -E -w 70% -h 50% \"lazyusage claude\"\n\n# Bind without the prefix (root table), e.g. Alt+u\nbind-key -n M-u display-popup -E -w 90% -h 80% \"lazyusage\"\n\n# Running from a source checkout instead of a global install\nbind-key u display-popup -E -w 90% -h 80% \"cd /path/to/lazyusage \u0026\u0026 bun run lazyusage\"\n```\n\nThis 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.\n\n## For agents\n\n### Output modes\n\n```bash\nlazyusage --capacity            # most compact: capacity_remaining only\nlazyusage --text                # one line per service, all fields\nlazyusage --json                # structured snapshot\nlazyusage --json --live         # continuous NDJSON stream\nlazyusage --json-only           # machine-safe: errors as JSON on stdout\nlazyusage claude --json         # single service\nlazyusage usage-check --json    # fast point-in-time check\n```\n\nWhat the text modes look like:\n\n```text\n$ lazyusage --capacity\nClaude: Session: -5% | Weekly: -4% | Sonnet: +6% [Subscription: max]\nCodex: Session: +19% | Weekly: +4% [Subscription: pro]\n\n$ lazyusage --text\nClaude: Session: 50% allowance used, 45% time elapsed, -5% capacity remaining (resets 1:20pm) | ...\nCodex: Session: 5% allowance used, 24% time elapsed, 19% capacity remaining (resets 2:22pm) | ...\n```\n\n### JSON contract\n\nSnapshot responses include resource-awareness metadata so agents can distinguish fresh data from fallback or cached data.\n\n```json\n{\n  \"timestamp\": \"2026-03-22T12:00:00.000Z\",\n  \"available_services\": [\"claude\", \"codex\"],\n  \"services\": [\n    {\n      \"name\": \"claude\",\n      \"available\": true,\n      \"source\": \"api\",\n      \"stale\": false,\n      \"error\": null,\n      \"subscription_type\": \"Max\",\n      \"metrics\": [\n        {\n          \"name\": \"session\",\n          \"used_pct\": 26,\n          \"remaining_pct\": 74,\n          \"time_elapsed_pct\": 61,\n          \"capacity_remaining\": 35,\n          \"resets\": \"9:00pm\"\n        }\n      ]\n    }\n  ]\n}\n```\n\nImportant fields:\n\n- `source`: where the snapshot came from (`api`, `pty`, `cache`, `fallback`)\n- `stale`: whether the last good result is being reused\n- `error`: fetch failure detail when the service could not return a fresh clean result\n- `remaining_pct`: hard limit headroom\n- `capacity_remaining`: burn-rate headroom relative to elapsed time\n\nTreat `remaining_pct` as the hard gate. Treat `source`, `stale`, and `error` as confidence signals.\n\n### Skill and prompt templates\n\nThe canonical agent skill lives at [`skills/lazyusage/SKILL.md`](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.\n\nCopy-paste prompt templates for goal/loop agents:\n\n- [`skills/lazyusage/templates/claude-goal-capacity.prompt.md`](skills/lazyusage/templates/claude-goal-capacity.prompt.md): Claude agent on a goal that may only spend a fixed share of remaining capacity\n- [`skills/lazyusage/templates/codex-goal-capacity.prompt.md`](skills/lazyusage/templates/codex-goal-capacity.prompt.md): the same capacity-budget protocol for Codex agents (`5h` / `weekly` metric keys)\n- [`skills/lazyusage/templates/claude-session-guard.prompt.md`](skills/lazyusage/templates/claude-session-guard.prompt.md): Claude agent that pauses itself near the 5-hour session limit\n\nRunnable examples:\n\n- [`examples/agent_integration.ts`](examples/agent_integration.ts)\n- [`examples/agent_integration.sh`](examples/agent_integration.sh)\n- [`examples/dashboard/README.md`](examples/dashboard/README.md)\n\n### Capacity budgets for unsupervised work\n\nA 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.\n\n```bash\n# Gate a work loop on a capacity budget:\n# unsupervised work may use at most 40% of what currently remains.\nSTART=$(lazyusage usage-check claude --json-only | jq '[.services[] | select(.name==\"claude\").metrics[] | select(.name==\"week_all\").remaining_pct] | first')\nBUDGET=$(echo \"$START * 0.4\" | bc)\n\nwhile true; do\n  NOW=$(lazyusage usage-check claude --json-only | jq '[.services[] | select(.name==\"claude\").metrics[] | select(.name==\"week_all\").remaining_pct] | first')\n  SPENT=$(echo \"$START - $NOW\" | bc)\n  if [ \"$(echo \"$SPENT \u003e= $BUDGET\" | bc)\" -eq 1 ]; then\n    echo \"capacity budget exhausted, stopping unsupervised work\"\n    break\n  fi\n  run_one_unit_of_work\ndone\n```\n\nThe 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.\n\n## Collector daemon\n\nFor 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.\n\n```text\n  lazyusage daemon start                  TUI startup\n        │                                     │\n        ▼                                     ▼ daemon healthy?\n  ┌──────────────┐    snapshots    ┌────────────────┐\n  │  collector   │────────────────►│  SQLite store  │──► Graph tab, history,\n  │ (60s cycle)  │                 └────────────────┘    predictions\n  └──────────────┘                 TUI reads stored snapshots instead of\n                                   starting its own collection chain\n```\n\n```bash\nlazyusage daemon start      # start in the background\nlazyusage daemon status     # health, last collection, data freshness\nlazyusage daemon logs       # recent log output\nlazyusage daemon stop       # stop the daemon\n\n# Run at login as a background service\nlazyusage daemon install    # launchd agent on macOS, systemd user unit on Linux\nlazyusage daemon uninstall\n```\n\nConfiguration 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).\n\n## Capacity prediction and planning\n\n`lazyusage` can project how much spare capacity you will have at the end of the current weekly window, based on your recorded usage history:\n\n```bash\n# Show predicted spare capacity at window end\nlazyusage --predict\n\n# Mark upcoming days with an expected work intensity (regime) to refine the prediction\nlazyusage plan 2026-06-15 H        # High, ~15%/day\nlazyusage plan 2026-06-16 L        # Low, ~3%/day\nlazyusage plan list\nlazyusage plan clear 2026-06-15\nlazyusage plan clear --all\n```\n\nRegimes: `L` (Low, 3%/day), `M` (Medium, 9%/day), `H` (High, 15%/day), `B` (Burst, 25%/day).\n\nThis 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`](docs/design/01-capacity_prediction.md).\n\n## Local server\n\nThe server is designed for local tooling. It binds to `127.0.0.1` by default and is intended for localhost browser or agent consumers.\n\n```bash\nlazyusage --serve\nlazyusage --serve --port 3000\nlazyusage --serve --host 0.0.0.0 --port 3000\n```\n\nEndpoints:\n\n- `GET /` all configured services\n- `GET /claude` Claude only\n- `GET /codex` Codex only\n- `GET /health` server metadata\n- `GET /stream` SSE stream for all configured services\n- `GET /stream/claude` SSE stream for Claude only\n- `GET /stream/codex` SSE stream for Codex only\n\n## Install\n\n### Fastest path\n\n```bash\nbunx lazyusage --help\n```\n\n### Global install\n\n```bash\nbun add -g lazyusage\nlazyusage --help\n```\n\n### From source\n\n```bash\ngit clone https://github.com/jayfarei/lazyusage.git\ncd lazyusage\nbun install\nbun run build\nbun run lazyusage --help\n```\n\n## Styling\n\nThe TUI ships with an intentional default theme instead of pretending to be fully themeable. An alternate monochrome palette is available for minimal terminals:\n\n```bash\nLAZYUSAGE_THEME=monochrome lazyusage\n```\n\n## Repository layout\n\n```text\npackages/\n  core/      data collection, parsing, storage, formatting (publishable library)\n  cli/       TUI application + CLI commands (publishable CLI)\n  e2e/       end-to-end tests via tmux (private)\ntests/       unit tests (core, cli, tui)\nskills/      canonical agent skill + prompt templates\nexamples/    agent integration examples + browser dashboard\ndocs/        design documents (docs/design/) and research notes (docs/research/)\nscripts/     build tooling\n```\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide, and [ROADMAP.md](ROADMAP.md) for planned work.\n\n```bash\nbun install\nbun run build\nbun run test:core\nbun run test:cli\nbun run test:tui\nbun run test:smoke\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjayfarei%2Flazyusage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjayfarei%2Flazyusage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjayfarei%2Flazyusage/lists"}