{"id":30444459,"url":"https://github.com/leeguooooo/claude-code-usage-bar","last_synced_at":"2026-06-08T03:06:54.765Z","repository":{"id":310760434,"uuid":"1041102492","full_name":"leeguooooo/claude-code-usage-bar","owner":"leeguooooo","description":"Real‑time statusline for Claude Code: token usage, remaining budget, burn rate, and depletion time","archived":false,"fork":false,"pushed_at":"2025-11-28T07:09:47.000Z","size":367,"stargazers_count":132,"open_issues_count":2,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-05T10:32:21.698Z","etag":null,"topics":["ai-tools","claude-ai","cli-tool","developer-tools","monitoring","productivity","python","status-bar","terminal-ui","tmux","token-monitoring","usage-tracking"],"latest_commit_sha":null,"homepage":null,"language":"Python","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/leeguooooo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"leeguooooo"}},"created_at":"2025-08-20T01:43:23.000Z","updated_at":"2026-01-03T10:07:28.000Z","dependencies_parsed_at":"2025-08-20T04:41:03.274Z","dependency_job_id":"cce407b2-4fb2-40bd-8359-b65097cfd513","html_url":"https://github.com/leeguooooo/claude-code-usage-bar","commit_stats":null,"previous_names":["leeguooooo/claude-code-usage-bar"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/leeguooooo/claude-code-usage-bar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leeguooooo%2Fclaude-code-usage-bar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leeguooooo%2Fclaude-code-usage-bar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leeguooooo%2Fclaude-code-usage-bar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leeguooooo%2Fclaude-code-usage-bar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leeguooooo","download_url":"https://codeload.github.com/leeguooooo/claude-code-usage-bar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leeguooooo%2Fclaude-code-usage-bar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:16:59.381Z","status":"ssl_error","status_checked_at":"2026-01-14T08:13:45.490Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai-tools","claude-ai","cli-tool","developer-tools","monitoring","productivity","python","status-bar","terminal-ui","tmux","token-monitoring","usage-tracking"],"created_at":"2025-08-23T10:02:17.016Z","updated_at":"2026-06-08T03:06:54.750Z","avatar_url":"https://github.com/leeguooooo.png","language":"Python","funding_links":["https://github.com/sponsors/leeguooooo"],"categories":["Usage Tracker"],"sub_categories":[],"readme":"# Claude Status Bar\n\n[![PyPI](https://img.shields.io/pypi/v/claude-statusbar.svg)](https://pypi.org/project/claude-statusbar/)\n[![Python](https://img.shields.io/pypi/pyversions/claude-statusbar.svg)](https://pypi.org/project/claude-statusbar/)\n[![Downloads](https://static.pepy.tech/badge/claude-statusbar/month)](https://pepy.tech/project/claude-statusbar)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/leeguooooo/claude-code-usage-bar?style=social)](https://github.com/leeguooooo/claude-code-usage-bar/stargazers)\n\nLightweight Claude Code status-line monitor. Shows your 5h / 7d rate-limit usage, reset timers, current model, context window, prompt-cache freshness, and (optionally) session cost — in a single compact line driven by Claude Code's `statusLine` hook.\n\n```\n5h[   27%    ]⏰1h28m →42% | 7d[   79%    ]⏰11h28m →88% | Opus 4.8(350.0k/1.0M) | cache 4m23s\n```\n\n![claude-statusbar live demo](docs/images/hero.gif)\n\n3 styles × 9 themes, configurable in one command. Auto-updates from PyPI. Just run `pip install claude-statusbar \u0026\u0026 cs --setup` and restart Claude Code.\n\n## Contents\n- [Latest release](#latest-release)\n- [What it shows](#what-it-shows)\n- [Install](#install)\n- [Styles \u0026 themes](#styles--themes)\n- [Configuration](#configuration-file)\n- [Fast mode (daemon)](#fast-mode--for-refreshinterval-1)\n- [Slash commands](#slash-commands-inside-claude-code)\n- [`cs doctor` — self-diagnostic](#cs-doctor--self-diagnostic)\n- [Usage cheatsheet](#usage)\n- [Environment variables](#environment-variables)\n- [How the cache countdown works](#how-the-cache-countdown-works)\n- [Troubleshooting](#troubleshooting)\n- [Upgrading](#upgrading)\n- [Comparison with alternatives](#comparison-with-alternatives)\n- [Integrations](#integrations)\n- [Contributing](#contributing)\n- [Acknowledgments](#acknowledgments)\n- [Contributors](#contributors)\n\n## Latest release\n\n**v3.11.0** (2026-06-02) — **rate-limit projections** (`show_projection`, default on): after each `⏰\u003creset\u003e` timer the bar shows `→NN%`, your expected end-of-window usage. The 5h model blends recent pace, whole-window average, and a local baseline; the 7d model integrates learned coarse rhythm buckets (work hours, non-work hours, night, weekend) so a busy first day is not blindly extrapolated across the whole week. `show_forecast` remains the separate `⚠\u003ceta\u003e` warning chip for imminent cap hits. Plus: `context_window.used_percentage = null` handled gracefully, and the daemon only renders windows active in the last 10s.\n\n**v3.10.0** (2026-06-02) — **live-activity line** (in-progress todo, active tool, completed-tool rollup), **git ahead/behind + session duration/lines** on the project line, **running-subagent** lines, an opt-in **`bar_shimmer`** starfield on the battery bars, and a **self-hosted plugin marketplace**. Plus: auto-update now actually runs in daemon mode (detached, non-blocking), and the cache countdown is per-session-correct. All new segments are opt-in except the todo line.\n\n**v3.6.0** (2026-05-08) — **`cs --setup` now defaults to daemon (fast) mode**: under 1% CPU continuously instead of ~3% inline. Pass `--inline` to opt back. Also: py3.9 compat fixes, GitHub Actions CI, animated hero GIF.\n\n**v3.5.1** — `npx skills add` install path, `show_cache_age` on by default.\n\n**v3.5.0** — consolidated `claude-statusbar` skill: say *\"switch theme to nord\"* / *\"余量颜色改成 #4ec85b\"* and Claude Code routes it to the right `cs` command.\n\n**v3.4** — per-segment color management (each metric colors itself by its own severity), classic style finally respects themes, two new themes (`catppuccin-mocha`, `tokyo-night`), per-severity color overrides via `cs config set color_ok|warn|hot`.\n\n**v3.2** — daemon fast-mode (now the default in v3.6.0) for ~5× lower CPU at `refreshInterval=1`.\n\n📋 **Full changelog:** [CHANGELOG.md](CHANGELOG.md) · [GitHub Releases](https://github.com/leeguooooo/claude-code-usage-bar/releases) — every version's changes, also linked from the [PyPI page](https://pypi.org/project/claude-statusbar/).\n\n## What it shows\n\n```\n5h[   27%    ]⏰1h28m →42% | 7d[   79%    ]⏰11h28m →88% | Opus 4.8(350.0k/1.0M) | cache 4m23s | $ 1.42\n⤷ claude-code-usage-bar ⎇ main● · +182 -47 · ⏱ 12m · v3.12.0\n⚙ effort:high · think:on · fast:off · style:default\n```\n\n| Segment | Meaning |\n|---------|---------|\n| `5h[27%]` | 5-hour rate-limit usage (rolling window from Anthropic API headers) |\n| `⏰1h28m` | Time until the 5-hour window resets |\n| `7d[79%]` | 7-day rate-limit usage |\n| `⏰11h28m` | Time until the 7-day window resets |\n| `→42%` / `→88%` | Projected end-of-window usage at your current rhythm (`show_projection`, on by default). Muted \u003c 80%, yellow ≥ 80%, red ≥ 100%. The 5h model blends recent pace + whole-window average + a local baseline; the 7d model integrates learned day/night/weekend buckets so a busy first day isn't extrapolated across the week. |\n| `⚠~18m` | At-risk warning chip — only when a window is projected to hit 100% **and** the cap is imminent (≤ 1 h). Separate from the projection (`show_forecast`, on by default). |\n| `Opus 4.8(350.0k/1.0M)` | Model name + current context window usage |\n| `cache 4m23s` / `cache COLD` | Countdown to prompt-cache expiry — the TTL (5min vs 1h) is auto-detected from the transcript, so it's right on a subscription (1h) or an API key (5min). Green when comfortable, yellow under 1min, red on COLD. Cache hits consume ~10× less rate-limit quota — for subscribers, letting it go COLD eats your 5h / 7d windows ~10× faster. Enabled by default; disable with `cs config set show_cache_age false` |\n| `$ 1.42` | Session cost in USD as Claude Code reports it. For Pro/Max subscribers this is the **API-equivalent value** of your usage (i.e. what it would cost on the API), not money owed. Useful as an ROI signal. Opt-in: `cs config set show_cost true` |\n| `⤷ \u003cproject\u003e ⎇ \u003cbranch\u003e●↑2↓1 · +182 -47 · ⏱ 12m` | Second-line identity + session line. Project comes from Claude Code's `workspace.repo.name` (cwd-basename fallback); branch reads `.git/HEAD` directly; the `●` dirty marker is refreshed by a background helper, cached 5 s. Enabled by default — turn off with `cs config set show_project_branch false`. `+added -removed` session lines (`show_lines`, +green/−red) also show by default. Opt-in extras live here too: `↑2↓1` commits ahead/behind upstream (`show_ahead_behind`, reuses the dirty-state `git status` — no extra spawn) and session `⏱` duration (`show_duration`). |\n| `▸ \u003ctask\u003e (3/7) · ◐ Edit auth.py · ✓ Read×3` | Third \"activity\" line — what's happening *right now*, parsed from the transcript: the in-progress **todo** + done/total (`show_todos`, on by default), the **active tool** (`◐`, `show_tools`), and an optional completed-tool rollup (`✓ name×N`, `show_tool_rollup`, default off). Omitted entirely when nothing is active. |\n| `◐ explore[haiku] \u003ctask\u003e 2m15s` | Bottom line(s) — one per running **subagent** (`show_agents`, opt-in, default **off**). Note: Claude Code already shows background agents in its own native panel, so this largely duplicates that; off by default for that reason. |\n| `⚙ effort:high · think:on · fast:off · style:default` | **Session-mode line** (`show_mode`, on by default) — how this turn is configured, from stdin. Tinted with a per-effort static gradient (`mode_gradient`) so the level reads at a glance. |\n| `📚 EN:6.0↑ JA:5.0→` | IELTS band progress (requires [prompt-language-coach](https://github.com/leeguooooo/prompt-language-coach)) |\n\nColors default to green / yellow / red at `30%` and `70%` — both thresholds configurable.\n\n## Install\n\n### Recommended: PyPI\n\n```bash\npip install claude-statusbar     # or: uv tool install claude-statusbar\n                                 # or: pipx install claude-statusbar\ncs --setup                       # wires the statusLine hook + installs the skill\n```\n\nRestart Claude Code to see the bar. `cs --setup` writes the following into `~/.claude/settings.json` (existing files are backed up first, other keys are preserved):\n\n```json\n{\n  \"statusLine\": {\n    \"type\": \"command\",\n    \"command\": \"cs render\",\n    \"refreshInterval\": 1\n  }\n}\n```\n\nSince v3.6.0 `cs --setup` defaults to daemon mode (`cs render` + `refreshInterval: 1`), which keeps CPU under 1% continuously while ticking the cache-age countdown every second. The daemon is auto-started by `cs --setup` and lazy-respawns on `cs render` if it ever dies, so you never see a frozen bar. Opt out with `cs --setup --inline` (writes plain `cs`, ~3% CPU at 1Hz) or set `refreshInterval` to a higher value — `cs --setup` preserves any explicit value you've already chosen.\n\n### Alternative: one-shot installer (audit first, then run)\n\nA bash helper is available if you'd rather not chain `pip install` + `cs --setup` manually. **Please read it before running** — it modifies `~/.claude/settings.json` and (with your explicit `[y/N]` consent) `~/.bashrc` / `~/.zshrc`:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/leeguooooo/claude-code-usage-bar/main/web-install.sh -o /tmp/cs-install.sh\nless /tmp/cs-install.sh    # audit it\nbash /tmp/cs-install.sh\n```\n\nOr, if you've already audited the script and trust this repo:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/leeguooooo/claude-code-usage-bar/main/web-install.sh | bash\n```\n\nThe header of [`web-install.sh`](web-install.sh) lists exactly what it touches.\n\n### Skill-only install (already have `cs`)\n\nIf you already have the `cs` binary installed (e.g. via `pip install`) and just want the conversational [`claude-statusbar` skill](#whats-new-in-v34) so Claude Code routes natural-language requests like \"switch theme to nord\" or \"余量颜色改成 #4ec85b\" to the right `cs` command:\n\n```bash\nnpx skills add leeguooooo/claude-code-usage-bar -g -y\n```\n\nThis installs only the skill globally. It does *not* install `cs` itself — the skill's actions all call out to the `cs` CLI, so you still need one of the install paths above for the binary. Use this path when distributing into environments that already manage Python tooling separately, or when you want to update only the skill without touching `cs`.\n\n`cs --setup` already installs the same skill alongside the slash commands, so most users don't need this path.\n\n## Styles \u0026 themes\n\nThe default style (`classic`) stays the same forever. Two alternative styles, plus a palette of seven themes, are opt-in.\n\n```bash\ncs --style capsule  --theme graphite   # try once\ncs --style hairline --theme twilight   # try once\ncs config set style capsule            # persist\ncs config set theme twilight\ncs styles                              # list available styles\ncs themes                              # list available themes\ncs preview                             # render every style × theme together\n```\n\n### Styles\n\n| Style | Look |\n|-------|------|\n| `classic`  | Original `[bar] \\| pipe` engineering layout. Default. |\n| `capsule`  | Each metric is a colored pill — type badge (`◷ 5H` / `☷ 7D` / `◆` / `📚`) on the left, value, severity dot on the right. Subway-signage feel. |\n| `hairline` | One-character mini-bar (`▁▃▆█`) per metric, dashed `┊` separators, tight typography. Maximally calm. |\n\n**Capsule** — `graphite` · `twilight` · `nord` · `dracula` · `sakura` · `linen` · `mono` · `catppuccin-mocha` · `tokyo-night`\n\n![capsule + graphite](docs/images/capsule-graphite.svg)\n![capsule + twilight](docs/images/capsule-twilight.svg)\n![capsule + nord](docs/images/capsule-nord.svg)\n![capsule + dracula](docs/images/capsule-dracula.svg)\n![capsule + sakura](docs/images/capsule-sakura.svg)\n![capsule + linen](docs/images/capsule-linen.svg)\n![capsule + mono](docs/images/capsule-mono.svg)\n\n**Hairline** — same theme set, different layout\n\n![hairline + graphite](docs/images/hairline-graphite.svg)\n![hairline + nord](docs/images/hairline-nord.svg)\n![hairline + dracula](docs/images/hairline-dracula.svg)\n![hairline + sakura](docs/images/hairline-sakura.svg)\n![hairline + mono](docs/images/hairline-mono.svg)\n\n**Classic** — kept identical to the pre-v2.7 look\n\n![classic + graphite](docs/images/classic-graphite.svg)\n\n### Themes\n\n| Theme | Vibe |\n|-------|------|\n| `graphite` | Cool dark graphite — default, fits most dark terminals |\n| `twilight` | Soft purples/roses — warm dark |\n| `linen`    | Cream/beige — for light terminal themes |\n| `nord`     | Nord palette — familiar Arctic blue |\n| `dracula`  | Dracula palette — high-contrast purple/black |\n| `sakura`   | Pink/cream — soft, light backgrounds |\n| `mono`     | Pure grayscale — no chromatic distraction |\n| `catppuccin-mocha` | Catppuccin Mocha — community-favorite pastel, easy on long viewing |\n| `tokyo-night` | Tokyo Night — deeper neon-blue mood with restrained accents |\n\nStyle and theme are independent: any of the **3 styles × 9 themes = 27 combinations**.\n\n### Slash commands inside Claude Code\n\nAfter running `cs --setup` (or `cs install-commands`), the following slash commands work inside Claude Code:\n\n| Slash command | What it does |\n|---------------|--------------|\n| `/statusbar`               | Show current config + lists styles/themes |\n| `/statusbar-preview`       | Render every style × theme combination using your real data |\n| `/statusbar-style \u003cname\u003e`  | Switch style (`classic` / `capsule` / `hairline`) |\n| `/statusbar-theme \u003cname\u003e`  | Switch theme (`graphite` / `twilight` / `linen` / `nord` / `dracula` / `sakura` / `mono` / `catppuccin-mocha` / `tokyo-night`) |\n| `/statusbar-doctor`        | Self-diagnostic — paste output in bug reports |\n| `/statusbar-reset`         | Wipe config back to defaults |\n\n### Configuration file\n\nPersisted to `~/.claude/claude-statusbar.json`:\n\n```json\n{\n  \"style\": \"capsule\",\n  \"theme\": \"twilight\",\n  \"density\": \"regular\",\n  \"auto_compact_width\": 100,\n  \"show_weekly\": true,\n  \"show_language\": true,\n  \"show_cost\": false,\n  \"show_cache_age\": true,\n  \"show_project_branch\": true,\n  \"show_todos\": true,\n  \"show_tools\": false,\n  \"show_agents\": false,\n  \"show_duration\": false,\n  \"show_lines\": true,\n  \"show_ahead_behind\": false\n}\n```\n\n| Key | Values | What it does |\n|-----|--------|--------------|\n| `style` | `classic` / `capsule` / `hairline` | Layout |\n| `theme` | `graphite` / `twilight` / `linen` / `nord` / `dracula` / `sakura` / `mono` / `catppuccin-mocha` / `tokyo-night` | Colors |\n| `density` | `compact` / `regular` / `cozy` | Padding around segments (capsule + hairline only) |\n| `auto_compact_width` | integer (e.g. `100`) | Force `hairline` when terminal narrower than this. `0` = disabled |\n| `show_weekly`, `show_language` | bool | Hide individual segments |\n| `show_cost` | bool, default `false` | Append `$ X.XX` — the current session's cost as Claude Code reports it. For Pro/Max subscribers this is the **API-equivalent value** of your usage (what it would cost on the API), not money owed; many subscribers use it as a \"subscription ROI\" gauge. Opt-in because the \"session\" boundary is what Claude Code reports — not necessarily what you intuitively call one. |\n| `show_cache_age` | bool, default `true` | Append a `cache 4m23s` countdown to Anthropic's prompt-cache expiry, with the TTL (5min vs 1h) auto-detected from the transcript. Three-level color: green (\u003e1min remaining), yellow (\u003c1min), red `cache COLD` (expired). Cache hits consume ~10× less rate-limit quota — for Pro/Max subscribers, letting it go COLD eats your 5h / 7d windows ~10× faster. `cs --setup` writes `refreshInterval: 1` by default so this segment ticks visibly. Original implementation contributed by [@marcwimmer](https://github.com/marcwimmer) in [#9](https://github.com/leeguooooo/claude-code-usage-bar/pull/9). Disable with `cs config set show_cache_age false`. |\n| `cache_ttl_seconds` | int, default `300` | **Deprecated since v3.9.0.** The segment now auto-detects the real TTL (5min vs 1h) from the transcript's `cache_creation` buckets, so this value is no longer consulted. Still accepted (and `cs config set cache_ttl_seconds …` still works) so existing configs don't break. See [How the cache countdown works](#how-the-cache-countdown-works). |\n| `show_project_branch` | bool, default `true` | Append a second line `⤷ \u003cproject\u003e ⎇ \u003cbranch\u003e●` below the bar. Project name comes from Claude Code's `workspace.repo.name` stdin field (falls back to cwd basename); branch is read from `.git/HEAD` directly. The `●` dirty marker is refreshed by a background helper and cached 5 s — the inline render path never blocks on `git`. Disable with `cs config set show_project_branch false`. |\n| `show_ahead_behind` | bool, default `false` | Append a `↑2↓1` commits-ahead/behind-upstream marker after the branch on the identity line. Reuses the same cached `git status --branch` call as the dirty dot, so it adds no extra git spawn. Only takes effect when `show_project_branch` is on (it lives on that line). Arrows show only for nonzero directions; in sync → nothing. |\n| `show_todos` | bool, default `true` | Third \"activity\" line: the in-progress todo + `done/total`, e.g. `▸ Wire the activity line (1/3)`. Parsed from the newest `TodoWrite` in the transcript (full list, last-write-wins) via the same bounded reverse-tail read as the cache countdown. The clearest \"is my long turn making progress?\" signal. Disable with `cs config set show_todos false`. |\n| `show_tools` | bool, default `false` | Activity line: the **active tool** (`◐ Edit auth.py` — the newest tool_use with no result yet). MCP names are shortened (`mcp__figma__get_screenshot` → `get_screenshot`). Opt-in. |\n| `show_tool_rollup` | bool, default `false` | Activity line: a frequency rollup of recently-completed tools (`✓ Edit×14 Bash×6 Read×4`). A volume tally rather than a live signal — separate from `show_tools` and off by default. Opt-in. |\n| `bar_shimmer` | bool, default `false` | **Experimental, classic style only.** A faint twinkling starfield in the *empty* part of the 5h/7d battery bars (static high/mid/low dot field + bright `✦`/`✧` stars winking in/out). The fill color is never changed. Capped at the statusLine's ~1Hz refresh, so it's a gentle twinkle, not a smooth animation. Off by default. |\n| `show_projection` | bool, default `true` | Appends an always-visible `→NN%` projection after each 5h/7d reset timer, estimating the percentage expected at reset. The 5h model blends recent pace, whole-window average, and local baseline; the 7d model integrates learned coarse rhythm buckets (work hours, non-work hours, night, weekend) so a busy first day is not blindly extrapolated across the whole week. Disable with `cs config set show_projection false`. |\n| `show_forecast` | bool, default `true` | Controls the separate `⚠~ETA` warning chip. It appears after the projection only when a window is projected to hit 100% before reset and the cap is imminent. Disable with `cs config set show_forecast false`. |\n| `show_agents` | bool, default `false` | One **bottom line per running subagent**, e.g. `◐ explore[haiku] 探索 RsaKeyPairPool 2m15s` (multiple agents → multiple lines). Inline agents finish via their tool_result; background (`run_in_background`) agents finish via the queue-operation that carries their tool-use-id. **Off by default because Claude Code already shows background agents in its own native panel** — enabling this largely duplicates that. |\n| `show_duration` | bool, default `false` | **Identity line:** session wall-clock duration as Claude Code reports it (`⏱ 12m`). Already on stdin — no transcript scan. Shows next to the project (needs `show_project_branch` on). Opt-in. |\n| `show_lines` | bool, default `true` | **Identity line:** session lines added/removed as Claude Code reports it (`+182 -47`, +green/−red). This is Claude Code's own cumulative session tally (every Write/Edit), **not a git diff** — it can exceed the net working-tree change. Needs `show_project_branch` on. On by default; disable with `cs config set show_lines false`. |\n| `show_version` | bool, default `true` | **Identity line:** a faint `· vX.Y.Z` at the very end (darkest grey + dim attribute, so it recedes). When a newer version is on PyPI, an amber `↑\u003cnewver\u003e` is appended (`· v3.11.2 ↑3.12.0`) — read from a local cache the background update check writes, so the render path never hits the network. Disable with `cs config set show_version false`. |\n| `show_mode` | bool, default `true` | A dedicated **`⚙` session-mode line**: `⚙ effort:high · think:on · fast:off · style:default`, straight from Claude Code's stdin (effort level / thinking / fast mode / output style). Each field is dropped when absent. Disable with `cs config set show_mode false`. |\n| `mode_gradient` | bool, default `true` | Tint the mode line with a **static gradient keyed to the effort tier** (cool→hot: low/auto slate, medium blue, high cyan, xhigh amber, max coral, ultracode pink→purple) — so the level reads at a glance. Static, not animated (an external statusLine refreshes at ≤1 Hz, so motion only flickers). `cs config set mode_gradient false` → plain per-tier text colours. |\n\nSet via `cs config set \u003ckey\u003e \u003cvalue\u003e`. Wipe everything back to defaults with `cs config reset`.\n\nOverride per-invocation via `--style` / `--theme` flags or `CLAUDE_STATUSBAR_STYLE` / `CLAUDE_STATUSBAR_THEME` env vars.\n\n## Fast mode (daemon) — default since v3.6.0\n\n`cs --setup` writes `cs render` + `refreshInterval: 1` by default. A long-lived `cs daemon` pre-renders into `~/.cache/claude-statusbar/rendered.ansi`; the statusLine command (`cs render`) is a thin reader that just `cat`s the file. Each tick is ~3-5ms, so total CPU stays under 1% continuously. The legacy inline path (~30ms/tick, ~3% CPU at 1Hz) is still available via `cs --setup --inline`.\n\n```bash\ncs --setup               # default: daemon mode, auto-starts the daemon\ncs --setup --inline      # opt out, use legacy inline path\ncs daemon status         # check the daemon is alive\ncs daemon stop           # stop the daemon (statusLine falls back to inline)\ncs daemon start          # start it again\n```\n\nCrash safety: if the daemon dies or freezes, `cs render` notices `rendered.meta.json` is older than 5s and falls back to inline render — and lazily re-spawns the daemon in the background. You never see a frozen status line.\n\n### Optional: auto-start on login (launchd / systemd)\n\nLazy-spawn (above) covers most cases — the daemon comes up on first `cs render`. If you want stronger guarantees (auto-start at login, OS restarts the daemon on crash, survives reboots without `cs render` needing to fire first):\n\n```bash\ncs daemon install        # installs ~/Library/LaunchAgents (macOS) or\n                          # ~/.config/systemd/user (Linux), starts the daemon\ncs daemon service        # report whether the OS-level service is registered\ncs daemon uninstall      # remove the LaunchAgent / systemd unit\n```\n\nOn macOS, the LaunchAgent has `KeepAlive=true` and `ThrottleInterval=10` — kill the daemon and launchd respawns it within 10 seconds. On Linux, the systemd user unit uses `Restart=always` (you may need `loginctl enable-linger $USER` for the daemon to survive logout).\n\n## `cs doctor` — self-diagnostic\n\nIf the status bar isn't behaving the way you expect, run:\n\n```bash\ncs doctor\n```\n\nIt prints (with red ✗ for anything off):\n\n- Which `cs` binary the OS will resolve, plus its version + Python interpreter\n- Whether `~/.claude/settings.json` has *our* statusLine entry (vs missing / vs another tool's)\n- How fresh `~/.cache/claude-statusbar/last_stdin.json` is (so you can tell if Claude Code is actually pushing data)\n- If the daemon is running (fast mode) — its pid and how stale `rendered.ansi` is\n- Terminal size and `TERM`\n- Current resolved `style` / `theme` / all `show_*` toggles\n- Slash commands installed under `~/.claude/commands/`\n\nPaste the output verbatim in any bug report — it's almost always enough to diagnose remotely.\n\n## Install as a Claude Code plugin\n\nThe repo ships a `.claude-plugin/plugin.json`, distributed via the **leeguooooo/plugins** marketplace. Inside Claude Code:\n\n```\n/plugin marketplace add leeguooooo/plugins\n/plugin install claude-statusbar@leeguooooo-plugins\n```\n\nYou still need the `cs` CLI (`pip install claude-statusbar` or `uv tool install claude-statusbar`) — the plugin only carries the slash commands; the heavy lifting is the Python package.\n\n## Usage\n\n```bash\ncs                              # render the status line (default command)\ncs --style capsule              # render with a one-off style\ncs --theme twilight             # render with a one-off theme\n\n# Configuration\ncs config show                  # show all persistent config\ncs config set style hairline    # persist style → ~/.claude/claude-statusbar.json\ncs config set theme linen       # persist theme\ncs config set show_cost true    # session $ cost segment\ncs config set show_cache_age false  # hide prompt-cache age segment\ncs config set show_tools true   # activity line: active tool + completed rollup\ncs config set show_agents true  # bottom line(s): running subagents + elapsed\ncs config set show_duration true # identity line: ⏱ session duration\ncs config set show_lines false  # hide identity-line +added -removed (on by default)\ncs config set show_version false  # hide the faint · vX.Y.Z (+ ↑update hint) at line end\ncs config set show_mode false    # hide the ⚙ effort/thinking/fast/style line\ncs config set mode_gradient false # mode line: plain per-tier colours, no gradient\ncs config set show_ahead_behind true  # ↑2↓1 on the project/branch line\ncs config set bar_shimmer true  # experimental: twinkling starfield on the battery bars\ncs config set show_projection false  # hide the →NN% end-of-window projection\ncs config set show_forecast false    # hide the ⚠~eta at-risk warning chip\ncs config set show_todos false  # hide the todo-progress segment (on by default)\ncs config reset                 # wipe config back to defaults\n\n# Discovery\ncs styles                       # list available styles\ncs themes                       # list available themes\ncs preview                      # render every style × theme with YOUR real data\ncs preview --theme nord         # filter to one theme\ncs preview --style hairline --theme dracula   # one specific combo\n\n# Daemon mode (default since v3.6.0; v3.2 introduced it as opt-in)\ncs --setup                      # default: writes `cs render` + starts daemon\ncs --setup --inline             # opt out, use legacy inline path\ncs daemon start                 # start daemon (manual)\ncs daemon stop                  # stop daemon\ncs daemon status                # pid + rendered.ansi freshness\ncs daemon install               # install LaunchAgent (macOS) / systemd unit (Linux)\ncs daemon uninstall             # remove the OS-level service\ncs daemon service               # report whether the OS service is registered\n\n# Diagnostics + flags\ncs doctor                       # self-diagnostic — paste output in bug reports\ncs --json-output                # machine-readable JSON\ncs --no-color                   # disable ANSI colors\ncs --warning-threshold 40 --critical-threshold 85\ncs --no-auto-update             # skip the per-day PyPI version check\n```\n\n`--plan` still exists for older scripts, but is deprecated and no longer changes the rendered output.\n\n### Environment variables\n\n| Variable | Effect |\n|----------|--------|\n| `CLAUDE_STATUSBAR_STYLE=capsule` | Render with this style (overrides config file) |\n| `CLAUDE_STATUSBAR_THEME=twilight` | Render with this theme (overrides config file) |\n| `CLAUDE_STATUSBAR_NO_UPDATE=1` | Disable automatic update checks |\n| `CLAUDE_STATUSBAR_WARNING_THRESHOLD=40` | Switch from green to yellow at 40% |\n| `CLAUDE_STATUSBAR_CRITICAL_THRESHOLD=85` | Switch from yellow to red at 85% |\n| `NO_COLOR=1` | Disable ANSI colors |\n\n`CLAUDE_PLAN` is still accepted for legacy compatibility, but it no longer changes the rendered status line.\n\n### JSON output\n\nUse `--json-output` if you want a machine-readable payload instead of the formatted status line:\n\n```bash\ncs --json-output\n```\n\n## Data source\n\nRate-limit percentages come directly from **Anthropic's official API headers**, surfaced into the JSON payload Claude Code injects on stdin to every `statusLine` command. Context-window usage comes from the same payload. The enabled-by-default `cache 4m23s` countdown is computed locally by tail-reading the active transcript JSONL, with the TTL (5min vs 1h) auto-detected from Anthropic's per-turn `cache_creation` buckets — see [How the cache countdown works](#how-the-cache-countdown-works).\n\nRequires Claude Code `v2.1.80+`.\n\n## How the cache countdown works\n\nThe `cache 4m23s` segment is computed locally on every render from the active session transcript. Two design choices keep it accurate:\n\n- **Anchored on the most recent `assistant` entry** — not the last user message, not file mtime. Anthropic's prompt cache is a sliding window (refreshed on every hit), so \"time left\" is measured from the last turn, and each new turn refills the countdown.\n- **TTL is auto-detected** (since v3.9.0), not hard-coded. Anthropic reports, per turn, which TTL it applied in `message.usage.cache_creation`: a non-zero `ephemeral_1h_input_tokens` means a 1-hour cache, `ephemeral_5m_input_tokens` means 5 minutes. That bucket already reflects subscription-vs-API-key auth, `ENABLE_PROMPT_CACHING_1H`, and the over-quota → 5m downgrade, so no static value can match it.\n\n```mermaid\nflowchart TD\n    A[\"transcript.jsonl\"] --\u003e|\"tail-read, \u0026le; 320KB\"| B[\"most recent assistant entry\"]\n    B --\u003e C[\"timestamp\u003cbr/\u003eage = now − ts\"]\n    B --\u003e D[\"usage.cache_creation\u003cbr/\u003e1h bucket → TTL 3600\u003cbr/\u003e5m bucket → 300\u003cbr/\u003eelse → 300 (fallback)\"]\n    C --\u003e R[\"remaining = TTL − age\"]\n    D --\u003e R\n    R --\u003e|\"\u0026gt; 0\"| OK[\"cache 51m07s\u003cbr/\u003egreen; \u0026lt; 1min → yellow\"]\n    R --\u003e|\"\u0026le; 0\"| CO[\"cache COLD\u003cbr/\u003ered\"]\n    style OK fill:#eaf6ec,stroke:#2f9e44,color:#1b5e2a\n    style CO fill:#fbeceb,stroke:#e0443d,color:#8f2723\n```\n\nIt's a couple dozen lines and not Claude-Code-specific — `message.usage.cache_creation` is a standard Claude API field, so you can reuse the logic in your own status bar, plugin, or script:\n\n```text\n# prompt-cache countdown. input: path to the current session transcript (JSONL).\n# three things to get right:\n#   1. anchor the most recent assistant entry (not the user message, not file mtime)\n#   2. read the TTL from the cache_creation buckets — don't hard-code it\n#   3. read the file tail only, don't slurp the whole thing\n\nfunction cacheCountdown(transcriptPath):\n    age = null            # seconds, from the newest assistant entry's timestamp\n    ttl = null            # seconds, from the newest entry that WROTE cache\n\n    # reverse-read the tail, at most 320KB (32KB chunks); grab age + ttl in one pass\n    for entry in reversedJsonlEntries(transcriptPath, maxBytes = 320 * 1024):\n        if entry.type != \"assistant\": continue\n        if age is null and entry.timestamp:\n            age = now() - parseTimeUTC(entry.timestamp)   # treat naive timestamps as UTC\n        if ttl is null:\n            cc = entry.message.usage.cache_creation\n            if   cc.ephemeral_1h_input_tokens \u003e 0: ttl = 3600\n            elif cc.ephemeral_5m_input_tokens \u003e 0: ttl = 300\n        if age is not null and ttl is not null: break\n\n    if age is null:  return \"COLD\"     # no assistant entry\n    if ttl is null:  ttl = 300         # no cache-write signal -\u003e conservative fallback\n    if age \u003c 0:      age = 0           # clock skew / future timestamp -\u003e clamp to 0\n\n    remaining = ttl - age\n    if remaining \u003c= 0: return \"COLD\"\n    return formatCountdown(ceil(remaining))\n\n# always show seconds so the number visibly ticks (proof it's live, not stuck)\nfunction formatCountdown(s):\n    if s \u003e= 3600: return \"{h}h{mm}m{ss}s\"   # 1h59m03s\n    if s \u003e= 60:   return \"{m}m{ss}s\"         # 58m23s / 4m07s\n    return \"{s}s\"                            # 47s (\u003c 1min)\n```\n\n**Deep dive** — how accurate it really is, plus the Feb→May 2026 cache-TTL saga (1h → 5m → 1h) with sources: [状态栏那行 cache 4m23s，到底准不准？ (Chinese)](https://blog.misonote.com/zh/posts/claude-statusbar-cache-countdown/)\n\n## Troubleshooting\n\n**Status line doesn't appear after install** — Restart Claude Code (settings.json is read at session start). If still missing, run `cs doctor` and check the `statusLine entry` row.\n\n**`cs doctor` says \"missing\"** — A Claude Code upgrade can wipe `statusLine` from `~/.claude/settings.json`. Run `cs --setup` (or `cs --setup --fast` if you want daemon mode) to restore it. The package also self-heals once per day automatically.\n\n**Numbers stuck / not updating** — Two possibilities:\n1. `refreshInterval` not set — Claude Code only re-renders on activity. Add `\"refreshInterval\": 30` (or `1` for live cache-age).\n2. Daemon mode running stale data — `cs daemon stop \u0026\u0026 cs daemon start`. Or just `cs doctor` and check `daemon` row freshness.\n\n**Cache-age segment shows `cache 0s` and never moves** — `refreshInterval` is unset; Claude Code only re-invokes the statusLine on each user/assistant turn. Set `\"refreshInterval\": 1` in settings.json. For 1Hz refresh you'll also want `cs --setup --fast` so the per-second invocation stays cheap.\n\n**`cs --setup --fast` then daemon shows wrong rate-limits** — Fixed in v3.2.1. Upgrade with `pip install -U claude-statusbar`.\n\n**Auto-update is annoying / blocked** — `export CLAUDE_STATUSBAR_NO_UPDATE=1` in your shell rc.\n\nFor anything else: open a [GitHub issue](https://github.com/leeguooooo/claude-code-usage-bar/issues) with the output of `cs doctor` attached — it captures version, paths, settings.json state, daemon state, and recent cache freshness in one paste.\n\n## Upgrading\n\nAuto-updates once per day from PyPI. To upgrade manually:\n\n```bash\npip install -U claude-statusbar\n# or\nuv tool upgrade claude-statusbar\n```\n\nTo disable auto-updates: `export CLAUDE_STATUSBAR_NO_UPDATE=1`\n\n## Comparison with alternatives\n\nThere are a few good Claude Code usage monitors. They solve overlapping but distinct problems — pick the one that matches *where* you want the information.\n\n| Tool | Lives in | Optimized for |\n|---|---|---|\n| **claude-statusbar (`cs`)** | Claude Code's `statusLine` (one line at the bottom) | Glanceable while you work; zero context-switching |\n| [ccusage](https://github.com/ryoppippi/ccusage) | Standalone TUI in a separate terminal window | Long-form usage analytics, cost breakdowns over weeks |\n| [Claude Code Usage Monitor](https://github.com/Maciek-roboblog/Claude-Code-Usage-Monitor) | Standalone TUI with predictive burn-rate | Real-time burn-rate forecast for paid plans |\n\n`cs` is intentionally one line of color and one decision per second. If you want a dashboard with charts, daily/weekly aggregates, and burn-rate prediction, run a TUI in a side pane. The two coexist nicely.\n\n## Integrations\n\n### prompt-language-coach\n\nInstall the [prompt-language-coach](https://github.com/leeguooooo/prompt-language-coach) Claude Code plugin to get IELTS band progress tracking. After setup, the status bar automatically shows your current writing level and trend:\n\n```\n... | Opus 4.8(350k/1M) | 📚 EN:6.0↑ JA:5.0→\n```\n\n- `↑` improved from last session · `↓` dropped · `→` no change\n- No configuration needed — the segment appears automatically when `~/.claude/language-progress.json` exists.\n\n## Contributing\n\nPRs welcome. The full contributor guide — local setup, test commands, architecture map, coding conventions, release flow — lives in [CONTRIBUTING.md](CONTRIBUTING.md). Security issues: see [SECURITY.md](SECURITY.md).\n\nQuick start:\n\n```bash\ngit clone https://github.com/leeguooooo/claude-code-usage-bar\ncd claude-code-usage-bar\nuv sync\nPYTHONPATH=src uv run pytest tests/   # 320+ tests, ~1.5s\n```\n\nRender path is hot (60×/min at `refreshInterval: 1`) — `tests/test_import_perf.py` pins which modules can't be imported on the fast path. Read CONTRIBUTING.md before adding dependencies.\n\n## Acknowledgments\n\n- [@marcwimmer](https://github.com/marcwimmer) — original `show_cache_age` widget ([#9](https://github.com/leeguooooo/claude-code-usage-bar/pull/9))\n- [claude-monitor](https://github.com/Maciek-roboblog/Claude-Code-Usage-Monitor) — token-usage analysis library used as the optional fast-path data source\n\n## Contributors\n\n\u003ca href=\"https://github.com/leeguooooo/claude-code-usage-bar/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=leeguooooo/claude-code-usage-bar\" alt=\"Contributors\" /\u003e\n\u003c/a\u003e\n\nMade with [contrib.rocks](https://contrib.rocks).\n\n---\n\n## License\n\nMIT\n\n## Star History\n\n\u003ca href=\"https://star-history.com/#leeguooooo/claude-code-usage-bar\u0026Date\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"docs/images/star-history-dark.svg\"\u003e\n    \u003cimg alt=\"Star history\" src=\"docs/images/star-history.svg\"\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n\u003csub\u003eStatic snapshot taken at v3.3.x; \u003ca href=\"https://star-history.com/#leeguooooo/claude-code-usage-bar\u0026Date\"\u003eclick for live chart\u003c/a\u003e.\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleeguooooo%2Fclaude-code-usage-bar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleeguooooo%2Fclaude-code-usage-bar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleeguooooo%2Fclaude-code-usage-bar/lists"}