Skip to content

About

Beautiful UI extensions for pi — footer, banner, themes, Nerd Fonts support

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Beautiful Pi

Beautiful UI extensions for pi, the terminal coding agent.

beautiful-pi screenshot

npm version npm downloads Tests License


Features:

  • Animated startup banner
  • Status footer with model, effort, session name, folder, git state and context usage
  • Cohesive rail-styled chat layout
  • One-line tool output for built-in and generic/MCP tools
  • Session auto-naming
  • OpenAI Codex usage monitor
  • OpenCode Go usage monitor
  • Codex account, pool, chain and preset routing with rate-limit failover
  • Provider-aware compaction coordination between Codex and Blackhole
  • Optional Herdr pane-label synchronisation
  • Custom settings TUI

Installation

Prerequisites

  • pi 1.2.0–1.2.x — install it globally.
  • A Nerd Font installed and configured in your terminal (recommended). The extensions degrade gracefully with ASCII fallbacks.

Install the package

From npm

pi install beautiful-pi

From source

git clone https://github.com/danielmrdev/beautiful-pi.git
cd beautiful-pi
pi install .

Then reload pi:

/reload

Development (live-link workflow)

pi install . may link the checkout into ~/.pi/agent/npm/node_modules/. If it installed a copy instead, back it up before replacing it with a symlink:

ln -s "$(pwd)" ~/.pi/agent/npm/node_modules/beautiful-pi

For a linked checkout, update its own dependencies after each pull:

pnpm install --frozen-lockfile

Then /reload. pi update --extensions alone can leave older copies of Codex compaction and Blackhole in Pi's shared npm directory. beautiful-pi loads those engines through package-local entry points, so a matching nested or checkout dependency wins; an outdated resolved version produces a Compaction dependency version mismatch load error instead of silently using the wrong engine. For a copied/npm install, reinstall or update the package to refresh its dependencies. Run pnpm test and pnpm typecheck before pushing.

Built-in extensions

These extensions are part of beautiful-pi itself and are loaded by extensions/index.ts:

Extension Purpose
Banner Animated startup header with agent info and loaded resources; hides on first input.
Footer Stats bar, cwd/Git footer, session timer editor, OpenAI Codex quota and OpenCode Go usage monitors.
One-line tools Compact rendering for bash, read, write, edit, grep, find, ls, plus a generic rail for MCP and other tools.
Assistant style Agent message rendering with thinking rail and text/error styling.
User style Rail-styled user messages.
Custom message style Rail-styled custom messages such as web-search and skill output.
Session title Generates a short title from the first user message, with truncation fallback.
Settings /bpi settings TUI; /beautiful-pi remains as a legacy alias.
Codex accounts /codex account, pool, chain and preset management, OAuth provider registration and rate-limit failover.
Compaction coordinator Selects native Codex compaction for Codex models and Blackhole for other providers.
Herdr pane sync Mirrors the Pi session name to the active Herdr pane when running inside Herdr.

Included integrations

One pi install beautiful-pi enables this curated package catalog automatically; no second package install is needed. Upstream packages remain normal npm dependencies, pinned exactly in package.json:

Category Bundled package Version Purpose Repo
Compaction @ogulcancelik/pi-codex-compaction 0.1.6 Native remote compaction for OpenAI Codex. repo
Compaction pi-blackhole 0.5.12 Conversation compaction and observational memory. repo
Context @hypabolic/pi-hypa 1.0.8 Command rewriting/compression plus Hypa-backed shell and file tools. repo
Workflows @plannotator/pi-extension 0.28.18 Interactive plan, code/PR review and agent Inbox. repo
Workflows @tintinweb/pi-subagents 0.22.0 Subagents, parallel execution and workflow orchestration. repo
Interaction @juicesharp/rpiv-ask-user-question 2.13.8 Structured questionnaires for user input. repo
Interaction @juicesharp/rpiv-btw 2.13.8 /btw side questions without polluting the main conversation. repo

