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

pi-king

v0.3.0

Published

tmux-backed session manager and supervisor for the Pi coding agent — background a session and come back to it later

Readme

⢦⡀⠀⠀⠀⣀⠀⠀⠀⢀⡴
⠈⢷⣄⣴⣿⣿⣿⣦⣠⡾⠁
⠀⣨⣿⣿⣿⣿⣿⣿⣿⣅
⠀⠉⢹⣿⠉⠉⠉⣿⡏⠉
⠀⠀⢸⣿⠀⠀⠀⣿⡇
⠀⠀⠘⠛⠀⠀⠀⠛⠛⠂

pi-king

Background a Pi session and come back to it later.

A tmux-backed session manager and supervisor for the Pi coding agent — a local control plane for long-running sessions. Hand a session to tmux with /bg, see every session on the machine in one dashboard, and reattach to any of them with a keypress.

npm license


Requirements

tmux is required. Persistence is tmux — pi-king does not implement its own process supervision, it hands the session to tmux and keeps track of what it handed over. Without tmux the dashboard still opens and the extension still loads, but there is nothing to background and nothing to reattach to.

brew install tmux          # macOS
sudo apt install tmux      # Debian/Ubuntu

Also needs Node (whatever Pi itself requires) and a terminal that Pi can drive.

Demo

pi-king demo

Three sessions in three projects are backgrounded with /bg, listed together in the dashboard, and one is reattached with its history intact — the same process, not a replay of its transcript.

1. Background a session

/bg hands the session to tmux and frees the terminal. History goes with it.

backgrounding a session

2. See everything still running

Grouped by project, with live state and elapsed time. The metrics band and inventory panels appear only when there is something to show.

the dashboard

3. Reattach with history intact

The session answers from its own context — the same process, resumed, not a transcript replayed into a new one.

reattaching

Recorded in a throwaway environment built by tools/demo-env.sh: placeholder skills and prompts, synthetic call logs, and a provider under a neutral name. A recording holds every panel on screen for its full length, so without that it would document the author's machine rather than this tool. Reproduce with tools/record-demo.sh.

The problem

You cannot currently background a Pi session and reattach to the running process later.

That is a capability gap, not a preference:

  • /resume browses session transcripts and can list sessions from every project — but it starts a new process against old history. The original is gone: in-memory state, running subagents, and the live agent loop with it.
  • A long-running session is therefore trapped in the terminal tab that spawned it. Close the tab and the work dies. Walk away and you lose track of what is still running.

What pi-king does

  • Persistence. Sessions run inside tmux. Detach and the session keeps working headless; reattach later and you are back in the same process.
  • Supervision. A live TUI listing every opted-in session across every project — state, what it is doing, and its background subagents.
  • Lifecycle. Create, rename, and delete sessions from the TUI.
  • Honest liveness. Sessions are verified by process identity. A crashed session disappears rather than lying about its state.

The loop is: dashboard → attach → work → detach → dashboard.

Credit

pi-king is heavily inspired by Claude Code's Agent View, which made the case that when you run several agents, the supervisory view is a first-class surface rather than an afterthought.

The difference is scope. Agent View — and Pi's closest equivalent, pi-subagents' FleetView — are session-scoped: they show the subagents inside one session. pi-king is process-scoped: it supervises whole Pi sessions across every project on the machine, and can put you back inside one.

Install

pi install git:github.com/stanleytejakusuma/pi-king

That gives you /bg, session tracking, and the /pi-dashboard command. Inside tmux, selecting a session in the dashboard switches to it directly.

Outside tmux, attaching needs a process that can take over the terminal after Pi exits, which an extension cannot do from inside a running session. Install the launcher for that:

npm i -g pi-king   # provides the `pi-king` command
pi-king            # opens the dashboard, owns the attach loop

pi-agents is installed as an alias for the same launcher.

The launcher starts Pi with only pi-king's extension loaded. It lists sessions and hands the terminal to tmux; it never calls a model, so loading the rest of your setup is startup cost for nothing. Sessions you start from it are separate processes and load your full configuration as normal.

Why two steps. They install different things. pi install registers the extension inside Pi, which is what gives you /bg, session tracking and the /pi-dashboard command; it does not put anything on your PATH. The npm global install provides the pi-king launcher, a standalone process that owns the terminal while tmux has it. You need the launcher only for attaching from outside tmux. Inside tmux, the extension alone is enough.

