Skip to content

Set Up the Statusline

Claude Code only for this settings-wired bar. Codex has no statusline surface and presents the shared .codearbiter/ state in its SessionStart briefing. Interactive Pi sessions install codeArbiter’s rich footer automatically and restore Pi’s native footer on shutdown or when the custom footer cannot initialize.

codeArbiter ships a token-aware statusline for Claude Code: a compact, full-width box that shows your session usage in every repo and, in an arbiter-enabled one, the live project state. It is dependency-free (native font glyphs only, no Nerd Font) and renders on every session once wired.

The codeArbiter statusline: a folder row; a git row with repo, branch, and a model pill; rate-limit percentages with reset countdowns; an arbiter row showing stage, tasks, open questions, and overrides; and session/today token, cost, burn, and context-usage segments.
  1. 1 folder
  2. 2 git
  3. 3 rate limits
  4. 4 model
  5. 5 arbiter
  6. 6 tokens
  7. 7 cost
  8. 8 burn
  9. 9 context
The real renderer capture, annotated in HTML so the image remains unchanged. Values are deterministic test data.

You will need: the plugin installed (see Install).

Run /ca:statusline once in any Claude Code session to wire the bar. The command writes an absolute statusLine.command entry in ~/.claude/settings.json, pointing at the renderer for your installed plugin version.

/ca:statusline

If a statusLine.command already exists in your settings, the current value is backed up before being replaced. Uninstalling restores the backed-up value; if there was none, the key is removed. The command also writes codeArbiter’s spinnerVerbs set and backs up any prior verbs, restored on uninstall.

To inspect the current state without modifying settings, run /ca:statusline status. Output shows whether settings.json is present, the renderer path (with a found/MISSING indicator), the active statusLine.command, and whether it belongs to codeArbiter.

Run /ca:statusline status, then open a fresh Claude Code session. Confirm that the reported codeArbiter-owned command resolves and a real render appears. The values belong to that session; a documentation screenshot is fixture data. Learn the segment meanings below before changing the palette. The product tour shows actual renderer fixtures.

The statusline defaults to its original violet palette. Set CODEARBITER_THEME in the environment that launches Claude Code to select violet, blue, green, amber, or mono. Names are case-insensitive. An unrecognized name falls back to violet, so a typo cannot break the renderer.

For a POSIX shell, set the value in the process that launches Claude Code:

Terminal window
CODEARBITER_THEME=blue claude

In PowerShell, set it for the current process before launch:

Terminal window
$env:CODEARBITER_THEME = 'blue'
claude

These examples affect that process and its children. They do not permanently rewrite your shell profile. Remove the process override to return to the default.

For a custom palette, set CODEARBITER_THEME=custom. The renderer reads ~/.codearbiter/statusline-theme.json unless CODEARBITER_THEME_FILE names another local file. Both ~ and environment variables in that path are expanded. The file is read-only: rendering does not write configuration or make network requests.

{
"accent": {
"deep": "#6c46b4",
"mid": "#965ce6",
"primary": "#b266ff",
"bright": "#d08cff"
},
"text": {
"muted": "#9696a2",
"normal": "#e8e8f0",
"on_accent": "#120e1a"
},
"semantic": {
"ok": "#78dc96",
"warn": "#ffb84c",
"danger": "#ff566e"
},
"gradient": {
"from": "#7850c8",
"to": "#cd8cff"
}
}

Every field is optional and omitted fields inherit from violet. Values must use six-digit #RRGGBB notation. Unknown keys and invalid color values are ignored. A missing, unreadable, oversized, malformed, or non-object file rejects the custom theme as a whole and safely renders with violet instead.

The standard NO_COLOR environment variable takes precedence over every built-in and custom theme. When it is present, the final statusline contains no ANSI color sequences while retaining the same text, glyphs, spacing, and clipping.

Compare the actual renderer output for violet, blue, green, amber and mono. The gallery uses identical deterministic fixture data in every theme. It is not a live session or billing report. NO_COLOR still takes precedence over a theme choice.