Hypa 1.0.8 fixes panes freezing when another window or cube peer views them, including viewers with different window sizes. The Pi extension prefers a native hypa already on PATH over its bundled binary; keep a separate global Hypa install updated too (hypa update).

pi-rtk-optimizer is no longer bundled: its declared Pi peers stop at 0.80, and Hypa covers b-pi's overlapping shell rewriting and output-compression use. Install RTK separately if you need its RTK-specific filters or /rtk metrics.

@tintinweb/pi-subagents@0.22.0 requires Pi 1.1.0 or newer, fixes cloned mention history on Pi 1.x, and cleans up timers on /reload and session replacement. Its default smart join mode now delivers background completions separately; choose group in /agents → Settings → Join mode to batch by parent turn. When a subagent uses extensions: true, it also starts configured MCP servers. Exclude them per agent with exclude_extensions: builtin:mcp, globally with -builtin:mcp in Pi's extensions setting, or disable them for a run with --no-mcp.

Plannotator 0.28.18 auto-connects detected agents when you run plannotator inbox; disable with PLANNOTATOR_INBOX_CONNECT=0. It asks before adding notes to agent instruction files and shows the changes first.

The package also ships the Plannotator skill at skills/plannotator/SKILL.md and the /btw system prompt at prompts/btw-system.txt.

Plannotator 0.28.18 persists code-review viewed-file progress by default under ~/.plannotator/review-progress (or PLANNOTATOR_DATA_DIR). Records include repo-relative paths in plain text and are not pruned. Disable persistence with PLANNOTATOR_REVIEW_PROGRESS=0 or { "reviewProgress": false } in ~/.plannotator/config.json.

pi-blackhole@0.5.12 is the official release, supports Pi 1.x, and includes the skipForProviders capability used to keep Codex and Blackhole compaction engines mutually exclusive. It also bounds path scanning so long encoded tool output cannot freeze compaction. Blackhole shows its live bh status line by default; set statusBar: false in Blackhole config if b-pi's own footer should be the only status display. See THIRD-PARTY-NOTICES.md for ownership and licenses.

Provider and compaction commands

beautiful-pi manages multiple Codex subscriptions on top of Pi's built-in provider auth. Pi owns the OAuth credential store (~/.pi/agent/auth.json); this package never writes it. In an interactive session:

Typing /codex opens the editor autocomplete with the available sections, subcommands, and existing account/pool/chain/preset refs.

/codex account add <label>   create a new Codex account (e.g. work, personal)
/codex account login [ref]   authenticate the account (run the shown /login)
/codex account logout [ref]  remove the stored credential (run the shown /logout)
/codex account switch [ref]  switch the active model to the account
/codex account list          list accounts with auth status
/codex account status [ref]  detailed status for one account
/codex account quota [ref]   inspect quota windows (5h/7d usage) per account
/codex account remove [ref]  remove the account configuration entry
/codex account migrate       run legacy multi-pass config migration
/codex pool create <name> <member...>   create a pool from account refs
/codex pool list            list pools with members
/codex pool inspect <pool>  per-member eligibility (auth, cooldown, project, strategy)
/codex pool enable <pool>   re-enable a pool
/codex pool disable <pool>  disable a pool (no rotation/failover)
/codex pool delete <pool>   remove the pool
/codex pool add <pool> <member...>      add members
/codex pool remove <pool> <member...>   remove members
/codex pool use <pool>      select a member (round-robin, quota-first, scheduled, or custom)
/codex pool strategy <pool> <round-robin|quota-first|scheduled|custom>
/codex pool schedule <pool> [<HH:MM-HH:MM>,...] [days <spec>] [from <date>] [to <date>] [roles <member>=<role> ...]
/codex pool schedule clear <pool>       remove the schedule
/codex pool selector <pool> <command>   custom member selector (outputs a member ref)
/codex pool selector clear <pool>       remove the selector
/codex chain create <name> <target...>  ordered fallback chain (targets: pool or account refs)
/codex chain list           list chains with targets
/codex chain inspect <chain>  per-target eligibility
/codex chain use <chain>    walk targets (each pool uses its strategy) and activate
/codex chain enable <chain> / disable <chain> / delete <chain>
/codex chain add <chain> <target...> / remove <chain> <target...>
/codex preset create <name> <pool> [model <prefix>]   named routing preset
/codex preset list / inspect <preset>
/codex preset activate <preset>   resolve the best eligible member and switch to it
/codex preset enable <preset> / disable <preset> / delete <preset>
/codex project allow <account...>  restrict this project to the given accounts
/codex project allow all          clear the project account restriction
/codex project pool <name> <member...>   override a global pool's members for this project
/codex project pool enable|disable|clear <name>
/codex project chain <name> <target...>  override a global chain's targets for this project
/codex project chain enable|disable|clear <name>
/codex project show           effective (global + project) config

