pi-powerline-footer

# pi-powerline-footer Customizes the default [pi](https://github.com/badlogic/pi-mono) editor with a powerline-style status bar, welcome overlay, and AI-generated "vibes" for loading messages. Inspired by [Powerlevel10k](https://github.com/romkatv/powerlevel10k) and [oh-my-pi](https://github.com/can1357/oh-my-pi). Image ## Features **Editor stash** — Press `Alt+S` to save your editor content and clear the editor, type a quick prompt, and your stashed text auto-restores when the agent finishes. Toggles between stash, pop, and update-existing-stash. A `stash` indicator appears in the powerline bar while text is stashed. **Working Vibes** — AI-generated themed loading messages. Set `/vibe star trek` and your "Working..." becomes "Running diagnostics..." or "Engaging warp drive...". Supports any theme: pirate, zen, noir, cowboy, etc. **Welcome overlay** — Branded splash screen shown as centered overlay on startup. Shows gradient logo, model info, keyboard tips, loaded AGENTS.md/extensions/skills/templates counts, and recent sessions. Auto-dismisses after 30 seconds or on any key press. **Rounded box design** — Status renders directly in the editor's top border, not as a separate footer. **Fixed editor cluster** — In interactive TUI sessions, chat/feed content scrolls above the fixed Pi working/status line, powerline rows, editor, ghost suggestions, bash transcript, and last-prompt/status rows. Scroll chat with the mouse wheel, PageUp/PageDown, Command+PageUp/PageDown, Ctrl+Shift+Up/Down, or message-jump shortcuts; the editor stays put. Drag text to copy it, drag selection to the viewport edge to scroll, double-click a line to select it, and right-click to open the terminal menu. Use `/powerline fixed-editor off` for Pi’s regular scrolling layout, or `/powerline mouse-scroll off` for native terminal selection. **Live thinking level indicator** — Shows current thinking level (`think:off`, `think:med`, etc.) with per-level colors. High and xhigh levels use a rainbow effect inspired by Claude Code's ultrathink. **Smart defaults** — Nerd Font auto-detection for iTerm, WezTerm, Kitty, Ghostty, and Alacritty with ASCII fallbacks. Colors matched to oh-my-pi's dark theme. **Git integration** — Async status fetching with 1s cache TTL. Automatically invalidates on file writes/edits. Shows branch, staged (+), unstaged (*), and untracked (?) counts. **Context awareness** — Color-coded warnings at 70% (yellow) and 90% (red) context usage. During streaming, the context segment refreshes from live assistant usage instead of waiting for the next turn. Auto-compact indicator when enabled. If `pi-custom-compaction` is installed and enabled, the powerline automatically hides native context segments so the footer does not show stale post-summary usage. **Token intelligence** — Smart formatting (1.2k, 45M), subscription detection (shows "(sub)" vs dollar cost). **Sticky bash mode** — Toggle bash mode with `ctrl+shift+b` or `/bash-mode`. It keeps a managed shell session alive for the current pi session, shows a dedicated `shell_mode` segment, streams command output into an embedded transcript below the editor, and lets `cd` or exported state persist across commands. **Shell ghost suggestions** — Bash mode is now ghost-first. Successful per-project shell history is the primary source, while deterministic path and git continuations can still extend an existing command. Shell-native completion probes are disabled so `!command` predictions never spawn interactive shell completion subprocesses. At command position, short stems first resolve from the newest successful local command, can use guarded global shell history for high-confidence heads like `git`, and finally fall back to a tiny curated default set when history is absent. Right now that curated set is `g` → `git status` and `c` → `cd ..`. If the bash prompt is empty, bash mode shows the newest successful project-history ghost suggestion when one exists, otherwise it stays empty. The same inline predictions now also kick in for one-off `!command` and `!!command` prompts. Right Arrow or Tab accepts ghost text into the editor, and Enter runs the current shell command. ## Installation ```bash pi install npm:pi-powerline-footer ``` Restart pi to activate. ## Usage Activates automatically. Toggle with `/powerline`, switch presets with `/powerline `, fixed-editor mode with `/powerline fixed-editor on|off|toggle`, and wheel mode with `/powerline mouse-scroll on|off|toggle`. Fixed editor is on by default. - `/powerline fixed-editor off` — return to Pi’s regular scrolling layout - `/powerline fixed-editor on` — re-enable the fixed editor - `/powerline fixed-editor toggle` — switch between the two You can also set it in `~/.pi/agent/settings.json` or project-local `.pi/settings.json`: ```json { "powerline": { "preset": "default", "fixedEditor": false } } ``` Use `"fixedEditor": true` to enable it again. Add `"mouseScroll": false` if you want native terminal selection instead of fixed-editor mouse handling. | Preset | Description | |--------|-------------| | `default` | Model, thinking, path (basename), git, context, tokens, cost | | `minimal` | Just path (basename), git, context | | `compact` | Model, git, cost, context | | `full` | Everything including hostname, time, abbreviated path | | `nerd` | Maximum detail for Nerd Font users | | `ascii` | Safe for any terminal | **Environment:** `POWERLINE_NERD_FONTS=1` to force Nerd Fonts, `=0` for ASCII. Preset selection is saved to `~/.pi/agent/settings.json` under `powerline` and restored on startup. Run `/powerline default` to switch back to the default preset. ### Custom items from extension statuses You can promote any extension status key into its own dedicated powerline item. This gives you a general way to register your own status items without changing this extension. 1. Any extension can publish status text through `ctx.ui.setStatus("my-key", "...value...")`. 2. Configure `powerline.customItems` to place those keys on the left, right, or secondary row. ```json { "powerline": { "preset": "default", "customItems": [ { "id": "ci", "statusKey": "ci-status", "position": "right", "prefix": "CI", "color": "warning" }, { "id": "review", "position": "secondary", "hideWhenMissing": false, "prefix": "review" } ] } } ``` `customItems` fields: - `id` (required): unique item id (`a-z`, `A-Z`, `0-9`, `_`, `-`) - `statusKey` (optional): extension status key to read, defaults to `id` - `position` (optional): `left`, `right`, or `secondary` (default `right`) - `prefix` (optional): text shown before the live status value - `color` (optional): any Pi theme color (`warning`, `accent`, etc.) or hex (`#RRGGBB`) - `hideWhenMissing` (optional): hide item when no status is present (default `true`) - `excludeFromExtensionStatuses` (optional): omit this key from the aggregate `extension_statuses` segment (default `true`) If you still prefer the old style, `"powerline": "default"` continues to work. ## Bash mode Toggle bash mode with either: - `ctrl+shift+b` - `/bash-mode on` - `/bash-mode off` - `/bash-mode toggle` Reset the managed shell with `/bash-reset`. While bash mode is active: - Enter runs the current shell command - Right Arrow accepts ghost text into the editor without running it - Tab accepts the current ghost suggestion when one exists; otherwise it does nothing - Up and Down browse matching shell history - `escape` exits bash mode and returns to normal prompt mode - `ctrl+c` interrupts the active shell job before falling back to normal pi behavior The managed shell is persistent for the current pi session. Command output appears in a transcript below the editor, and shell cwd changes are reflected in the footer path and `shell_mode` segment. If the bash prompt is empty, bash mode shows the newest successful project-history ghost suggestion immediately when one exists, including right after mode entry or after the prompt is cleared again. One-off `!command` and `!!command` prompts reuse the same shell prediction pipeline, including ghost text. Mode entry stays quiet: there is no automatic or manual dropdown completion surface, and ghost suggestions do not run shell-native completion probes. ### Bash mode configuration In `~/.pi/agent/settings.json`: ```json { "bashMode": { "toggleShortcut": "ctrl+shift+b", "transcriptMaxLines": 2000, "transcriptMaxBytes": 524288 } } ``` ## Editor Stash Use `Alt+S` / `Option+S` as a quick stash toggle while drafting. It keeps one active stash and clears the editor when stashing. | Editor | Stash | `Alt+S` result | |--------|-------|----------------| | Has text | Empty | Stash current text, clear editor | | Empty | Has stash | Restore stash into editor | | Has text | Has stash | Update stash with current text, clear editor | | Empty | Empty | Show "Nothing to stash" | Auto-restore after an agent run only happens when the editor is still empty. If you typed meanwhile, the stash is preserved. The `stash` indicator appears in the powerline bar (on presets with `extension_statuses`). Active stash is still session-local and resets on session switch / disable, but stash history is persisted to `~/.pi/agent/powerline-footer/stash-history.json` so it survives restarts. ### Stash history Open prompt history with either: - `ctrl+alt+h` - `/stash-history` Prompt history now has two sources: - stashed prompts — up to 12 recent stashed prompts (newest first) - recent project prompts — up to 50 recent user-submitted prompts pulled from pi sessions in the current project folder Selecting an entry inserts it into the editor. If the editor already has text, you can choose `Replace`, `Append`, or `Cancel`. ### Editor clipboard and chat shortcuts - `ctrl+alt+c` — copy full editor content - `ctrl+alt+x` — cut full editor content (copy, then clear) - `cmd+up` — scroll the fixed-editor chat viewport up - `cmd+down` — scroll the fixed-editor chat viewport down - `cmd+shift+up` — move the editor cursor to the start of the first line - `cmd+shift+down` — move the editor cursor to the end of the last line - `ctrl+shift+u` — jump the fixed-editor chat viewport to the previous user message - `ctrl+shift+i` — jump the fixed-editor chat viewport to the next user message - `ctrl+alt+,` — jump the fixed-editor chat viewport to the previous LLM message - `ctrl+alt+.` — jump the fixed-editor chat viewport to the next LLM message - `ctrl+shift+g` — jump the fixed-editor chat viewport to the bottom Copy/cut actions do not modify stash state or stash history. Dragging files, folders, images, or screenshots from Finder into the custom editor inserts their path strings. Chat jumps require fixed-editor mode because they use its app-owned scroll viewport. Submitting editor text also returns that viewport to the bottom so new output stays in view. ### Shortcut configuration You can override shortcut keys in `~/.pi/agent/settings.json`: ```json { "powerlineShortcuts": { "stashHistory": "ctrl+alt+h", "copyEditor": "ctrl+alt+c", "cutEditor": "ctrl+alt+x", "jumpPreviousUserMessage": "ctrl+shift+u", "jumpNextUserMessage": "ctrl+shift+i", "jumpPreviousLlmMessage": "ctrl+alt+,", "jumpNextLlmMessage": "ctrl+alt+.", "jumpChatBottom": "ctrl+shift+g", "scrollChatUp": "cmd+up", "scrollChatDown": "cmd+down", "editorStart": "cmd+shift+up", "editorEnd": "cmd+shift+down" } } ``` After changing bindings, run `/reload`. Invalid bindings, reserved key conflicts (like `Alt+S`), or duplicate conflicts automatically fall back to safe defaults. `cmd` and `command` are accepted aliases for Pi's `super` modifier for the documented Command navigation keys; unsupported Command-letter bindings such as `cmd+c` are ignored instead of matching plain text input. Some terminals, including Ghostty, bind Command+Arrow themselves; remap those terminal keys to send `\x1b[1;9A` / `\x1b[1;9B` for chat scrolling and `\x1b[1;10A` / `\x1b[1;10B` for editor-boundary navigation if you want Pi to receive them. ## Working Vibes Transform boring "Working..." messages into themed phrases that match your style: ``` /vibe star trek → "Running diagnostics...", "Engaging warp drive..." /vibe pirate → "Hoisting the sails...", "Charting course..." /vibe zen → "Breathing deeply...", "Finding balance..." /vibe noir → "Following the trail...", "Checking the angles..." /vibe → Shows current theme, mode, and model /vibe off → Disables (back to "Working...") /vibe model → Shows current model /vibe model openai/gpt-4o-mini → Use a different model /vibe mode → Shows current mode (generate or file) /vibe mode file → Switch to file-based mode (instant, no API calls) /vibe mode generate → Switch to on-demand generation (contextual) /vibe generate mafia 200 → Pre-generate 200 vibes and save to file ``` ### Configuration In `~/.pi/agent/settings.json`: ```json { "workingVibe": "star trek", // Theme phrase "workingVibeMode": "generate", // "generate" (on-demand) or "file" (pre-generated) "workingVibeModel": "openai-codex/gpt-5.4-mini", // Optional: model to use (default) "workingVibeFallback": "Working", // Optional: fallback message "workingVibeRefreshInterval": 30, // Optional: seconds between refreshes (default 30) "workingVibePrompt": "Generate a {theme} loading message for: {task}", // Optional: custom prompt template "workingVibeMaxLength": 65 // Optional: max message length (default 65) } ``` ### Modes | Mode | Description | Pros | Cons | |------|-------------|------|------| | `generate` | On-demand AI generation (default) | Contextual, hints at actual task | Model-dependent cost and latency | | `file` | Pull from pre-generated file | Instant, zero cost, works offline | Not contextual | **File mode setup:** ```bash /vibe generate mafia 200 # Generate 200 vibes, save to ~/.pi/agent/vibes/mafia.txt /vibe mode file # Switch to file mode /vibe mafia # Now uses the file ``` **How file mode works:** 1. Vibes are loaded from `~/.pi/agent/vibes/{theme}.txt` into memory 2. Uses seeded shuffle (Mulberry32 PRNG) — cycles through all vibes before repeating 3. New seed each session — different order every time you restart pi 4. Zero latency, zero cost, works offline **Prompt template variables (generate mode only):** - `{theme}` — the current vibe theme (e.g., "star trek", "mafia") - `{task}` — context hint (user prompt initially, then agent's response text or tool info on refresh) - `{exclude}` — recent vibes to avoid (auto-populated, e.g., "Don't use: vibe1, vibe2...") **How it works:** 1. When you send a message, shows "Channeling {theme}..." placeholder 2. AI generates a themed message in the background (3s timeout) 3. Message updates to the themed version (e.g., "Engaging warp drive...") 4. During long tasks, refreshes on tool calls (rate-limited, default 30s) 5. Cost and latency depend on your configured `workingVibeModel` ## Thinking Level Display The thinking segment shows live updates when you change thinking level: | Level | Display | Color | |-------|---------|-------| | off | `think:off` | gray | | minimal | `think:min` | purple-gray | | low | `think:low` | blue | | medium | `think:med` | teal | | high | `think:high` | rainbow | | xhigh | `think:xhigh` | rainbow | ## Path Display The path segment supports three modes: | Mode | Example | Description | |------|---------|-------------| | `basename` | `powerline-footer` | Just the directory name (default) | | `abbreviated` | `…/extensions/powerline-footer` | Full path with home abbreviated and length limit | | `full` | `~/.pi/agent/extensions/powerline-footer` | Complete path with home abbreviated | Configure via preset options: `path: { mode: "full" }` ## Git polling By default the git segment polls both branch and dirty state. If background `git status --porcelain` calls interfere with your workflow, use branch-only polling: ```json { "powerline": { "git": { "polling": "branch" } } } ``` Use `"off"` to disable extension-owned git polling entirely and only show the branch reported by Pi when available. ## Segments `model` · `thinking` · `shell_mode` · `path` · `git` · `subagents` · `token_in` · `token_out` · `token_total` · `cost` · `context_pct` · `context_total` · `time_spent` · `time` · `session` · `hostname` · `cache_read` · `cache_write` ## Separators `powerline` · `powerline-thin` · `slash` · `pipe` · `dot` · `chevron` · `star` · `block` · `none` · `ascii` ## Theming Colors are configurable via pi's theme system. Each preset defines its own color scheme, and you can override individual colors and icons with a `theme.json` file in the extension directory. ### Default Colors | Semantic | Theme Color | Description | |----------|-------------|-------------| | `model` | `#d787af` | Model name | | `shellMode` | `accent` | Bash mode segment | | `path` | `#00afaf` | Directory path | | `gitClean` | `success` | Git branch (clean) | | `gitDirty` | `warning` | Git branch (dirty) | | `thinking` | `thinkingOff` | Thinking level (`off`) | | `thinkingMinimal` | `thinkingMinimal` | Thinking level (`minimal`) | | `thinkingLow` | `thinkingLow` | Thinking level (`low`) | | `thinkingMedium` | `thinkingMedium` | Thinking level (`medium`) | | `context` | `dim` | Context usage | | `contextWarn` | `warning` | Context usage >70% | | `contextError` | `error` | Context usage >90% | | `cost` | `text` | Cost display | | `tokens` | `muted` | Token counts | ### Custom Theme Override Create `~/.pi/agent/extensions/powerline-footer/theme.json`: ```json { "colors": { "pi": "#ff5500", "model": "accent", "shellMode": "accent", "path": "#00afaf", "gitClean": "success", "thinking": "thinkingOff", "thinkingMinimal": "thinkingMinimal", "thinkingLow": "thinkingLow", "thinkingMedium": "thinkingMedium" }, "icons": { "auto": "↯", "warning": "" } } ``` Colors can be: - **Theme color names**: `accent`, `muted`, `dim`, `text`, `success`, `warning`, `error`, `border`, `borderAccent`, `borderMuted` - **Hex colors**: `#ff5500`, `#d787af` Icons can be any string, including `""` when you want to suppress a specific glyph entirely. See `theme.example.json` for all available options.