If you use Claude Code for hours a day, two things tend to ambush you: a context window that is nearly full, and a rate limit you didn't know you were close to. Both numbers exist. Claude Code just doesn't put them in front of you by default.

So I built a statusline that does. It's open source, installs with one command, and works on macOS, Linux and Windows.

claudecode-statusline preview

What it shows

Segment What it tells you
[🪨 CAVEMAN] Active Caveman mode (hidden when off)
📁 project 🌿 branch Project folder and current git branch
🤖 Claude Sonnet 4.6 The model answering right now
CTX ███░░░░░ 42% Context window usage
⚡ ▄ MEDIUM Effort level, only when the model reports one
5h ███░░░░░ 42% used 58% rem ↺ 1h 22m 5-hour limit: spent, remaining, time to reset
7d ██████░░ 85% used 15% rem ↺ 3d 7h Weekly limit, same format
🪨 ~42% tokens saved Optional Caveman token savings estimate

The bars are colour-coded. Usage goes green, then yellow, then red as it climbs. The "used" and "remaining" numbers are coloured independently, because 15% remaining is a warning even if it's just the flip side of 85% used.

Install

macOS / Linux:

git clone https://github.com/FahimFBA/claudecode-statusline.git cd claudecode-statusline chmod +x install.sh ./install.sh 

Windows (PowerShell):

git clone https://github.com/FahimFBA/claudecode-statusline.git cd claudecode-statusline powershell -ExecutionPolicy Bypass -File install.ps1 

Then restart Claude Code.

The installer asks whether you want a full install or a custom one. Custom shows a numbered menu so you can take only the segments you want. It merges into your existing ~/.claude/settings.json and backs that file up first, so it won't clobber your settings.

How it works

Claude Code has a statusLine setting. You point it at a command, and Claude Code runs that command and passes a JSON blob about the current session on stdin. Whatever the command prints to stdout becomes your statusline.

The setting looks like this:

"statusLine": { "type": "command", "command": "bash \"~/.claude/hooks/caveman-statusline.sh\"" } 

The renderer only reads a handful of fields from that JSON:

  • workspace.project_dir (falling back to workspace.current_dir) for the folder name
  • model.display_name
  • context_window.used_percentage
  • effort.level
  • rate_limits.five_hour and rate_limits.seven_day, each with used_percentage and resets_at

If a field is missing, that segment is silently skipped. That's why the effort level only appears on models that report one.

Drawing a bar

The bar is eight cells wide:

function fillBar(pct, width) { const filled = Math.max(0, Math.min(width, Math.floor((pct * width) / 100))); return '█'.repeat(filled) + '░'.repeat(width - filled); } 

Severity colours use ANSI 256-colour codes, and "used" and "remaining" have separate thresholds:

const usedColor = (p) => (p >= 80 ? 196 : p >= 50 ? 220 : 114); // red / yellow / green const remColor = (p) => (p <= 20 ? 196 : p <= 50 ? 220 : 114); 

Time until reset

The rate limit data includes a reset timestamp. The renderer turns it into a short countdown and tolerates both seconds and milliseconds, since it's easy to get that wrong:

function fmtReset(epoch) { let n = Number(epoch); if (!(n > 0)) return ''; if (n > 1e12) n = Math.floor(n / 1000); // tolerate ms const rem = Math.max(0, n - Math.floor(Date.now() / 1000)); const d = Math.floor(rem / 86400); const h = Math.floor((rem % 86400) / 3600); const m = Math.floor((rem % 3600) / 60); if (d > 0) return `${d}d ${h}h`; if (h > 0) return `${h}h ${m}m`; return `${m}m`; } 

The Windows lesson

My first version was a bash script that used jq to parse the JSON. That's fine on macOS and Linux. On Windows, neither bash nor jq is there by default, so the statusline came up missing its icons, model, context bar and rate limits.

The fix (v1.0.1) was a second renderer written in Node, with no dependencies. Claude Code users already have Node, and child_process handles the git branch lookup. The Windows installer now uses the Node renderer and no longer needs bash at all. macOS and Linux keep the bash renderer.

If you're writing a tool for Claude Code that has to run on Windows, don't assume bash or jq exist.

Customising it

Every segment can be switched off with an environment variable set to 0:

Variable Hides
SL_CAVEMAN=0 Caveman badge
SL_PROJECT=0 Project and branch
SL_MODEL=0 Model name
SL_CTX=0 Context window bar
SL_EFFORT=0 Effort level
SL_5H=0 5-hour limit
SL_7D=0 Weekly limit
SL_SAVINGS=0 Token savings

The installer writes these for you when you pick the custom option. You can also edit them into the statusLine command by hand, or re-run the installer and choose different components.

About the Caveman part

The badge and the token savings estimate come from Caveman by JuliusBrussee. It's a plugin that makes Claude answer in terse, stripped-down language to cut output tokens while keeping the technical content. The statusline shows which Caveman level is active (lite, full or ultra), and /caveman-stats reports real token usage from the session log.

Caveman is optional. Turn off its segments and you still get everything else.

Uninstall

Delete the hook scripts and remove the hooks, statusLine, enabledPlugins and extraKnownMarketplaces keys from ~/.claude/settings.json. The README has the exact commands for macOS / Linux and PowerShell.

Try it

Repo: https://github.com/FahimFBA/claudecode-statusline

If you try it and a segment is wrong on your setup, open an issue with your OS and what the statusline showed. I'd also like to hear which segments you'd add.