days <spec> accepts everyday | weekdays | weekend | sun,mon,... | mon-fri ranges; roles pairs a member with primary|backup (backups are used when no primary is eligible). ref/target matches an account by label, credential id (openai-codex, openai-codex-2), or id. Pool strategies: round-robin (rotate to the next eligible member), quota-first (healthiest member by quota headroom, live check on use), scheduled (time/day windows with primary/backup roles), and custom (shell selector fed the eligible members on stdin). Chains define ordered fallback targets across pools and accounts; presets pin a named pool + optional model prefix; project overrides apply only in trusted projects (stored in .pi/beautiful-pi.json).

ref matches an account by label, credential id (openai-codex, openai-codex-2), or id. Adding an account registers its provider with Pi's /login, so /login openai-codex-2 starts the normal OAuth flow; /logout openai-codex-2 removes that credential. Accounts are stored under the accounts key of ~/.pi/agent/beautiful-pi.json; a trusted project can restrict which accounts are usable via allowedCredentialIds in .pi/beautiful-pi.json.

Legacy pi-multi-pass configuration (global ~/.pi/agent/multi-pass.json and project .pi/multi-pass.json) migrates automatically on session start: valid Codex subscriptions become accounts and project allowedSubs becomes allowedCredentialIds. A backup (*.bak-<timestamp>) is created before the legacy file is renamed to *.migrated; migration is safe to rerun and skips malformed or unknown entries without touching valid account configuration.

Pools and rate-limit failover

Pools group accounts for round-robin routing and automatic failover. A pool rotates through eligible members (authenticated, not cooling down, allowed in this project); /codex pool use <name> activates the pool's next eligible member and advances the rotation pointer. Membership is ordered — the order given at create/add is the rotation order.

When a request fails with a Codex rate limit or quota error and the active account is a member of an enabled pool, beautiful-pi marks that account as attempted (per request) and cooling down (default 60s, per pool), switches to the pool's next eligible member, and re-sends the interrupted request. Each account is attempted at most once per request; when every member has been attempted the original error stands. Non-rate-limit failures never trigger failover. Cooldowns and the per-request replay state live in memory and reset when Pi restarts.

Pi's own auth commands still work for a single account:

/login openai-codex       configure or refresh Codex OAuth
/logout                   remove credentials saved by /login

For scripts or external clients, print the configured OAuth bearer token without starting a session:

pi auth print-bearer-token --provider openai-codex --model gpt-5.5

pi auth reads stored credentials and never accepts them as command-line input. Use pi auth --help for the exact command surface.

Codex native remote compaction is enabled for the base openai-codex provider and managed accounts (openai-codex-N). The account adapter preserves account-specific checkpoint identity and credentials; switching accounts with a checkpoint from another account fails closed. Compaction uses the Codex Responses API, keeps its opaque checkpoint in Pi's native compaction entry, and fails closed if the remote request fails. On supported Pi versions (1.2.0–1.2.x), Pi controls when compaction runs: configure compaction.reserveTokens in ~/.pi/agent/settings.json or project-local .pi/settings.json. Pi triggers when used tokens exceed contextWindow - reserveTokens; default reserve is 16,384 tokens. For a 272k-token model, default trigger is near 94% used. To trigger near 30% used, set a model override with reserveTokens: 190400 (70% of 272k).

