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

@miclivs/pi-shot

v0.1.1

Published

Beautiful pi session screenshots. Render any pi session as a PNG.

Readme

pi-shot

Capture the live pi TUI as a pixel-perfect PNG. Compose synthetic conversations from CLI flags, drive real slash commands, load existing sessions, swap themes — whatever you need to make the screenshot you want.

hero

Why

pi is a terminal-first AI coding agent and its TUI does a lot of work (syntax-highlighted reads, real diffs on edits, colored bash backgrounds, custom extension messages, theme support). Most screenshot tools either:

  • snapshot a static frozen frame and lose all the live behavior, or
  • run the real terminal and inherit your font/theme/window chrome.

pi-shot drives a real headless pi instance inside node-pty + @xterm/headless, walks the buffer cell-by-cell, and renders the result through HTML + Playwright. The output uses pi's actual ANSI colors, the actual theme JSON, and a clean macOS-style window frame. The image is auto-trimmed to fit the content so there's no dead space below the conversation.

Install

npm install -g @miclivs/pi-shot

You also need pi itself installed and on your PATH:

npm install -g @mariozechner/pi-coding-agent

Quick start

# render a synthetic two-turn chat with a bash tool call
pi-shot \
  --no-banner --pi-arg --offline \
  -m "user:list files" \
  -m "bash:ls -la:total 12\ndrwxr-xr-x  3 user staff  96 ." \
  -m "assistant:Three files." \
  -o chat.png
# capture an existing pi session as-is
pi-shot --session ~/.pi/agent/sessions/proj/abc.jsonl -o session.png
# pre-fill the editor box with a half-typed prompt
pi-shot --prompt "add tests for the auth flow" -o prompt.png
# drive an extension's slash command live
pi-shot --no-banner --keys "/psst-set" --keys "\r" -o ext.png

Examples

The examples/ folder has 15 self-contained scripts covering every feature. Each one writes a numbered PNG next to itself. Run any of them individually, or bash run-all.sh to generate them all.

| File | Shows | |---|---| | 01-empty.sh | Empty pi at rest | | 02-simple-chat.sh | A two-turn user/assistant chat | | 03-bash-tool.sh | A bash tool call with multi-line output | | 04-edit-tool.sh | An edit tool rendered as a real unified diff | | 05-all-tools.sh | Every tool kind in one shot: read, write, edit, bash, grep, find, ls | | 06-thinking.sh | An assistant turn with a thinking block | | 07-custom-message.sh | A custom-typed message of the kind extensions emit | | 08-prefilled-prompt.sh | The editor box pre-filled with text | | 09-slash-command.sh | The slash-command autocomplete popup | | 10-multi-step-keys.sh | Multiple --keys bursts driving a multi-step flow | | 11-real-session.sh | An existing pi session JSONL rendered as-is | | 12-light-theme.sh | The same conversation in pi's built-in light theme | | 13-custom-theme.sh | A custom theme JSON file applied to pi | | 14-with-extension.sh | An extension's slash command rendered live | | 15-pi-psst-end-to-end.sh | Full pi-psst story with a real LLM call |

Composing conversations

For quick captures, the -m "kind:body" shorthand covers everything:

user:<text>
assistant:<text>
thinking:<text>
bash:<command>:<output>
read:<path>:<content>
write:<path>:<content>
edit:<path>:<oldText>:<newText>
grep:<pattern>:<path>:<matches>
find:<pattern>:<path>:<results>
ls:<path>:<entries>
custom:<type>:<content>
model:<provider>:<model-id>
thinking_level:<off|minimal|low|medium|high|xhigh>

Use \n inside any field to insert a real newline.

For more complex flows (multi-content assistant turns, custom tool details), write a JSON file matching the ComposeMessage union and pass --compose file.json instead:

[
  { "kind": "user", "text": "hello" },
  { "kind": "assistant", "text": "hi", "thinking": "they greeted me" },
  { "kind": "bash", "command": "ls", "output": "file.txt" },
  { "kind": "edit", "path": "src/a.ts", "oldText": "foo", "newText": "bar" }
]

