@henryavila/claudebar
v1.3.5
Published
Zone-driven statusline for Claude Code with TOML config
Maintainers
Readme
claudebar
A two-row, zone-driven statusline for Claude Code. Designed for the subscriber tier: rate-limit awareness matters more than dollar cost.
What it does
Reads the JSON session context Claude Code feeds it via stdin after every message, and prints two ANSI-colored rows:
✦ Opus 4.7 · HIGH · tmux:session:1.2 owner/repo › ⎇ branch 3 #1234 ⏳
ctx ▰▰▱▱▱▱▱▱▱▱ 23% 5h ▰▰▰▱▱▱▱▱▱▱ 34% 7d ▰▰▰▰▰▰▱▱▱▱ 62%Identity row (top) — what session is this? Fuel-gauge row (bottom) — how much runway do I have?
Features
- Pip-style fuel gauges with zone-driven colors: green
<60%, yellow60-89%, red≥90%— applied independently to context window, 5-hour rate limit, and 7-day rate limit. The bar shape tells you "how full"; the color tells you "how worried". - Quota reset countdown + time-elapsed marker on the
5hand7dchips:5h · 2h18m ▰▰▰▰│▰▰▱▱▱▱ 60%. The text tells you when the window resets; the│inside the bar shows how far into the window you already are. When the marker is inside the fill, you're burning faster than time allows; past the fill, you have margin. - Identity row shows model, reasoning effort, tmux pane context, repo, worktree, branch, dirty file count, and PR review state.
- Agent-active mode: when a subagent is dispatched, the model name dims and a pulsing chip shows the agent name — at-a-glance "my turn is paused".
- Tmux integration: when running inside tmux, the identity row gains a
tmux:session:window.panechip to disambiguate multiple Claude sessions across panes. - TOML configuration: every color, threshold, glyph, and chip toggle is configurable via
~/.config/claudebar/config.toml. Changes recompile automatically on the next render. - Graceful degradation: rate-limit bars hide when not on a subscriber tier; PR chip hides without a PR; effort chip hides on models without effort support; worktree marker hides outside worktrees. No placeholder text, no orphan separators.
- Cross-platform: macOS, Ubuntu/Debian, Arch, Fedora, WSL2 — same bash script, no edits.
Each state at a glance
| State | Render |
|---|---|
| Calm — start of session, low context, clean tree | |
| Mid-session — worktree, dirty tree, PR pending | |
| Caution — yellow zone (60-89%) | |
| Danger — red zone (≥90%) + PR changes requested | |
| Subagent dispatched — model dims, agent chip pulses | |
| PR approved — clean tree, green PR chip | |
| Main working tree — no worktree, no PR, minimal chrome | |
| Tmux integration — tmux:session:window.pane chip | |
Install
npx @henryavila/claudebar installThis:
- Copies the statusline script to
~/.config/claudebar/. - Generates a fully documented
config.tomlwith all defaults (commented out). - Backs up
~/.claude/settings.jsonwith a timestamp. - Patches
settings.jsonto point at the installed script. - Registers the self-heal hooks and a native OS self-heal daemon (see How it works). Add
--no-daemonto skip the daemon. - Runs diagnostic checks to confirm everything works.
Send any message in Claude Code (or restart it) — the new statusline renders.
Prerequisites
jqandgit(the script uses them at runtime)- A 256-color terminal (anything modern)
- A Nerd Font installed and active in your terminal
Don't have a Nerd Font? Install one:
npx @henryavila/claudebar install-fontDefaults to JetBrainsMono. Pass --font FiraCode (or any name from nerd-fonts releases) for a different family.
Diagnostics
npx @henryavila/claudebar doctorChecks bash, jq, git, 256-color, installed files, settings.json, the self-heal/auto-update hooks, the OS self-heal daemon, and version — reports pass/fail for each.
Configuration
npx @henryavila/claudebar configOpens ~/.config/claudebar/config.toml in $EDITOR. On save, validates the TOML and recompiles automatically. Changes take effect on the next statusline render (next message or 30-second tick).
The config file is self-documenting — every option is listed with its default, commented out. Uncomment only what you want to change.
What you can configure
| Section | Controls |
|---|---|
| [colors] | Every color in the statusline (xterm-256 codes, 0-255) |
| [thresholds] | Zone boundaries: warning (green→yellow) and critical (yellow→red) |
| [chips] | Toggle any segment on/off: model, effort, tmux, repo, branch, worktree, dirty, PR, agent, each fuel gauge, countdown text, time marker |
| [layout] | Force compact or full layout, set refresh interval |
| [glyphs] | Override Nerd Font icons with any character |
Example
[colors]
model = 99 # change model color to purple
[thresholds]
warning = 50 # go yellow earlier
critical = 80 # go red earlier
[chips]
tmux = false # hide tmux chip
countdown = false # hide countdown text on fuel gaugesUpdate
npx @henryavila/claudebar updateReplaces the statusline script and toml-parser with the latest version. Your config.toml is backed up and preserved — new config options are added automatically via migration.
Uninstall
npx @henryavila/claudebar uninstallBacks up settings.json, removes the statusLine block and hooks, deregisters the OS self-heal daemon (launchd/systemd/cron/profile), and deletes ~/.config/claudebar/.
How it works
Claude Code pipes a JSON object to the script's stdin after every assistant message (debounced 300ms) plus on a 30-second tick. The script:
- Parses every needed field in a single
jq -rinvocation using@shfor shell-safe quoting. - Derives the current git branch and dirty-file count, with a 5-second session-scoped cache to avoid re-shelling
giton every message. - If
config.tomlexists, auto-recompilesconfig.shwhen the TOML is newer (adds <1ms overhead per render). - Composes two rows:
identity_row(top) andfuel_row(bottom), with each chip checking itsCHIP_*toggle and owning its preceding separator so absences don't leave orphan glyphs. - Prints ANSI-colored text to stdout. Claude Code displays it below the prompt.
Self-healing
Claude Code can re-persist ~/.claude/settings.json from its in-memory snapshot (e.g. on a TUI toggle), dropping the statusLine block — and sometimes the heal hook entry itself. claudebar recovers on two layers:
- Hooks (fast path) — a silent
SessionStart+UserPromptSubmithook restoresstatusLineand re-registers itself, bringing the bar back within one prompt. - OS daemon (backstop) — because a rewrite can drop the hook entry too (after which nothing hook-driven ever runs again), a native supervisor re-injects everything from outside Claude Code:
launchd(macOS),systemd --user(Linux/WSL), or acron/~/.profilepoll fallback. It watchessettings.jsonand restores full parity (statusLine + both heal hooks + the auto-update hook).
Manage the daemon directly with claudebar daemon [install|uninstall|status|restart]. Opt out with claudebar install --no-daemon or [daemon] enabled = false in config.toml.
See DESIGN.md for the full spec and CHANGELOG.md for version history.
Mobile / compact layout
On narrow terminals or mobile connections, claudebar switches to a 3-row compact layout with 5-pip bars:
✦ Opus 4.7 · HIGH #4 ⏳
claudebar › main ✓
ctx ▰▱▱▱▱ 12% 5h ▰▱▱▱▱ 18% 7d ▰▰▱▱▱ 45%Automatic detection
When connecting via mosh (e.g., Moshi on iOS), compact layout activates automatically — the script detects mosh-server in the process tree.
Moshi iOS setup: Go to Settings > Integrations > Export ENV and enable MOSHI_CLIENT. This ensures detection even if the process-tree walk is blocked.
Other mobile SSH apps
If you use a different mobile terminal app (Termius, Blink, Prompt, etc.) that connects via plain SSH (no mosh), automatic detection is not possible — the SSH protocol does not expose client identity to the server.
Set the override in your remote shell profile (~/.bashrc, ~/.zshrc, etc.):
export CLAUDEBAR_LAYOUT=compactOr configure it in config.toml:
[layout]
force = "compact"Detection priority
| Priority | Signal | How to use |
|----------|--------|------------|
| 1 | CLAUDEBAR_LAYOUT=compact | export in shell profile or app SSH config |
| 2 | config.toml [layout] force | npx @henryavila/claudebar config |
| 3 | MOSHI_CLIENT=1 | Enable in Moshi iOS settings |
| 4 | mosh-server ancestor process | Automatic (mosh connections) |
| 5 | $COLUMNS < 60 | Automatic (very narrow terminals) |
To force full layout on a mosh session: export CLAUDEBAR_LAYOUT=full.
Testing
npm test # Node.js CLI tests + bash tests
npm run test:cli # Node.js CLI tests only
npm run test:bash # bash tests only
bash test/perf.sh # asserts <50ms warm-cache execution
bash test/portability.sh # checks no GNU-only flags, bash 3.2 compatContributing
PRs welcome. Keep:
statusline.shperformant (<50 ms warm) — singlejqcall, cache shell-outs.- New visual elements documented in
DESIGN.mdwith a screenshot indocs/screenshots/. - TDD discipline — every new function gets a unit test in
test/unit/. - Cross-platform —
./test/portability.shmust still pass. - Zero npm dependencies — CLI uses Node.js stdlib only.
License
MIT — see LICENSE.
Acknowledgements
- Visual inspiration: the 2-row layout of powerlevel10k. claudebar does not depend on p10k — it works in any shell.
- Pip-bar aesthetic inspired by Apple Watch / Linear progress indicators.
- Color palette: Catppuccin Mocha base background.
- Related community projects: ccstatusline, starship-claude.