~/.pi/agent/pi-codex-compaction.json and project-local .pi/pi-codex-compaction.json (autoCompact / thresholdRatio) apply only to the upstream engine's fallback for Pi versions older than 0.84.4, outside b-pi's supported range. Other providers follow Pi's normal lifecycle.

pi-blackhole@0.5.12 includes the provider-aware skip capability. Compaction engine selection is coordinated automatically: Codex models use native Codex compaction (opaque checkpoints preserved), every other model uses Blackhole, exactly one engine acts per turn, and the selection is independent of extension registration order. On session start the coordinator appends "skipForProviders": ["openai-codex"] to ~/.pi/agent/pi-blackhole/pi-blackhole-config.json, so Blackhole steps aside for Codex sessions (no compaction, no observational-memory consolidation). Managed account models are projected to this provider for Blackhole's skip check; its compact hook also steps aside directly. A project-local skipForProviders list or the PI_BLACKHOLE_SKIP_PROVIDERS environment variable overrides the global list; the coordinator warns when either override omits a compatible openai-codex entry. Entries may be bare providers or provider:api pairs. It also warns if the installed Blackhole lacks the capability. The /blackhole-memory and /blackhole-recall commands remain available when Blackhole is loaded.

Configuration entry points

Path or command Purpose
~/.pi/agent/settings.json or .pi/settings.json Pi settings, theme, and compaction threshold (compaction.reserveTokens)
~/.pi/agent/beautiful-pi.json beautiful-pi feature and rail overrides
~/.pi/agent/pi-codex-compaction.json Codex fallback config for Pi <0.84.4 only
.pi/pi-codex-compaction.json Project fallback config for Pi <0.84.4 only
~/.pi/agent/pi-blackhole/pi-blackhole-config.json Blackhole compaction and memory
/beautiful-pi or /bpi Open beautiful-pi settings TUI
/reload Reload package resources after config changes

Features

Animated startup banner

banner-animation

On session start, beautiful-pi displays a fullscreen banner with:

  • Left column: Large π ASCII art with per-character fade-in animation, plus agent info card (Pi version, b-pi version, model, active theme).
  • Right column: Resource listing — all loaded extensions, skills, and themes.

The banner auto-hides on first input.

Toggle: showBanner setting (default: on).


Status footer

status-footer

A two-line widget that replaces the default pi footer:

Above the editor — stats bar

Shows model, thinking level (off, minimal, low, medium, high, xhigh, or max), context usage (bar + percentage) and the session title. Unknown future levels are shown verbatim.

Below the editor — cwd + git state + quota

  • Current directory (with ~ for home, smart truncation)
  • Git branch, ahead/behind, staged/modified/untracked counts
  • OpenAI Codex rate-limit usage (5h + 7d windows) — shown when using an OpenAI Codex model
  • OpenCode Go subscription usage (5h, 7d, 30d tiers) — shown when using an OpenCode Go model, fetched from the Zen /zen/go/v1/usage API with the provider key already configured in pi
  • Usage pace view: press Ctrl+Alt+U, or click the usage segment in fullscreen TUI, to replace percentages/reset times with 12-cell pace bars. ━ marks consumed quota (accent; warning over pace, error when exhausted), ┄ the dim remaining quota and · the ideal linear limit for now (accent).

Toggle: showFooter setting (default: on).


Rail-styled chat messages

All message types render with a consistent left rail (┃) and controlled indentation:

Agent messages

  • Text blocks: no left rail, clean background (or default terminal bg)
  • Thinking blocks: coloured ┃ rail with italic content (colour controlled by thinkingRailColor setting)
  • Error/stop reasons: shown in error colour

User messages

  • Coloured ┃ rail on the left (colour controlled by userRailColor setting)