The compose builder uses pi's own typed SessionManager under the hood, so the resulting JSONL is guaranteed to match pi's real session schema.

Driving live pi

Anything you can type into pi, you can send via --keys. Each --keys flag is one keystroke burst, and pi-shot waits for pi to settle between bursts so multi-step flows work cleanly:

pi-shot \
  --no-banner \
  --keys "/psst-set DEMO_KEY sk-live-abc demo,prod\r" \
  --keys "echo the value of DEMO_KEY using bash\r" \
  --idle-ms 8000 \
  -o demo.png

Escape sequences supported: \r, \n, \t, \e, and \xHH.

Theming

# built-in light theme
pi-shot --theme light -o light.png

# any pi theme JSON file
pi-shot --theme my-theme.json -o custom.png

The theme JSON schema is documented in pi's own theme directory. pi-shot copies your real ~/.pi/agent dir into a private temp dir and layers the theme override on top, so all your packages, credentials, and model preferences still apply.

Output

pi-shot writes the output file path to stdout so you can pipe it:

convert "$(pi-shot -m 'user:hi' -o /tmp/x.png -q)" -resize 50% small.png

All status messages go to stderr. Use -q/--quiet to silence them entirely. NO_COLOR is honored.

Reference

USAGE
  pi-shot [INPUT] -o OUTPUT.png [OPTIONS]

INPUT (one of)
  --session <file>            open an existing pi session JSONL
  --compose <file>            load compose messages from a JSON array file
  -m, --message <kind:body>   compose a synthetic message (repeatable)

OUTPUT
  -o, --output <file>         output PNG path (required)

PROMPT BOX & DRIVING
  --prompt <text>             pre-fill the editor input box
  --keys <text>               send raw keystrokes (repeatable)
  --extension <path>          load a pi extension before capture (repeatable)

TERMINAL SIZE
  --cols <n>                  terminal columns (default: 120)
  --rows <n>                  terminal rows (default: 35)

CAPTURE TIMING
  --idle-ms <n>               ms of pty silence to consider pi idle (default: 2500)
  --step-timeout-ms <n>       hard timeout per message step (default: 30000)
  --delay <n>                 extra delay after final idle, before capture
  --capture <mode>            "viewport" (default) or "all" (full scrollback)

WINDOW CHROME
  --no-window                 disable the macOS-style window frame
  --padding <px>              padding inside the window (default: 20)
  --background <color>        window background color
  --border-radius <px>        window border radius (default: 8)

STARTUP CHROME
  --no-banner                 skip pi's startup overview (welcome banner,
                              [Context], [Extensions], [Skills], etc)

THEMING
  --theme <name|file>         pi theme: "dark", "light", or path to JSON
  --window-bg <color>         override the screen background only
  --font-family <css>         override the monospace font stack
  --font-size <px>            override font size (default: 14)
  --line-height <n>           override line-height multiplier (default: 1.15)

PI PASSTHROUGH
  --cwd <path>                working directory pi runs in
  --pi-arg <arg>              pass an extra argument to pi (repeatable)

GENERAL
  -q, --quiet                 suppress pi-shot's own status output
  -h, --help                  show full help
  --version                   print version

Run pi-shot --help for the complete reference with all message kinds and inline examples.

How it works

  1. PtyRunner spawns pi inside node-pty with COLORTERM=truecolor and feeds its output into an @xterm/headless Terminal instance.
  2. SessionBuilder uses pi's exported SessionManager to write a real session JSONL file from the compose messages, guaranteeing the shape pi expects.
  3. The runner waits for pi to go idle (no output for --idle-ms ms), then any --prompt is typed into the editor and any --keys bursts are sent.
  4. HtmlRenderer walks the xterm cell buffer, builds an HTML document with the exact ANSI colors pi emitted, integer-pixel row heights to avoid sub-pixel gaps in colored backgrounds, and auto-trims trailing empty rows.
  5. Playwright screenshots the HTML and writes the PNG.

The whole pipeline takes 5-10 seconds for a typical capture.

License

MIT