Requires tmux for persistence. Without it, pi-king still runs and lists sessions — it just cannot background them, and says so.

pi-king does not modify your Pi configuration. It never sets PI_CODING_AGENT_DIR, and sessions it spawns inherit your normal setup.

Recommended tmux settings

Pi negotiates the kitty keyboard protocol. Without these, modified keys (Shift+Enter and friends) misbehave inside tmux, and keystrokes can duplicate:

set -s extended-keys on
set -s extended-keys-format csi-u

Use

pi-king          # open the dashboard (installed as a bin by the package)

| Key | Action | |---|---| | | select | | enter / | attach (tmux-backed) or jump to its terminal tab | | n | new session | | e | rename | | j | offload-job panel (~/.pi/jobs markers): enter show JSON, r resume, c clear finished, x/X delete | | x x | delete (two presses) | | r | refresh | | esc | close |

Inside any Pi session:

/bg     # background this session into tmux and surface it on the dashboard

/bg is safe to run mid-turn: it queues and fires once the session settles, so an in-flight response and any running subagents finish normally rather than being killed.

Detach from an attached session with tmux's own Ctrl+B d.

Hub daemon (offload jobs + boot restore, 24/7)

The interactive dashboard exits when you attach into tmux, which used to kill marker watching with it (a job landing mid-attach went silent). The detached hub daemon owns marker polling, injection, the macOS banner, and session- window restore as a launchd KeepAlive agent — it never dies. The dashboard is a view of the same state, attachable on demand. Plain node process, not pi (no TUI to render, no model to call — the whole pi runtime was pure overhead; measured 0.00% CPU at rest, vs 3.57% for the pi-process version it replaced).

pi-king --daemon-install      # write plist + bootstrap com.stanz.pi-king-hub
pi-king --daemon-status       # launchd state + hub.log tail
pi-king --daemon-uninstall    # stop + remove
  • Exactly one injection per marker across daemon + dashboard + session-side pi-jobs watchers: first writer of ~/.pi/jobs/.injected/<hash>.json wins (wx claim, same hash identity as acks). Banner + panel always; injection once.
  • Owner-only targeting: a completion is delivered to the exact session that spawned the job (spawnerSessionId), and to nothing else. No owner on this dashboard (headless, exited, invisible) means no injection at all — the banner and the panel still surface it, and r in the owner session is the recovery path. cwd/resultPath/"most recent"/the cursor row are deliberately not fallbacks: relevance guesses caused repeated cross-session interruptions.
  • Never mid-turn: injection waits for the owner to finish its turn (and for its subagents to stop), the same rule every other send-keys path here follows, and holds off while a workflow run owns that project. Waiting burns no claim, so the report is delivered on a later tick, exactly once.
  • Idle is cheap: the daemon resolves the fleet (ps, tmux, git status) only when a marker actually needs an owner. With nothing to deliver, a tick is a readdir plus a stat per marker and forks nothing.
  • Boot restore: tmux start-server if down, then every visible card whose process is gone and whose window is missing gets a fresh window (the fleet recovery from the 2026-08-07 kill-server accident, automated). A session killed with X does come back — the card is the only tombstone-free record.
  • Log: ~/.pi/king/hub.log. Marker writer: ~/.pi/jobs/scripts/pi-jobs-run.sh.

Configuration

Everything is optional; unset means the corresponding panel is simply absent.

| Variable | Effect | |---|---| | PI_KING_CALL_LOGS | Directory of per-day call-log JSON. Unset means no metrics band. | | PI_KING_PIPELINE | Full command for the omniroute cost pipeline, fired fire-and-forget on each stats refresh (ingest + price TTL + export). Unset means costs update only when the export is refreshed by other means. | | PI_KING_CLIS | Comma-separated CLIs to report presence of. Defaults to common dev tools. | | PI_KING_STATUS_DIR | Overrides the session-status directory. Testing only. |

Design notes

Longer reasoning in docs/SPEC.md. The short version:

  • Explicit opt-in. A session appears only if pi-king spawned it or you ran /bg. Being alive is not enough.
  • No fabricated numbers. No progress bars — Pi exposes no completion percentage, so a bar would be invented. Missing data renders as nothing, never as a zero implying a measurement.
  • Liveness is identity, not existence. A pid alone proves only that some process holds it; abruptly-killed sessions leave files behind and the OS recycles pids onto other live Pi sessions. Process start times are compared.
  • Standalone. Stock Pi and the Node standard library only. Subagent rollup is feature-detected.