Tool execution

When toolsOneLine is enabled (on by default), each tool call renders as a single compact line:

    ┃ spinner  cmd — npm install express
    ┃ ✓        Read  ~/config/app.ts:10–30
    ┃ ✓        Grep  "middleware"  src/  (*.ts)
    ┃ ✓        Edit  ~/config/app.ts
  • Spinning dots during execution (disappears when done)
  • Green ✓ on success, red ✕ on error
  • Colour and dimness controlled by toolRailColor and dimToolsText settings
  • Unregistered tools (MCP, web search, etc.) get the same treatment via a generic patch

Custom messages (web search results, skill output, etc.)

    ┃ Web Search Results
    ┃ Title: Finding the answer
    ┃ URL: https://example.com

Colour controlled by customMessageRailColor and dimCustomMessages settings.


Session auto-title

On first user input in a new session, beautiful-pi sends a lightweight LLM call to generate a concise emoji title (e.g. ✨ Add dark mode toggle). The title appears in:

  • The session selector sidebar
  • The terminal tab title
  • The stats bar (above editor)

Falls back to simple truncation if the LLM call fails. The feature is configurable via sessionTitle setting (default: on).


/bpi settings command

/bpi opens a TUI settings panel where you can toggle all features and pick rail colours. /beautiful-pi is retained as an alias:

╭───  beautiful-pi settings ────────────────────────────────╮
│                                                           │
│  > Banner                        on                       │
│    Footer                        on                       │
│    Session title                 on                       │
│    Tools one-line                on                       │
│    Indent level                  4                        │
│                                                           │
│    Agent rail color              accent                   │
│    User rail color               mdLink                   │
│    Thinking rail color           mdHeading                │
│    Dim thinking text             on                       │
│    Tools rail color              success                  │
│    Dim tools text                on                       │
│    Custom rail color             borderMuted              │
│    Dim custom messages           on                       │
│                                                           │
╰──  ↑↓ navigate  Space/Enter change  Esc close  ───────────╯

Changes persist to ~/.pi/agent/beautiful-pi.json. Run /reload after changing toggles or colours.


Editor border

The editor gets a custom border treatment:

  • Content lines prefixed with ❯
  • Bottom border shows a session timer in the right corner:
    └────────────────────────────────────────────────────────── ◷ 42m ─┘
    
  • The top border is removed so the stats bar merges seamlessly into the editor

Settings reference

All settings are stored in ~/.pi/agent/beautiful-pi.json. Only values that differ from defaults are persisted. Delete the file to reset everything.

Setting Type Default Description
showBanner boolean true Show animated startup banner
showFooter boolean true Show stats bar + footer
sessionTitle boolean true Auto-generate session titles
toolsOneLine boolean true Compact one-line tool output
indentLevel integer 4 Rail indentation (spaces)
agentRailColor string "accent" Agent thinking rail colour token
userRailColor string "mdLink" User message rail colour token
thinkingRailColor string "mdHeading" Thinking block rail colour token
thinkingTextColor string "muted" Thinking text colour token
dimThinkingText boolean true Dim thinking text
toolRailColor string "success" Tool execution rail colour token
dimToolsText boolean true Dim completed tool labels
customMessageRailColor string "borderMuted" Custom message rail colour token
dimCustomMessages boolean true Dim custom message text

Colour tokens reference the active theme's semantic colour map. Available tokens: accent, border, borderAccent, borderMuted, muted, dim, text, thinkingText, success, error, warning, syntaxKeyword, syntaxFunction, syntaxString, syntaxType, mdHeading, mdLink, mdCode, customMessageLabel, toolTitle.


Publishing

Use package.json as the b-pi version source. For each release, choose a SemVer bump, move Unreleased entries in CHANGELOG.md to a dated version section, and create an annotated v<version> tag after the release commit. Never reuse or move an existing release tag.

Run release checks before publishing:

