Three-line ccstatusline layouts for Claude Code.
Lines 1 and 2 are the same in both variants:
- Line 1 — working dir,
owner/repo, git branch, diff stat, CI status, PR status - Line 2 — model, thinking effort, context bar, input / cached / output tokens
Line 3 is what differs, and picking the right one depends on the account:
| File | Line 3 | Use when |
|---|---|---|
ccstatusline-settings-usage.json |
account email, 5h block reset timer, session usage, weekly usage, weekly reset timer, compaction counter | the default — every segment populates on an ordinary account |
ccstatusline-settings.json |
worktree, worktree branch, original branch, 5h block reset timer, extra usage used / left | you have a spending cap configured and let Claude Code manage your worktrees |
The extra-usage-* widgets read n/a without a spending cap on the account, and the
worktree-branch / worktree-original-branch widgets need Claude Code to be managing the
worktree — so on a plain account the second variant leaves most of line 3 empty. See
Widgets that may render nothing below.
Both variants keep six columns per line, and that constraint drives the whole layout.
With autoAlign on, every column is padded to the widest entry in that column across all
three lines, so one long segment inflates the column and opens a gap on the two lines that
have something short in the same position. Two rules follow:
- Equal widget counts per line. A seventh widget on one line leaves the others with an empty cell in that column, and the padding shows up as a void rather than a gap.
- Put the widest segment in column 1. Column 1 already holds the working directory and
the model name, so it absorbs a long value; the same widget parked in a trailing column
sits opposite short ones like
(no PR)and tears a hole in the row. The account email is the widest thing here, which is why it leads line 3 instead of closing it.
Powerline enabled with the nord-aurora theme, rounded caps, truecolor, and column
auto-alignment so segments line up vertically across the three lines.
- A Nerd Font in your terminal. Without one the powerline separators render as tofu.
- Truecolor terminal support (the config uses
colorLevel: 3; drop to2for 256 colors).
Back up whatever you have first:
cp ~/.config/ccstatusline/settings.json ~/.config/ccstatusline/settings.json.bak-$(date +%Y%m%d-%H%M%S)Then drop the new config in — pick the variant from the table above:
# usage variant (recommended)
mkdir -p ~/.config/ccstatusline && curl -fsSL https://gist.githubusercontent.com/fabn/47b4bca04e9258c3f78040201d2ffc38/raw/ccstatusline-settings-usage.json -o ~/.config/ccstatusline/settings.json
# worktree variant
mkdir -p ~/.config/ccstatusline && curl -fsSL https://gist.githubusercontent.com/fabn/47b4bca04e9258c3f78040201d2ffc38/raw/ccstatusline-settings.json -o ~/.config/ccstatusline/settings.jsonWire it into Claude Code in ~/.claude/settings.json if it isn't already:
{
"statusLine": {
"type": "command",
"command": "npx -y ccstatusline@latest",
"padding": 0,
"refreshInterval": 10
}
}The status line picks the new config up on the next refresh — no restart needed.
cp ~/.config/ccstatusline/settings.json.bak-<timestamp> ~/.config/ccstatusline/settings.jsonRender it against a fake payload:
echo '{"session_id":"t","cwd":"'$PWD'","model":{"id":"claude-opus-5","display_name":"Opus 5"},"workspace":{"current_dir":"'$PWD'"}}' \
| CCSTATUSLINE_WIDTH=150 npx -y ccstatusline@latestCCSTATUSLINE_WIDTH forces the render width, which matters because flex layout depends on it.
That minimal payload is enough to check colours and separators, but the context, token and
compaction widgets read the session transcript and will show [Timeout], n/a or nothing
without it. To exercise those, point transcript_path at a real session log:
TP=$(ls -t ~/.claude/projects/*/*.jsonl | head -1)
echo '{"session_id":"'$(basename "$TP" .jsonl)'","transcript_path":"'$TP'","cwd":"'$PWD'","model":{"id":"claude-opus-5","display_name":"Opus 5"},"workspace":{"current_dir":"'$PWD'"}}' \
| CCSTATUSLINE_WIDTH=200 npx -y ccstatusline@latestDo not read a [Timeout] from the minimal payload as a broken widget — re-test with a
transcript before changing the config.
Note that neither XDG_CONFIG_HOME nor CLAUDE_CONFIG_DIR redirects where ccstatusline
reads its settings — it resolves the path from the home directory. There is no way to
test an alternative config in isolation, which is why the backup step above matters.
powerline.separators, startCaps and endCaps hold Private Use Area characters:
| Field | Codepoint | Shape |
|---|---|---|
separators |
U+E0B4 |
right half circle |
startCaps |
U+E0B6 |
left half circle |
endCaps |
U+E0B4 |
right half circle |
These do not survive copy/paste through most browsers and chat clients — they get
silently stripped to "", and powerline then renders with no separators at all. Always
download the JSON with curl rather than pasting it. If you do end up with empty strings,
put them back by codepoint:
python3 - <<'EOF'
import json, os
p = os.path.expanduser('~/.config/ccstatusline/settings.json')
c = json.load(open(p))
c['powerline']['separators'] = [""]
c['powerline']['startCaps'] = [""]
c['powerline']['endCaps'] = [""]
json.dump(c, open(p, 'w'), indent=2, ensure_ascii=False)
EOFEverything below is editable from the interactive TUI (npx -y ccstatusline@latest),
which is easier than hand-editing JSON.
| Setting | Value here | Notes |
|---|---|---|
flexMode |
full-until-compact |
full terminal width minus 6, dropping to minus 40 once context use crosses compactThreshold. Other values: full, full-minus-40. There is no percentage width option. |
compactThreshold |
60 |
the context-usage percentage that triggers the narrower width above |
powerline.autoAlign |
true |
pads each column to the widest entry in that column across lines, so boundaries line up. The padding is inside the segment, so it is coloured, not a gap. Toggle with a on the Powerline screen. |
current-working-dir → segments |
1 |
shows only the last path component (~/.../project). Raise it to widen. Note ~ counts as a component. Keys h / s / f on the widget. |
git-branch → maxWidth |
20 |
truncates long branch names with an ellipsis so they cannot dominate the line. Only some widgets support maxWidth — git-branch, git-root-dir, git-untracked-files, git-is-fork, output-style, custom-command. |
claude-account-email |
column 1 of line 3 | worth having to tell a personal account apart from a work one. It is the widest segment in the layout, so it goes first, where the working directory and the model name already make the column wide — see the column rules above. Drop it and the whole grid narrows. |
compaction-counter |
↻ 0 |
counts compact_boundary records in the session transcript, i.e. how many times the context was compacted. metric also accepts auto, manual, unknown and reclaimed (tokens recovered); format switches between ↻ N, Compactions: N and a bare number. Set hideZero to make it disappear until the first compaction. |
reset-timer |
2h3m |
despite the generic name this is the block reset timer — time left in the current 5-hour usage window. Its sibling block-timer shows time elapsed in the same window, so the two disagree by design; putting both on a line is confusing rather than redundant. |
git-worktree → hideNoGit |
true |
shows which working tree you are in, derived from git rev-parse --git-dir rather than from the payload, so it works with hand-made worktrees. Two states worth knowing: main is a hardcoded literal meaning "the main working tree" — not the branch, and it stays main while you are on feature/x. Anything else is the worktree's git name, normally the directory basename, again not the branch. hideNoGit suppresses the no git placeholder outside a repo. |
There is no minimum-width setting for a widget or a column. Column width is purely a function of the widest content in that column.
Several widgets hide themselves when their data source is empty, so the line silently gets shorter rather than showing a placeholder. That is expected, not a broken config:
git-ci-statusandgit-reviewneed a PR on the current branch (and theghCLI authenticated). They show-and(no PR)otherwise.extra-usage-remainingneeds a spending cap to be configured on the account; with no cap there is nothing to subtract from and the widget disappears.- the
worktree-mode,worktree-name,worktree-branchandworktree-original-branchwidgets read aworktreeobject out of the JSON payload Claude Code sends on stdin — they do not ask git. A worktree you created yourself withgit worktree adddoes not put that object in the payload, so all four render nothing even while you are sitting in the worktree. They light up when Claude Code is managing the worktree itself. Usegit-worktreeinstead if you make your worktrees by hand — see below. remote-control-statusrenders only when remote control state exists for the session.session-cost,session-nameandfable-weekly-usagerender nothing at all on a plain account;cache-hit-ratereadsCache Hit: n/a.weekly-opus-usageandweekly-sonnet-usagesit at a permanent0.0%even whileweekly-usageclimbs. These map to theseven_day_opus/seven_day_sonnetrate-limit fields, which are nullable in the payload schema where plainseven_dayis not — they are per-model windows that not every plan populates. Prefer the aggregateweekly-usage.
session-usage, weekly-usage and weekly-reset-timer, on the other hand, do populate
on an ordinary individual account — no team or org membership needed. If line 3 of the
worktree variant looks dead, that is the worktree and spending-cap widgets above, not a
quota-data limitation. Switch to the usage variant rather than giving up on the row.
npx -y ccstatusline@latest → Export Config writes the current in-memory config to
~/ccstatusline-config.json, including unsaved edits. Import Config validates, migrates
older schema versions, previews the effective diff, then applies either Replace All
(omitted fields go back to defaults) or Merge (only the fields present in the file are
overlaid). Both preserve machine-local installation metadata.