@timmyjl12/pi-statusline
v0.1.0
Published
Powerline statusline footer for the pi coding agent — built-in themes, spacious full + multiline layouts, rich git/PR/context segments.
Maintainers
Readme
@timmyjl12/pi-statusline
Powerline statusline footer for the pi coding agent — built-in
themes, a spacious full layout that spreads across the whole terminal width,
and an airy grouped multiline layout. Based on
@narumitw/pi-statusline,
with ideas from
@yorch/pi-statusbar (theme-token
auto mode, rich git/PR/context segments, presets, Nerd Font detection) and
feniix/pi-statusline
(live activity + skill tracking, throttled rerenders, statusline tool).
multiline: 🌣 anthropic model 🧠 high devbox ◷ 12m 🕒 14:32
🔢 ↑12k ↓1.8k 📦 R200k W23k CH85.0% 42.0%/200k Act: running
💸 $0.0043 /workspace/project ⎇feature/statusline ✎ c921a07 Add thing
🧭 advisor: ON · 🔌 MCP: 3 servers enabledInstall
pi install npm:@timmyjl12/pi-statuslineOr try it without installing:
pi -e npm:@timmyjl12/pi-statuslineLocal development (from this repository's root):
npm run check # typecheck + tests
npm run preview # render every layout with fixture dataIf Pi loads this local folder, run /reload after editing it. At a normal terminal
width, the first multiline row should show 🌣 <active provider> before the
model; compare it with /model after switching providers.
Layouts
| Layout | Shape | Idea |
| ----------- | ----- | ---- |
| minimal | 1 line | provider · model · cwd · branch · context |
| compact | 1 line | provider · model · git · cost · context + session clock |
| default | 1 line | full telemetry, dense (yorch-style) |
| full | 1 spacious line across the whole width | identity left, telemetry right, justified to the edges with generous padding — easiest single-line read |
| multiline (default) | 3 rows, plus optional fourth | provider/model/thinking + session; tokens/cache/context + tools/activity; cost + full directory/git/longer commit; extension statuses (e.g. pi-advisor) when available |
Built-in presets show the active provider before the model when space permits;
custom segments lists must include provider explicitly. Rows that overflow
the terminal width shed their lowest-priority segments first (context and cache
are kept longest, then model, tools, activity, tokens, and cost); a row that
cannot fit even one segment renders empty rather than over-wide.
Themes
auto (default) · tokyo-night · ocean · sunset · forest ·
candy · neon · mono · custom.
auto follows pi's active theme via theme tokens (re-skins with Tokyo Night,
light, or any custom theme). custom reads per-block hex colors from
customBlocks, or per-segment segmentPalette colors. Set
"transparentBackground": true to keep custom foregrounds while painting no
backgrounds.
Working indicator
The animation pi shows in the editor's top border while it works, plus the
footer's working… icon, are configurable. Defaults keep the original
pulse. /statusline indicator lists the animals first, then the regular
modes; picking an animal asks how it should animate (dance, pulse,
breathing, or static — and the penguin then asks for its rendering style).
| Mode | Look |
| ---- | ---- |
| pulse (default) | the original · • ● • heartbeat dot — or, with an animal, dots beating around it (·🐧· ●🐧●, the pulsing penguin) |
| dance | an animal traversing the line with alternating music notes — the penguin can dance as the 🐧 emoji, as classic ASCII poses (choreography derived frame-by-frame from a real dancing GIF), or as a custom font glyph (see below); other animals are emoji |
| breathing | a slow breath: dots spread and brighten around the animal on the inhale (· 🐧 · ↔ · 🐧 ·) |
| static | the animal, once — no animation |
| dot | a single . sweeping left ↔ right |
| scanner | a ▓ block dragging a fading ▒░ trail, ping-pong |
| equalizer | a scrolling ▁▂▃▄▅▆▇█ audio wave |
| orbit | rotating ◐◓◑◒ |
| moon | lunar phases 🌑→🌘 |
| ecg | heartbeat ♥♥♡ rhythm |
| clock | spinning 🕐→🕛 |
| dice | rolling ⚀→⚅ |
Subjects: auto (default — each mode's own subject: plain dots for the
abstract modes, penguin for dance, breathing, and static) · penguin · dog · cat · otter ·
duck · frog · fox · panda · crab · snail · turtle · unicorn.
Animals apply to dance, pulse, breathing, and static.
Message: working (default — pi's trailing Working text) · none (hides the
border message and the footer's working… suffix; the transient interrupt
hint still reappears when pi needs it).
Colors: auto (per-mode theme defaults) · a theme token (accent, success,
warning, error, dim, muted) · a custom #RRGGBB (truecolor with
ANSI-256 fallback). The color applies to the top-line frames and the
footer's working icon. Emoji frames (moon, clock, emoji
animals) keep their native colors — terminals ignore ANSI color on emoji.
Where things appear: during a turn, the editor's top border shows the animated
frame next to pi's Working message (the penguin walks the line doing its
pose cycle), while the footer's status segment shows a single static icon
(🐧 working… when dancing; ✓ done when the turn completes).
Custom penguin glyph
/statusline penguin glyph renders the penguin as a single character
(U+E900) patched into your terminal font — crisp at any size, and
ANSI-colorable (it follows color, unlike emoji). It needs a one-time font
setup on your machine:
python tools/penguin-font.py <your-terminal-font.ttf> <penguin.gif> --out-dir outInstall the output font and select it as your terminal font (e.g. in Windows
Terminal settings), then /statusline penguin glyph. Without the patched
font, U+E900 renders as a missing-glyph box — so this style is machine-local,
not something the package can ship. The tool traces the GIF's alpha mask to
TrueType outlines (monochrome silhouette); regenerate src/penguin.ts
poses from the same GIF with tools/penguin-gif-frames.py.
Traversal modes re-fit their span when the terminal resizes (frames are
regenerated live). Regenerate the penguin poses from any GIF with
python tools/penguin-gif-frames.py <gif> --out src/penguin.ts (requires
Pillow).
Commands
/statusline— open a themed settings menu (no args); selecting a setting opens its choices. Type a subcommand to jump directly to its choices, or press Tab for argument completions:theme <name>·layout <name>·directory <auto|full|short>·separator <name>·density <name>·nerd <on|off|auto>·context <percent|remaining|used>·contextbar <on|off>·pr|skill|activity <on|off>·indicator <animal|mode>·animal <auto|name>·message <working|none>·color <auto|token|#RRGGBB>·penguin <emoji|ascii|glyph>·import-legacy·status·settings·help/footer— alias for/statusline
The extension also registers a statusline model tool that returns the
current statusline text (handy for scripting and non-UI sessions).
Settings
One dedicated file, global + project merge (project wins):
- global:
<agentDir>/timmyjl12_pi_statusline/config.json - project:
<cwd>/.pi/timmyjl12_pi_statusline/config.json
The old <agentDir>/pi-statusline.json belongs to another extension and is
never read or overwritten at runtime. Use /statusline import-legacy (or
python.exe tools/import_legacy_config.py from this repo) to copy its supported
customizations into this package's settings while keeping the active multiline
default. Run /statusline to change settings; the folder and file are created on
the first successful change.
{
"theme": "auto",
"layout": "multiline",
"directoryMode": "auto",
"density": "cozy",
"separator": "none",
"nerd": null,
"contextBar": true,
"contextMode": "percent",
"indicator": "pulse",
"indicatorAnimal": "auto",
"indicatorMessage": "working",
"indicatorColor": "auto",
"penguinStyle": "emoji",
"showPr": true,
"showSkill": true,
"showActivity": true,
"transparentBackground": false
}Optional legacy-compatible settings: segmentText (per-segment prefix,
suffix, and model truncation), extensionStatusIcons (status key → icon,
with exact → wildcard → alias → * precedence), icons (base icon glyphs),
and segmentPalette (per-segment fg/bg; bg: "transparent" is supported).
directoryMode: "auto" shows the full directory path in multiline and a
shortened path in other layouts; "full" or "short" overrides either.
Custom layouts use segments with "line_break" row splits (sets
layout: "custom" unless an explicit preset layout is also given):
{
"layout": "custom",
"segments": ["model", "cwd", "branch", "line_break", "context", "tokens", "time"]
}customBlocks selects the custom theme:
{
"theme": "custom",
"customBlocks": {
"header": { "fg": "#090c0c", "bg": "#a3aed2" },
"meter": { "fg": "#a0a9cb", "bg": "#1d2230" }
}
}Nerd Font icons auto-detect iTerm / WezTerm / Kitty / Ghostty / Alacritty (and
Ghostty inside tmux); override with "nerd": true|false or
STATUSLINE_NERD_FONTS=1/0. When no Nerd Font is detected, the powerline
and round separators automatically fall back to dots (the half-circle
glyphs only exist in Nerd Fonts, so any other font shows boxes).
Debugging
Only settings inside the package-specific folder apply. Unsupported keys in
that folder's config.json are listed by /statusline status; malformed files
produce a session-start warning. The old pi-statusline.json is ignored.
Silent by default. To trace failures (subprocesses, settings loads, footer lifecycle), enable debug logging — logs go to stderr, never stdout:
PI_STATUSLINE_DEBUG=1 piLines look like [pi-statusline:git] <timestamp> <message> {"json"}.
User-visible problems additionally surface in /statusline status and as
notification toasts.
Segments
brand · provider · model · thinking (shown once) · cwd
(full/contracted by directory mode) · path (same directory mode) · branch · git (worktree
⁺, conflicts ⚑, ⇡ahead ⇣behind, +staged ~modified ?untracked) · diff
(unstaged lines added/deleted) · stash (saved stash entries) · commit (shortSha + longer subject) · remote
(host/owner/repo) · pr (clickable #n via gh, draft-aware) · tools
(active built-in/extension/MCP tool + fan-out count and cumulative uses N) · activity (Act: thinking|responding|bash
x2|idle) · skill (last explicit skill) · context (eighth-block bar +
percent/remaining/used, warns >70%, errors >90%) · tokens (↑↓ +/min rate) ·
cache (R + W + CH%) · cost (adaptive precision) · time · session
(elapsed) · hostname · turn · worktree · statuses (other extensions).
Git state refreshes on events (session start, prompt submit, agent end, file-mutating
tool calls, model change), debounced and coalesced, plus a slow 20 s fallback. Rendering
itself never spawns a process. Every git call runs with optional locks disabled
(--no-optional-locks, GIT_OPTIONAL_LOCKS=0), so it cannot contend with your own
git add/commit for index.lock. Only the git fields the active layout shows are
fetched. PR state uses a 5 min TTL. Footer rerenders are throttled to ~100ms during
streaming, and settings files are re-checked by async mtime at most every 5 s.
Attribution
- Base design, palettes, responsive fitting, dedicated settings file: @narumitw/pi-statusline (MIT).
- Theme-token mode, rich git/PR/context segments, presets, nerd detection, working indicator: @yorch/pi-statusbar (MIT).
- Live activity/skill tracking, throttled scheduler, statusline tool: feniix/pi-extensions pi-statusline (MIT).
License
MIT — see LICENSE.