pnpm typecheck     # TypeScript checks
pnpm test          # complete automated suite
pnpm pack:check    # inspect tarball contents

The tarball must contain runtime extensions, assets, README, license, CHANGELOG.md, and THIRD-PARTY-NOTICES.md; it must not depend on a bundled node_modules/ directory. Run pnpm smoke to verify a clean install: it packs the tarball, installs it into a fresh temporary agent directory (resolving every exact dependency, including the official pi-blackhole release), asserts every manifest path resolves, and boots the pi CLI the install resolved twice — once in print mode (reaching the auth stage "No API key found" is the success signal) and once in TUI-capable mode under a PTY, where the banner must render with no extension load errors and the passed model visible. The smoke test also exercises the compaction coordination at runtime: the coordinator must write skipForProviders into the clean agent dir, and both installed engines are driven through real compaction events to prove one-engine-per-turn — native Codex compaction for Codex sessions (blackhole steps aside) and blackhole for other providers. It repeats the check after moving the pinned engines to package-local node_modules and simulating stale versions in the shared npm directory, including a real Pi load. The smoke test needs network access to the npm registry plus script (util-linux) and tsx on the host; it requires no OAuth, Codex, or quota credentials — provider requests are not part of release verification.

pnpm publish --access public  # requires npm account with 2FA

After npm publication, submit the package to the pi.dev gallery using the npm package name and the public image URL declared in the package manifest. The gallery automatically detects pi-package keyword packages.


Extension architecture

extensions/
├── index.ts                    # Entry point — wires all extensions
├── shared/
│   ├── icons.ts                # Nerd Fonts detection, icon sets, strWidth()
│   └── settings.ts             # Settings loader, safe colour helpers, tests
├── settings/
│   └── index.ts                # `/bpi` + `/beautiful-pi` settings commands
├── codex-accounts/
│   └── index.ts                # `/codex` accounts, pools, chains and failover
├── compaction/
│   ├── index.ts                # Provider-aware compaction entry point
│   ├── coordinator.ts          # Codex/Blackhole engine coordination
│   ├── codex-engine.ts         # Load pinned Codex compaction dependency
│   └── blackhole-engine.ts     # Load pinned Blackhole dependency
├── herdr-pane-sync/
│   └── index.ts                # Optional Herdr pane-label synchronisation
├── banner/
│   └── index.ts                # Startup banner (aboveEditor header)
├── footer/
│   ├── index.ts                # Stats bar + footer widgets
│   ├── box-editor.ts           # Custom editor with ❯ prefix + timer
│   └── openai-usage.ts         # OpenAI Codex quota fetcher/parser
│   └── opencode-go-usage.ts    # OpenCode Go quota fetcher/parser
├── assistant-style/
│   └── index.ts                # Agent message rail style
├── user-style/
│   └── index.ts                # User message rail style
├── custom-message/
│   └── index.ts                # Custom message rail style
├── session-title/
│   └── index.ts                # Auto-title generation
└── tools-one-line/
    ├── index.ts                # Tools wire-up
    ├── shared.ts               # OneLine component, spinner, registerTool helpers
    ├── register-bash.ts        # Bash tool label
    ├── register-read.ts        # Read tool label
    ├── register-write.ts       # Write tool label
    ├── register-edit.ts        # Edit tool label
    ├── register-grep.ts        # Grep tool label
    ├── register-find.ts        # Find tool label
    ├── register-ls.ts          # Ls tool label
    └── register-generic.ts     # Generic tool rail patch (MCP, unregistered tools)

Security

This project includes a pre-commit hook that scans staged changes for secrets using gitleaks. Set it up:

git config core.hooksPath .githooks

You can also run it manually:

pnpm gitleaks:scan     # full repo scan
pnpm gitleaks:staged   # scan staged changes only

Development

See CONTRIBUTING.md for workflow, conventions, and contribution guidelines.

License

MIT — see LICENSE.

About

Beautiful UI extensions for pi — footer, banner, themes, Nerd Fonts support

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages