@aliaksei-raketski/pi-statusline
Pi extension for a highly customizable, ANSI-aware statusline footer.
Package details
Install @aliaksei-raketski/pi-statusline from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@aliaksei-raketski/pi-statusline- Package
@aliaksei-raketski/pi-statusline- Version
0.3.8- Published
- Jul 22, 2026
- Downloads
- 807/mo · 41/wk
- Author
- aliaksei-raketski
- License
- MIT
- Types
- extension
- Size
- 97.8 KB
- Dependencies
- 1 dependency · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@aliaksei-raketski/pi-statusline
A Pi extension that replaces the footer statusline with a configurable, multi-line layout.
Install
pi install npm:@aliaksei-raketski/pi-statusline
# or project-local
pi install -l npm:@aliaksei-raketski/pi-statusline
Features
- Runtime TypeScript extension loaded directly by Pi; no package build step is required.
- Published package includes the
extensions/statuslinesource tree used by Pi at runtime. - Custom footer layout with spacer tokens.
- Single-line and multi-line layouts.
- Automatic narrow-terminal fallback to one status item per line.
- Per-token and per-state color control (
muted, theme names, hex, or 256-color numbers). - Optional extension statuses from
ctx.ui.setStatus():- Use explicit
statusestoken to show all extension statuses. - Or reference any status key name directly in
layoutto show that extension status only.
- Use explicit
- Live updates for model, thinking level, branch, changes, PR, and session usage/cost.
- Project-local config is loaded only when the project is trusted.
Configuration
Configuration is loaded from two files and merged in order:
- User config:
~/.pi/statusline.json - Project config:
<project>/.pi/statusline.json(only when project is trusted)
Invalid config values are ignored and fall back to defaults, with warnings emitted in the UI.
If no user config exists, statusline will create ~/.pi/statusline.json with the default configuration on first launch for easy editing.
Default config
{
"layout": [
["branch", "changes", "pr", "spacer", "project"],
["context", "cache", "cost", "spacer", "model", "thinking"],
["title"],
["cwd"]
],
"separator": " • ",
"separatorColor": "dim",
"prefix": {
"cwd": "⌂",
"branch": "↳ ",
"project": "◯",
"title": "✎",
"model": "◉",
"thinking": "◐",
"context": "◔",
"tokens": "◈",
"cache": "↻",
"statuses": "◍"
},
"colors": {
"cwd": "muted",
"branch": {
"clean": "success",
"dirty": "muted",
"default": "accent"
},
"title": "muted",
"project": "muted",
"model": "toolTitle",
"changes": "dim",
"pr": "muted",
"thinking": {
"off": "thinkingOff",
"minimal": "thinkingMinimal",
"low": "thinkingLow",
"medium": "thinkingMedium",
"high": "thinkingHigh",
"xhigh": "thinkingXhigh"
},
"context": {
"normal": "muted",
"warning": "warning",
"full": "error",
"default": "muted"
},
"tokens": "muted",
"cache": "muted",
"cost": "muted"
}
}
Layout
layout is either:
- a single array of tokens (single line), or
- an array of arrays (multi-line).
A line can include the reserved token spacer to allocate flexible spacing. Note: separator is only inserted between tokens inside the same segment, so if you put spacer between every token, separators may not be visible.
On narrow terminals, the renderer falls back to one item per line (ordered by layout), using all available width and without segment separators/spacers.
Lines that render to no visible content are omitted automatically (for example an empty title line).
Examples:
{ "layout": ["cwd", "branch", "model"] }
{
"layout": [
["cwd", "model", "thinking"],
["changes", "title", "context"]
]
}
Status items
The layout array uses the following token names:
cwd— current working directory, shortened with~for your home directory.model— current model name (model id only, e.g.gpt-4.1), orunknownif unavailable.thinking— current thinking level from Pi:off,minimal,low,medium,high,xhigh.branch— current git branch from footer context. It is stateful:cleanwhen working tree has no changes anddirtywhen there are staged/unstaged/untracked changes.changes— git changes summary with counts:!<conflicts> +<staged> ~<unstaged> ?<untracked> ↑<ahead> ↓<behind>(only non-zero parts are shown; untracked files are counted per-file).pr— current pull request number for current branch, shown asPR #<number>whengh pr viewreturns a number.title— current session name (ctx.sessionManager.getSessionName()) if set.project— project name frompackage.jsonwhen available, otherwise directory name.tokens— total message tokens seen so far as<input>↑ <output>↓.context— context usage:<percent>%/<contextWindow>(for example52.5%/128k) and optional state (normal,warning,full) based on percent.cache— cache usage:<cacheRead>/<cacheWrite> <percent>%using branch history assistant usage.cost— accumulated usage cost shown as$<value>.
statuses is rendered when statuses is explicitly in layout.
You can also include any status key directly (for example my_extension); if another extension sets it via ctx.ui.setStatus("my_extension", "..."), it will be rendered in that slot.
Colors
colorsvalues can be theme tokens (e.g.muted,warning,accent), hex colors (e.g.#8aadf4), 256 colors (0-255), or""for no color.- For stateful items (
branch,thinking,context) you can pass an object keyed by state:
{
"colors": {
"thinking": {
"off": "dim",
"minimal": "muted",
"low": "warning",
"medium": "accent",
"high": "error",
"xhigh": "error"
},
"context": {
"normal": "muted",
"warning": "warning",
"full": "error",
"default": "muted"
}
}
}
For unknown states, default is used as fallback, then built-in defaults are used.
For separator, use separator or separatorColor to control token separators and their color.
Development
Tests live in packages/statusline/extensions/statusline/test. From the repository root:
pnpm nx run @aliaksei-raketski/pi-statusline:test
To try locally from the repository root:
pi -e ./packages/statusline