npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@heyhuynhgiabuu/pi-pretty

v0.6.29

Published

Pretty terminal output for pi — syntax-highlighted file reads, colored bash output, tree-view directory listings, and more.

Downloads

9,375

Readme

pi-pretty

npm version GitHub release

A pi extension that upgrades built-in tool output in the terminal and includes built-in FFF-powered search for find/grep.

Tool result bodies start collapsed (header + line count) and retain a blank row below their output. Use Pi Ctrl+O (app.tools.expand) on a tool block to show full output; Ctrl+Shift+O expands all. See Pi keybindings.

It currently enhances:

  • user messages: a prompt icon using userMessageText; live input follows the active thinking-level color for its icon
  • read: syntax-highlighted text previews with line numbers, read docs labels for Pi documentation reads, plus inline image rendering when the terminal supports it
  • bash: colored exit summary (exit 0/exit 1) with a preview body of command output
  • ls: Nerd Font file icons with tree-oriented rendering
  • find / grep: built-in FFF-backed search with frecency-aware results, plus grouped/highlighted rendering
  • working indicator: an oh-my-pi-style shimmer sweep in the input's top-border Working… row — flush-left, rotating phrases, per-session accent tint (see Working indicator)
  • thinking label: the hidden-thinking Thinking... label gets the same shimmer treatment (see Thinking label)

Companion to @heyhuynhgiabuu/pi-diff for write/edit diff rendering.

Install

pi install npm:@heyhuynhgiabuu/pi-pretty

Latest release: https://github.com/buddingnewinsights/pi-pretty/releases/latest

Or load locally:

pi -e ./src/index.ts

Screenshots

Bash and read rendering bash exit summary + output preview, and syntax-highlighted read text output.

Icons and grep rendering ls/find/grep with Nerd Font icons and grouped/tree-oriented rendering.

Inline image rendering read rendering an image inline in supported terminals.

Terminal support for inline images

Inline image previews are supported in Ghostty, Kitty, iTerm2, and WezTerm.
When running in tmux, pi-pretty uses passthrough escape sequences.

tmux must allow passthrough. Enable it with:

set -g allow-passthrough on

(or run once in a session: tmux set -g allow-passthrough on)

Bundled FFF search

pi-pretty now bundles @ff-labs/fff-node and owns the built-in find / grep search behavior directly.

If you use bundled FFF mode, do not load pi-fff at the same time, because Pi extensions do not compositionally share ownership of the same built-in tool names.

FFF data is stored under a pi-pretty-specific path:

~/.pi/agent/pi-pretty/fff/

This makes it clear that the cache belongs to this extension rather than Pi core.

How to use it

1. Install and load only pi-pretty

pi install npm:@heyhuynhgiabuu/pi-pretty

Do not also load pi-fff in the same Pi setup.

2. Start Pi in a project

cd /path/to/your/project
pi

On session start, pi-pretty initializes the bundled FFF index for the current working directory.

3. Use the built-in tools normally

You keep using the normal built-in tool names — pi-pretty owns them directly.

Examples:

find pattern="*.ts" path="src"
grep pattern="handleRequest" glob="*.ts"
read path="src/index.ts"
ls path="src"

4. Check FFF status or force a rescan

pi-pretty also provides two maintenance commands:

/fff-health
/fff-rescan

Use them when:

  • you want to confirm indexing is active
  • the session started with a partial index warning
  • you made large filesystem changes and want a fresh scan

Notes

  • find results are frecency-aware, so files you touch more often can bubble up earlier.
  • grep can show a cursor notice when more results are available.
  • If you see a partial index warning, let the session settle or run /fff-rescan.
  • When Pi starts in the exact home directory or filesystem root, FFF stays disabled by default and find/grep use Pi's SDK fallback instead of interrupting startup. Broader indexing requires explicit opt-in below.

To opt into home or root indexing for a session:

PRETTY_FFF_HOME_SCAN=1 pi
PRETTY_FFF_ROOT_SCAN=1 pi

The equivalent Pi flags are --pretty-fff-home-scan and --pretty-fff-root-scan. Root scanning is intentionally never enabled by default because it can watch a very large filesystem and expose unrelated files to the agent.

Configuration

Config file: ~/.pi/agent/pi-pretty.json

Place a JSON file alongside Pi's settings.json to customize pi-pretty. Every option can also be set via environment variables, which take precedence over the config file: env var > pi-pretty.json > built-in default (the theme additionally falls back to ~/.pi/agent/settings.json's theme before the default).

{
	"background": {
		"tool": "#1e1e2e",
		"error": "#2a1e1e"
	},
	"theme": "github-dark",
	"icons": "nerd",
	"enableTools": ["ls"],
	"disableTools": ["grep"],
	"maxHlChars": 80000,
	"maxPreviewLines": 80,
	"cacheLimit": 128,
	"fff": {
		"enableHomeScanning": false,
		"enableRootScanning": false
	},
	"workingIndicator": {
		"text": ["Working…", "Thinking…"]
	}
}

