statusline command
Wire codeArbiter's statusline into ~/.claude/settings.json, or remove it.
/ca:statuslineAvailability is read from each shipped host catalog. Preview-only commands are marked on the page.
What it does
Section titled “What it does”Wires codeArbiter’s renderer into ~/.claude/settings.json, or removes it. A plugin can’t own a
statusLine directly and ${CLAUDE_PLUGIN_ROOT} isn’t expanded inside settings.json, so this
command resolves the renderer’s absolute path and writes it in. It’s the only sanctioned way to
make that edit: the backing script backs up any existing statusLine before overwriting it
(so uninstall can restore it later), and it never clobbers a settings file it can’t parse.
The renderer itself is global — folder, git, model, rate limits, context, cumulative tokens, and
an estimated API-equivalent cost render in every repo. The arbiter-specific segments (stage,
tasks, open questions, overrides) show up only in a repo that has opted in via CONTEXT.md
frontmatter. Token and cost figures are reconstructed from the session transcript and its
subagent transcripts, each request counted once. The cost is an estimated pay-as-you-go
equivalent, not a bill, and its label says how complete it is: api≈ complete, api≥ a lower
bound, api≈? no defensible figure, host≈ Claude Code’s own estimate (Session only, when
reconstruction is unavailable). See the statusline guide for the full contract.
/ca:statusline install | uninstall | statusinstall is the default. Before running install, the resolved command and the prior line it
will back up are shown for confirmation — editing global settings is the user’s call.
Example
Section titled “Example”> /ca:statusline install
About to set statusLine.command to: python "/home/x/.claude/plugins/ca/hooks/statusline.py"No prior statusLine to back up.Proceed? y
WIRED codeArbiter statusline -> python ".../hooks/statusline.py"no prior statusLine existed; uninstall will simply remove ours.
Takes effect on the next render (new prompt or session).When to reach for it
Section titled “When to reach for it”Confirming the wiring took effect, or diagnosing whether something else owns the statusline, is
/ca:doctor’s broader install-health check as well as this command’s own status action.
Related
Section titled “Related”Route context
Section titled “Route context”Find this entry in the workflow atlas. Compare its related teaching maps, host spelling and context inputs. The exact procedure below remains the owner.
Source
Section titled “Source”Source — plugins/ca/commands/statusline.md (v3.7.0)
---description: Wire codeArbiter's statusline into ~/.claude/settings.json, or remove it.argument-hint: "install | uninstall | status"---
# /ca:statusline — wire-up
A plugin cannot own a `statusLine`, and `${CLAUDE_PLUGIN_ROOT}` is not expanded inside`settings.json`. So the renderer at `${CLAUDE_PLUGIN_ROOT}/hooks/statusline.py` is wired in byresolving its absolute path at install time and writing it to the user's `statusLine.command`. Thebacking script `${CLAUDE_PLUGIN_ROOT}/hooks/wire-statusline.py` performs the surgery deterministicallyand never clobbers a settings file it cannot parse.
The renderer is global — its usage box (folder, git, model, rate limits, context, cumulative tokens,API-equivalent cost, per-call token burn) renders in every repo. The arbiter segments(`stage · tasks · q · over`) light up only where `.codearbiter/CONTEXT.md` sets `arbiter: enabled`.
Token and cost figures are reconstructed from the transcripts on disk: the parent session transcriptand every delegated subagent transcript under it. Each request is counted once, even when streamingsnapshots or forked subagents replay it. The dollar figure is the estimated pay-as-you-go**API-equivalent**, meaning what the same tokens would have cost at the list API rates shipped withcodeArbiter. It is not a bill, and it is not what a subscription charges. Each Session and Todayfigure carries its own label:
- `api≈$N` — every observed request was priced, so the figure is complete.- `api≥$N` — a lower bound. Some usage could not be priced (an unknown model, tool, or price modifier), or the scanner is still catching up on a large transcript. The number only rises as coverage improves.- `api≈?` — no defensible dollar figure: nothing has been reconstructed yet (grey), or usage exists but none of it could be priced (amber). The renderer never shows a precise number it cannot stand behind.- `host≈$N` — Session only, and only when reconstruction is unavailable: Claude Code's own session estimate, the highest value it has reported. It is never mixed with `api` figures and never used for Today.- A trailing `*` marks a stale figure. That render could not take the ledger lock, so it showed the last committed totals instead of zeros.
In a narrow box the words drop and the symbol stays (`≈$N`, `≥$N`, `h≈$N`), so a figure is nevercut off mid-number.
The statusline refreshes only when Claude Code redraws it, and codeArbiter adds no timer. Work that arender defers (bounded reads on a large backlog) is never lost. It resumes on the next redraw, anduntil then the figure reads `api≥`. The per-call burn sparkline tracks the parent session's ownrequests only. Subagent usage counts toward the totals but not toward burn.
Each visible subagent row reports its recorded model. Claude IDs retain a compact family/versionlabel such as `model:sonnet-4-6`; multiple models report `model:mixed`, while absent or malformedmetadata reports `model:?`. The tag uses the active theme's bright accent, with no model-specificcolors.
## Argument
`$ARGUMENTS` is one of `install` (default), `uninstall`, or `status`.
## Procedure
1. Run the backing script with the requested action, passing the resolved plugin root so the absolute path is written correctly:
``` python "${CLAUDE_PLUGIN_ROOT}/hooks/wire-statusline.py" <action> --plugin-root "${CLAUDE_PLUGIN_ROOT}" ```
On non-Windows hosts the interpreter token defaults to `python3`; override with `--interp` only if neither `python` nor `python3` is the wanted interpreter.
2. **install** — back up any existing `statusLine` to `_codearbiterStatuslineBackup`, then set `statusLine.command` to `<python> "<abs>/hooks/statusline.py"`. Re-running install after a plugin upgrade just refreshes the path; it does not overwrite the backup. **Before running install, show the user the resolved command and the prior line it will back up, and confirm.** Editing the user's global settings is their call, not yours.
The script REFUSES to wire a plugin root that will not outlive the session — a git worktree, for instance. `settings.json` is global and the pin is absolute, so a worktree path breaks the statusline the moment that checkout is pruned. On a refusal, report it verbatim and re-run from the real install (the plugin cache, or the main checkout) rather than working around it.
3. **uninstall** — restore the backed-up line, or remove `statusLine` entirely if none existed. Never blocked, wherever it is run from — a user stuck with a dead pin must be able to clear it.
4. **status** — report the current `statusLine.command`, whether it is codeArbiter's, and any backup on file. Changes nothing.
5. Report the script's output verbatim, then state what changed. If install succeeded, tell the user the statusline takes effect on the next render (a new prompt or session). Tip: `CODEARBITER_COMPACT=1` drops the subagent rows; `CODEARBITER_STATUSLINE=off` disables it; `CODEARBITER_WIDTH` sets the box width.
## Hard gate
MUST NOT edit `~/.claude/settings.json` by hand for this — the backing script is the only sanctionedpath, so the backup/restore contract holds. MUST NOT proceed with `install` without first surfacingthe resolved command to the user and getting a go-ahead.