The bar has two tiers of segments.

These render in every Claude Code session, regardless of whether the open repo is arbiter-enabled.

KeySegmentShows
1
folder
Active working directory, abbreviated to key path components
2
git
Repo owner/name and current branch, with a dirty-state marker when uncommitted changes are present
4
model
Model display name and effort level as a colored pill
3
rate limits
5-hour and 7-day API usage percentages, with reset countdowns when the host supplies them
9
context
Context window usage bar, used percentage, and remaining headroom before auto-compaction
6
tokens
Session and daily in/out token counts from the session transcript and its subagent transcripts, each request counted once
7
cost
Session and daily API-equivalent cost reconstructed from those transcripts at list API rates, with a provenance label (see Reading the cost figure)
8
burn
Per-request token sparkline for the parent session’s own calls; subagent usage counts toward totals, not burn
not shown
subagents
Recent tasks with liveness, selected model, input/output tokens, and age; mixed or missing model metadata is explicit

The cost is an estimate of what the same tokens would cost at pay-as-you-go list API rates. It is not a bill, and it is not what a subscription charges. codeArbiter prices every request it finds in the parent transcript and every subagent transcript under it, using rates shipped with the plugin. Each request is counted once, even when streaming snapshots or forked subagents repeat it. The label tells you how far to trust the number:

LabelMeaning
api≈$N
Complete: every observed request was priced
api≥$N
A lower bound. Some usage could not be priced (an unknown model, tool, or price modifier), or a large transcript is still being read. The figure only rises as coverage improves
api≈?
No dollar figure codeArbiter can defend: nothing has been reconstructed yet (shown grey), or usage exists but none of it could be priced (shown amber)
host≈$N
Session only, when reconstruction is unavailable: Claude Code’s own session estimate. It is never mixed with api figures and never used for Today
trailing *
Stale: that redraw could not take the ledger lock, so it shows the last saved totals

In a narrow box the words drop and the symbol stays (≈$N, ≥$N, h≈$N).

The statusline updates only when Claude Code redraws it, and codeArbiter adds no timer of its own. Each redraw reads a bounded amount of new transcript. Work that does not fit is never lost: it resumes on the next redraw, and the figure reads api≥ until it catches up. Per-session accounting state lives under ~/.codearbiter/ledger.json.sessions/.

These render only when the open repo carries arbiter: enabled in .codearbiter/CONTEXT.md. The activation check uses the same frontmatter parser the enforcement hooks use, so the bar and the gates always agree on whether a repo is active. See Enforcement & Security for the activation contract.

KeySegmentShows
5
stage
Current project stage from the stage key in CONTEXT.md frontmatter
5
tasks
In-flight task count from open-tasks.md; done tasks are excluded
5
questions
Count of open CONFIRM-NN questions in open-questions.md
5
overrides
Override entries logged since the last /ca:checkpoint

A non-zero questions or overrides count renders in red. A non-zero tasks count renders in white. A green dot before the arbiter row confirms the repo is active.

/ca:statusline uninstall

If a prior statusLine.command was backed up at install time, it is restored. Spinner verbs are restored the same way.

Every session, session-start.py runs the refresh action automatically. If the wired path points at a previous plugin version, for example after a plugin update moves the renderer, the path is rewritten to the current absolute location. The write happens only when the path actually changed; a steady-state session never modifies settings.json.

If the renderer file is absent mid-update, the self-heal skips the write. A later session where the file is present corrects the path.

/ca:statusline refuses to touch ~/.claude/settings.json when the file is not valid JSON:

REFUSING TO WRITE: ~/.claude/settings.json is not valid JSON (...).
Fix it by hand, then re-run - I will not clobber an unparseable settings file.

Open the file in a text editor, restore valid JSON, then re-run /ca:statusline.


For the statusline.py renderer and wire-statusline.py script reference, see Hooks reference: non-event scripts. For Pi’s automatic rich-footer behavior and its fail-soft native fallback, see Pi host support.