| Key | Type | Env var override | Default | | --- | --- | --- | --- | | background.tool | hex color | — | terminal default | | background.error | hex color | — | background.tool | | theme | Shiki theme name | PRETTY_THEME | github-dark (after pi-pretty.json theme, then ~/.pi/agent/settings.json theme, when valid Shiki themes) | | icons | nerd | none (or off) | PRETTY_ICONS | nerd | | enableTools | string array | PRETTY_ENABLE_TOOLS | [] (ls is opt-in) | | disableTools | string array | PRETTY_DISABLE_TOOLS | [] | | maxHlChars | positive int | PRETTY_MAX_HL_CHARS | 80000 | | maxPreviewLines | positive int | PRETTY_MAX_PREVIEW_LINES | 80 | | cacheLimit | positive int | PRETTY_CACHE_LIMIT | 128 | | fff.enableHomeScanning | boolean | PRETTY_FFF_HOME_SCAN (1/0) | false | | fff.enableRootScanning | boolean | PRETTY_FFF_ROOT_SCAN (1/0) | false | | workingIndicator.enabled | boolean | PRETTY_WORKING_INDICATOR (on/off) | true | | workingIndicator.text | string or string[] (phrases rotated per sweep; env accepts comma-separated) | PRETTY_WORKING_INDICATOR_TEXT | ["Working…"] | | workingIndicator.mode | shimmer | kitt | static | PRETTY_WORKING_INDICATOR_MODE | shimmer | | workingIndicator.low | theme color name or #hex | — | dim | | workingIndicator.mid | theme color name or #hex | — | muted | | workingIndicator.high | theme color name or #hex | — | accent | | workingIndicator.bold | boolean | — | true | | workingIndicator.hint | boolean | — | deprecated (ignored) | | workingIndicator.sessionAccent | boolean | — | true | | thinkingIndicator.enabled | boolean | PRETTY_THINKING_INDICATOR (on/off) | true |

  • Config values take priority over theme-provided backgrounds (toolBg / toolErrorBg).
  • Precedence for FFF scan scope is CLI flag > environment variable > pi-pretty.json > safe default (false).
  • All options except background.* are read once at startup; restart pi to apply changes to them (background.* applies live).
  • To override the config directory, set PRETTY_CONFIG_DIR env var.

Working indicator (shimmer)

While the agent streams, pi-pretty replaces pi's static Working... row with an oh-my-pi-style shimmer: a bright accent band sweeps across the text at 30 cells/second over a dim braille spinner, rendered flush-left in Pi's embedded working-status row at the top border of the input. The custom row contains only the spinner and shimmer text; it does not append Pi's interrupt hint or token-count status. On hosts that provide Pi's embedded working-status API, pi-pretty supplies its custom frames to that row; older hosts fall back to a zero-padding widget above the editor. Mode kitt swaps the sweep for a ping-ponging scanner head with a decay trail; static renders a single unanimated frame. Tier colors resolve #rrggbb hex first, then the active pi theme color name, then built-in fallbacks. Set workingIndicator.enabled: false (or PRETTY_WORKING_INDICATOR=off) to restore pi's default indicator. TUI sessions only; theme changes take effect on the next session.

text accepts a single phrase or an array — the sweep plays each phrase in order, one full band sweep per phrase (e.g. ["Working…", "Thinking…", "Pondering…"]). The env var splits on commas.

When sessionAccent is on, the mid/high tiers and the spinner are tinted with a stable per-session accent color derived from the session name (an OKLCH port of oh-my-pi's session accent) — different windows get different hues at uniform perceived brightness. Renaming the session re-tints the indicator live. Explicit workingIndicator.mid/high colors disable the tint.

Thinking label (shimmer)

With thinking blocks hidden (pi's hideThinkingBlock setting), the label shows elapsed reasoning time (Thinking... 12s) under the same shimmer: italic thinkingText base with the accent band (and the session accent tint) sweeping through it. Both the active and completed labels have one leading space for consistent output alignment. On the first text or tool delta it freezes as Thought for 12s. Durations below one second use milliseconds (250ms instead of 0s); longer durations retain compact whole-second units (12s, 1m 05s, 1h 02m 03s).

Each row keeps its own label: pi-pretty intercepts the host's per-row label fan-out (AssistantMessageComponent.prototype.setHiddenThinkingLabel), so the streaming row animates while completed rows stay frozen at their own Thought for 12s instead of every row mirroring the latest write. Durations live for the current session (they are not persisted across restarts). A message with several thinking runs (interleaved thinking → text → thinking, common on Gemini) shares one label line per run, so those runs accumulate a single per-message total — a later run resumes the count instead of rewinding to zero. If the host class is missing or reshaped, the intercept falls back to pi's global-label behavior — including restoring the default Thinking... at message end so older rows are never mislabeled. The 30fps ticker runs only while the current message's last block is thinking, bounding the cost of setHiddenThinkingLabel(label) rebuilding chat children. Inherits mode, bold, and the palette/accent from workingIndicator.

Environment variables

Optional environment variables:

  • PRETTY_THEME (overrides pi-pretty.json theme, which overrides ~/.pi/agent/settings.json theme; otherwise pi-pretty falls back to that setting before github-dark)
  • PRETTY_CONFIG_DIR — directory to read pi-pretty.json from (default: ~/.pi/agent/)
  • PRETTY_MAX_HL_CHARS (default: 80000)
  • PRETTY_MAX_PREVIEW_LINES (default: 80)
  • PRETTY_CACHE_LIMIT (default: 128)
  • PRETTY_ICONS (nerd by default, set to none to disable icons)
  • PRETTY_WORKING_INDICATOR (on/off, overrides workingIndicator.enabled)
  • PRETTY_WORKING_INDICATOR_MODE (shimmer/kitt/static)
  • PRETTY_WORKING_INDICATOR_TEXT (indicator label)
  • PRETTY_DISABLE_TOOLS — comma-separated list of tool names to skip during registration (e.g. read,grep). Explicit disables take precedence over enabled defaults.
  • PRETTY_ENABLE_TOOLS — comma-separated list of opt-in tools. ls is disabled by default; set PRETTY_ENABLE_TOOLS=ls to register it.

Development

Future pi-pretty custom-tool renderers should use customToolTitle(name) from src/tools/labels.ts; it returns ⚙ <name>. Built-in tool replacements keep their own labels.

npm install
npm run typecheck
npm run lint
npm test

License

MIT — huynhgiabuu