Named presets silently ignore leftSegments/rightSegments - the nerd preset's baked arrays were what we saw, and the configured arrays were dead. preset: custom with explicit arrays: chip (right) = token_in, token_out, cost, context_pct, time_spent; strip (left) = session_name, vim, mode, hostname, model, path, git (branch text off - worktree branches are autogenerated; dirty badges kept), pr. Cut tok/s duplicate, clock, cache trio, context_total, subagents, session hash. Composer shape stays claude after live box/band/rule trials. models.yml display name frank-archon drops the (dankserver) suffix; id untouched. Docs: pi/statusline.md records the preset-vs-custom trap, shape->segment routing, and the context-meter truth.
3.9 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | ||||
|---|---|---|---|---|---|---|---|---|
| reference | OMP Status Line Customization | How the omp status line actually works — presets vs custom arrays, composer-shape segment routing, the context meter, and the fleet's tuned segment layout. |
|
2026-10-18 |
OMP Status Line Customization
Ground truth from the installed bundle (@oh-my-pi/pi-coding-agent/dist/cli.js)
verified live on blankpad 2026-10-18. All knobs live in
agent/config.yml under statusLine: (tracked — see
Command Center repo); the file is file-watched, so edits
repaint a running session without restart (verify visually: niri screenshot,
see niri capture recipe).
Preset vs custom — the trap
statusLine.preset ships whole configurations (default, minimal,
compact, full, nerd, ascii, custom). leftSegments /
rightSegments / segmentOptions are only read when preset: custom —
with any named preset they are silently ignored. The fleet config runs
preset: custom.
Composer shape routes the segments
composer.shape decides where the two segment arrays render:
| shape | leftSegments | rightSegments |
|---|---|---|
claude (fleet) |
bottom strip, left-aligned | top rule chip, right-aligned |
rule |
same as claude, gap above strip | same |
band |
merged single row above editor | same row, right side (title skipped — it rides the working row) |
box |
box top border | box top border |
borderless / pi / field / rail |
single bottom bar | single bottom bar |
The ⠿ Working… row is hardcoded: shimmer text + composer.tokenRate readout
(+ session title in band only). Model/thinking-level can never join it
despite the settings description — that composer-bar behavior is Tern-only.
Segment universe (27)
pi, status, model, mode, path, git, pr, subagents,
token_in, token_out, token_total, token_rate, cost, context_pct,
context_total, time_spent, time, session, hostname, cache_read,
cache_write, cache_hit, session_name, usage, collab, stream, vim.
Conditional segments render nothing until their trigger exists: vim needs
tui.vimMode, mode needs plan/yolo, pr needs an associated PR, git shows
staged/unstaged/untracked badges (branch text optional via
segmentOptions.git.showBranch), status needs an extension push.
session = first 8 chars of the session id (resume-by-id handle).
The context meter
The red rule in the claude shape is the context meter: its length tracks
context usage. statusLine.contextLine (off / percentage / annotated /
embedded) only changes rendering in box/band — in claude all non-off
values look identical. Docs' claim that contextLine is "box composer only" is
wrong for the meter itself; the labeled inline variant (57%×—200K←) is the
box/band-only part.
Path segment in worktrees
Inside a git worktree the path segment always renders
projectName/worktreeName when segmentOptions.path.stripWorkPrefix is true
(default), or the abbreviated cwd otherwise — base-directory-only is not
renderable. maxLength clips tail-first.
Fleet configuration (2026-10-18)
- Chip (right):
session_namewas moved to the strip; chip =token_in,token_out,cost,context_pct,time_spent— pure numbers, stable width. - Strip (left):
session_name,vim,mode,hostname,model,path,git(no branch text — worktree branches are autogenerated names),pr. - Deliberately cut:
token_rate(lives on the working row),time(panel clock),cache_*(noise),context_total(implied byx/200K),subagents,session. - Model display names slimmed in
models.yml(frank-archon, no endpoint suffix);name:is free-form display,id:is the wiring — renaming ids is the cutover procedure, see Pi Models.