One bash script. Your session cost in dollars, live, so you stop burning Opus on work that doesn't need it.
I kept leaving sessions on Opus long after the hard thinking was done. Claude Code does warn you, but the context and rate-limit notices flash past and you dismiss them without reading. Discipline loses to a number you can't see.
TL;DR
- Grab
statusline-hud.shfrom github.com/newell-paul/statusline-hud, drop it in~/.claude/,chmod +xit. - Add a
statusLineblock to~/.claude/settings.json(snippet below).
Wire it up
Prerequisites
-
jqon yourPATH. The script hard-exits withβ jq missingwithout it. - A terminal with 256-colour and UTF-8 support, and a font that renders
π₯ β‘ βΊ β© β β β βββββββ. Any modern terminal with a Nerd Font, or the macOS/iTerm2/GNOME defaults, will do. - macOS or Linux. Native Windows isn't supported; the script is bash and uses POSIX tools (WSL should work, untested).
Install
- Copy
statusline-hud.shto~/.claude/and make it executable. - Add this to
~/.claude/settings.json:
{
"statusLine": {
"type": "command",
"command": "~/.claude/statusline-hud.sh"
}
}
refreshInterval is optional. Leave it out and the bar redraws on Claude Code events: each new assistant message, after /compact, and on permission-mode or vim-mode changes. Add "refreshInterval": 5 if you want it to also tick on a timer, for example to keep the countdown accurate while background subagents are running.
The repo has 80 bats tests and a hardened git_safe() wrapper that disables core.fsmonitor and core.hooksPath, so a hostile .git/config can't execute code via the bar.
Settings reload; the bar appears on your next interaction.
The JSON hiding in the statusline
Claude Code's statusline is just a shell command: JSON in on stdin, one line of text out. Cost, effort, fast mode, cache stats, both rate-limit windows are all already in there, emitted on every render (debounced 300ms). Nothing's missing. There's just nothing showing it. (Tap the pipe with tee to see the full payload; PAYG (pay-as-you-go) and API users will find rate_limits absent.)
What the bar shows
With everything switched on:
- Directory + git status (
βNβN,βif dirty) - Model name with effort badge (
β‘Lo/β‘Med/β‘Hi/β‘xHi/β‘Max) and fast-mode rocket π when/fastis active - Context-window bar: 5 cells using eighths (
ββββββββ) so the bar moves smoothly within a tier, with the tier colour stepping green β yellow β orange β red (see the README for the exact ctx and rate-limit breakpoints; they differ) - 5-hour and 7-day rate-limit bars (both shown by default; comment either out in
SEGMENTS). A reset countdown (βΊ2h14m) attaches to whichever limit is more constrained, and only once it crosses 60% - Cache hit ratio (
β©97%), only after >5k input tokens -
π₯cumulative session spend in USD (or input tokens; see toggle below)
Everything is configurable from the CONFIG block at the top of the script.
The SEGMENTS array is your control panel. Comment out a line to hide that segment, reorder lines to rearrange the bar. Want git status on the right and the flame on the left? Move the lines.
Other knobs you'll probably touch:
-
TURN_UNIT:usd(default) shows the flame in dollars; flip totokensfor input-token count instead. Intokensmode the value is the live context window (see the flame section below), so its thresholds are fractions of a 200k context, not session totals. -
TIER_COLOR,BAR_CTX,BAR_LINEAR: bar palette and the tier thresholds at which each bar flips colour. -
TURN_HI_USD/TURN_MED_USD: USD thresholds for the flame's amber/red (TURN_HI_TOK/TURN_MED_TOKfor tokens mode).
One jq call and a few git invocations per render. Cheap enough to ignore.
The flame: a session-scale spend gauge
π₯ $5.64 is the cumulative session spend, read straight from cost.total_cost_usd. Green under $5, amber $5β$20, red β₯ $20, tuned for Max users where a long Opus session runs that high in estimated spend. Red doesn't mean stop. It means the next routine task is the one to drop to Sonnet for, or /clear and start fresh.
PAYG users paying list price should dial down: try TURN_MED_USD=0.50 / TURN_HI_USD=2.00.
The discomfort isn't financial, it's visible. Same psychology as a power meter: you don't read the number, you notice when it pegs into the red.
Green means I haven't checked the bar in a while and don't need to. Amber means the session has grown legs, fine if I meant it, worth noticing if I didn't. Red means I'm running Opus on a long, heavy context, and it's time to make a choice.
Acting on the red
Opus for architecture, complex debugging, ugly refactors. Sonnet for most everyday work. Haiku for routine commands.
On Pro and Max, cost.total_cost_usd is an estimate, not your bill: API list rates applied client-side, which can differ from what you're actually billed. It's still the best signal for what the flame answers, which is how much have I put through the model so far.
If you'd rather see input tokens, flip TURN_UNIT=tokens in the CONFIG block, but be aware that as of v2.1.132 total_input_tokens reflects current context window, not cumulative session totals, and can drop after a /compact. The default token thresholds (TURN_MED_TOK / TURN_HI_TOK) are tuned to that: fractions of a 200k context, so red means "context is filling up," not "expensive session."
For historical totals, /usage gives you the deeper view. The bar nudges you in the moment; /usage is the rear-view mirror.
Once the bar is in front of you, two habits move the needle:
- Pin routine slash commands to
model: haiku. Commit, lint, review-diff: none of these need Opus. - Use subagents for delegation. They get a fresh, isolated context window, not your full history.
When a session has done its job, /clear before the next task so you're not dragging a stale context forward; if you want to keep the thread, /compact reclaims the space instead. Then swap to the model the next task actually needs.
The data was always there. Now you can see it.
The repo is at github.com/newell-paul/statusline-hud. Issues and PRs welcome.


Top comments (0)