Files
command-center/omp-docs/pi/statusline.md
T
Frank c2d855b33d Status line: move model segment to the right cluster (model, cost, time)
Left group keeps the where-am-I identity (host, path, git, pr); the right
cluster carries what's-running (model) plus cost and elapsed time, painted
in array order. context_pct verified to hoist into the inline meter spacer
regardless of array position. Docs + changelog updated.
2026-10-18 01:08:26 -07:00

104 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: reference
title: OMP Status Line Customization
description: 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.
tags:
- omp
- tui
- statusline
- config
timestamp: 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](../core/index.md)); the file is file-watched, so edits
repaint a running session without restart (verify visually: niri screenshot,
see [niri capture recipe](../system/index.md)).
## 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 |
|---|---|---|
| `band` (fleet) | merged single row above editor | same row, right side (title skipped — it rides the working row) |
| `claude` | bottom strip, left-aligned | top rule chip, right-aligned |
| `rule` | same as claude, gap above strip | same |
| `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
In the `band` shape (fleet) the meter is the labeled inline line between the
segment groups (`60% ———— × 200K`). In the `claude` shape the red rule left of
the right-segment chip **is** the 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 is the box/band-only
part.
## Path segment and `stripWorkPrefix`
`segmentOptions.path.stripWorkPrefix` (default **true** — the code tests
`!== false`) gates two behaviors in the `path` renderer:
1. **Worktree sessions:** `true` never shows the disk path — it renders the
logical `projectName/worktreeName` label (bare `projectName` when the
current branch is named after the worktree) with the worktree glyph.
`false` opts out and shows the real cwd with a folder glyph, plus a
` ↳ relativeRepoRoot` suffix inside a repo. Base-directory-only is not
renderable in either mode.
2. **All sessions:** `true` uses the pretty display path (scratch sessions
get the scratch-folder icon); `false` uses the raw absolute cwd.
`abbreviate` and `maxLength` (clip, default 40) apply afterwards in both
modes. The fleet runs `true` — logical label, worktree glyph (verified live
2026-10-18; an earlier trial of `false` for the full cwd was rejected by eye).
## Fleet configuration (2026-10-18)
- Shape `band`: one merged status row. Left group: `session_name`, `vim`,
`mode`, `hostname`, `path`, `git` (no branch text — worktree branches are
autogenerated names), `pr`. Right group (array order = paint order, so the
last entry hugs the screen edge): `model`, `cost`, `context_pct`,
`time_spent` — `context_pct` hoists out of the run to paint the labeled
inline meter (`60% ——— × 200K`) as a flexible spacer between the groups.
`session_name` renders on the working row, not the status row.
- Deliberately cut: `token_rate` (lives on the working row), `time` (panel
clock), `cache_*` (noise), `context_total` (implied by the meter),
`subagents`, `session`, `token_in`/`token_out` (cumulative totals are
in `/session` anyway).
- 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](/pi/models.md).