Docs

The wordmark is generated, not a magic constant: python3 tools/braille-art.py 11.

Updating

/reload inside a running session re-imports extensions, skills, and prompts from disk (it clears Pi's module cache). What it does not do is re-run startup-only registration: pi.registerProvider() calls, the scoped model list, and OmniRoute routing are all bound once at process start and a reload leaves them unchanged. For those changes the dashboard's r key performs a full restart of every affected session — tmux respawn-pane replaces the Pi process in place with pi --session <same-id>, so the transcript history survives while the new process picks up the new providers. Busy sessions are queued and restart automatically once they settle.

Knowing when to come back

Backgrounding a session is half the tool; the other half is finding out what happened while you were gone.

  • A session that finishes a turn while detached is marked attention and sorts to the top, showing Done: <the prompt that finished>. It stays marked until you attach — reading the result is the acknowledgement, no keypress required.
  • A tool call waiting on an approval dialog shows as trust with the tool named. Without this, a session blocked on a permission prompt looks exactly like one that is working.
  • Provider failures and failed tools show as error with the reason.
  • On macOS, each of these also raises a desktop notification — but only while the session is detached. If you are watching, it stays quiet. Notifications use osascript; no dependency is added, and on other platforms they are simply absent.

Inside a tmux-hosted session, left-arrow at an empty prompt detaches back to the dashboard — gated exactly like a fleet-list activator, so it never touches cursor movement while you are typing. Ctrl+B d still works everywhere, unconditionally.

Idle rows show the session's last reply — the closing line of its most recent answer, read from the transcript itself, so it works even for sessions started before pi-king was installed. Each row also carries its context usage (ctx 72%, colour turning as compaction approaches) and each project header shows uncommitted-change counts, because a returning user's second question after "what did it do" is "did it leave work uncommitted".

Ctrl+T pins the selected session: pinned sessions leave their directory group and sit in one section at the top, keeping their project name on the row. Shift+Up / Shift+Down moves a session within its own section — its project group, or the pinned section. A row will not cross a boundary, because doing so would silently change what it means; pinning is what moves a session between sections. Both are remembered in ~/.pi/king/layout.json and survive restarts. The dashboard owns that file: pins are a view preference, and writing them into the session status files would put two processes on one file.

Sessions are never deleted by the dashboard. A session whose process has ended shows as exited, and enter resumes its transcript in place, in its directory. X on an exited card removes the card alone; the transcript is Pi's and survives regardless.

Limitations

Stated plainly rather than discovered later:

  • macOS only, in practice.

    | | | |---|---| | macOS | developed and tested here | | Linux | should work — tmux is located at runtime, not assumed — but never verified | | Windows | unsupported; the launcher is a POSIX shell script, so WSL at best |

  • Jump-to-tab for non-tmux sessions is macOS + Ghostty only. Feature-detected, and degrades to a message pointing at /bg.

  • The no-tmux path is untested. It is written and it degrades deliberately, but that branch has never actually fired in anger.

  • The first launch is noisier than later ones. The launcher runs Pi from a small directory of its own that carries quietStartup and a model list the hub will never call. Pi applies a directory's settings only once that directory is trusted, so on the very first run those are ignored: expect normal startup output, and one warning per model pattern your global config enables but the hub does not load. It settles by itself once the directory is trusted. Nothing is broken and the dashboard behaves identically either way.

  • Two dashboards at once is undefined. Nothing coordinates two supervisors reading and pruning the same status directory. One at a time.

  • A crash between spawning and verifying a handoff can strand a session. /bg verifies the new tmux session exists before retiring the old process, but a kill in that window leaves a session running that nothing is tracking. It is still reachable with tmux attach.

  • Attaching outside tmux needs the launcher. A process cannot hand its controlling terminal to a child without both fighting for stdin, so the extension alone can only tell you the command to run. Inside tmux this does not apply.

  • Stats are optional and format-specific. The metrics band reads a call-log layout that no stock Pi install writes. Unset PI_KING_CALL_LOGS means no band, which is the intended default.

AI disclosure

Substantially written with AI assistance, then reviewed, tested, and debugged by hand. Several designs here exist because a naive version failed in practice: docs/SPEC.md records what broke and why the current shape was chosen. Issues and corrections welcome.

License

MIT