One payload in
Claude Code pipes a JSON blob to the statusline command on every render. cockpit reads that, the repo's cost ledger, and git. Nothing else.
CLAUDE CODE · STATUSLINE OPEN SOURCE
Four lines under your prompt. How much context you can actually still use, what this session is costing per hour, whether your pace will hit the 5-hour cap before it resets, and how many other sessions are quietly eating the same limit.
Session warming up.
Backs up settings.json before it touches it.
Not ready? --dry-run shows every change and writes nothing.
WHY FOUR LINES
A single line has room for the numbers. It has no room for what they mean next. These three are the reason cockpit is four.
Auto-compact fires while there is still headroom on the clock, so a raw 82% remaining is a lie about how much room you really have. cockpit subtracts the buffer and shows usable context, so 100% means compaction, not empty.
62% used means nothing without knowing how fast you got there. cockpit extrapolates your burn against the window and prints where you will land. If that lands past 100%, it prints the clock until you're capped and tells the effort badge to say ↓ease.
Rate limits are billed to the account, not the window. Four terminals open means four sessions draining one budget, and each of them thinks it is alone. Every cockpit heartbeats to a shared temp file, so each panel can show the whole fleet and its combined burn.
WHAT IT SHOWS
Point at any part of the panel. Tap on touch, or use ← → once focused.
Hover a segment to read it.
RECORDING
The hero runs invented session data through the real projection maths, because a page cannot have a live Claude Code session. This is sixteen seconds of actual stdout, captured from the tool and not recreated. It shows three lines rather than four: the sample payload has no todo list and the repo has no cost ledger, so the panel correctly hides both segments.
THE HONEST LEDGER
Every statusline is a trade: screen space and a subprocess or two, in exchange for not having to guess. Here is both sides, so you can decide before you install rather than after.
Known gaps, in rough order of how much they would help. None of them are claimed. Every one is a reasonable first contribution.
UNDER THE HOOD
Claude Code pipes a JSON blob to the statusline command on every render. cockpit reads that, the repo's cost ledger, and git. Nothing else.
Zero dependencies, zero fetches, zero telemetry. Rate limits arrive inside the payload. Nothing about your session leaves the machine.
Every reader is wrapped. A missing ledger, a corrupt config, a repo with no upstream: the segment drops out and the rest of the panel renders.
Live numbers sit in fixed-width fields. Your spend rolling from $9.99 to $10.00 won't shove the line sideways mid-thought.
CONFIG
Drop a cockpit.config.json next to your settings. Everything is optional; a missing file gives you the full panel.
{
"segments": { "ledger": false, "todos": false },
"context": { "autoCompactBuffer": 16.5, "width": 10 },
"limits": { "width": 8, "projection": true },
"colors": { "ledger": "gold" }
}
OPEN SOURCE
MIT, developed in the open, and small enough to read in one sitting. Come argue about the defaults, ship a segment, or show what you built on top of it.
Comments here are GitHub Discussions, rendered in place. Post with your GitHub account and the thread lives in the repo, not in a database only I can read.
Forks, themes, ports, and tools that read the same numbers. If you built something on top of cockpit, it belongs here.
The whole statusline is one file with no dependencies. Adding a segment is a function and a config key, and the tests run with node scripts/test.js.
No Claude Code session needed. Pipe JSON straight in and see what renders.
echo '{"model":{"display_name":"Test"}}' | node src/statusline.js
Write a reader that returns null when it has nothing to say, wrap it in safe(), push it onto the right line, and add a key to DEFAULTS.segments.
The one hard rule: render() must never throw. A throw blanks the statusline on every single render. Add a case to the test file with the worst payload you can imagine.
node scripts/test.js
FAQ
Because it measures something different. Claude Code reports raw remaining context. Auto-compact fires while a buffer is still on the clock, so raw remaining overstates your actual headroom. cockpit subtracts that buffer, which means its 100% is the moment compaction fires, not the moment the window is literally full. Set context.autoCompactBuffer to 0 if you want the raw number back.
Your current pace, extended to the end of the 5-hour window, lands past 100%. That is the estimated time until you hit the cap. It replaces the →N% projection whenever the projection would exceed 100. Stop working and it stops being true, which is rather the point of showing it.
No. Zero dependencies, no network calls of any kind. Rate limits arrive inside the JSON payload Claude Code already pipes to the statusline command. The only things it reads from disk are your todo files, an optional per-repo cost CSV, and the pool heartbeats it writes itself.
It is, and that is the honest cost. Turn segments off until it is the size you want; with ledger, todos and pool off it collapses to two. The default is deliberately maximal because a segment you never configured is a segment you never had to think about.
Because the three things worth the most do not fit on one. A pace projection needs the percentage, the reset clock and the extrapolation sitting next to each other. The repo ledger needs three numbers to mean anything. The pool needs a count and a combined rate. If you want one line, turn segments off until you have one: that is a supported configuration, not a compromise.
Yes. MIT. Do what you like, no attribution dance required. If you build something on top of it, open a showcase issue and it goes on this page.