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

@perturbationai/pai

v0.2.0

Published

A phone-first build of pi-web.

Downloads

434

Readme

PAI

A phone-first build of pi-web.

pi-web runs the pi coding agent in a browser — sessions, files, git, skills, model configuration — and all of that is upstream's. What it did not have is a layout composed for a phone, and it carries a handful of defects that a phone runs into first. That is what this build changes, and nothing else.

npx @perturbationai/pai

It serves on 127.0.0.1:30141. Add it to your home screen and it runs standalone, with lock-screen notifications when a session finishes.

npx @perturbationai/pai --help          # ports, hostname, the PI_WEB_* environment

The environment variables are upstream's and unchanged — PI_WEB_PASSWORD, PI_WEB_ALLOWED_HOSTS, PI_WEB_HOSTNAME — so anything already configured against pi-web keeps working.

What is different from pi-web

Every change is listed below. The complete diff is one link: v0.9.1 → this build — the first commit in this repository is upstream v0.9.1 imported verbatim, so the comparison against it is exactly what PAI changes.

Fixed

Upstream defects rather than preferences. Each was reproduced before it was patched, and each is better sent upstream than carried here.

  • A new session did not survive being left. The workspace's last-open memory was not cleared, so the next load restored the session that was open before it. Loading a bare / ended at ?session=<the previous one>. It matters most on a phone, where a home-screen app is relaunched constantly.
  • The first tap on a session row only produced a hover state, revealing rename and delete under the finger, so opening the session took a second tap.
  • Hover painted into the inline style stuck after a touch. iOS fires mouseenter and often never mouseleave, so the tint stayed under the finger — including a blue flash on whichever control the session dialog opened beneath.
  • An expanded thinking block lost its collapse target, leaving a 14×17 icon as the only way back. It is 26×26 now, and 38×38 where the pointer is coarse.
  • The model button omitted its provider, although the dropdown already groups by provider and the same model id can exist under two of them.
  • A model that is no longer configured went on being named, which reads as a working selection. It now says "Select model".
  • The keyboard's height was read once, and WebKit reports a half-settled value on the resize event itself. Read again as it settles, and polled.
  • The home indicator's inset stayed reserved while the keyboard covered it.
  • A device kept the first build it ever cached. The service worker named its cache after the package version, which a patched build never moves. Each build gets its own.
  • /apple-touch-icon.png was a 404 — the path Safari falls back to when adding to the home screen, which is where a miss gets the generated letter tile instead of the mark.
  • A tap in the terminal does not raise the keyboard on iOS. iOS raises it when a focus lands inside a user gesture, and xterm focuses its hidden textarea as soon as the connection opens, long before a thumb arrives. Reproduced against stock v0.9.1.
  • A terminal in an installed iOS web app never connects. connect() returned on navigator.onLine in silence — no error, no retry. A home-screen web app reports itself offline while every other request on the page goes through.

Changed

Most are confined to a phone by a width or a pointer query. Three are not, and are how this build looks on a desktop as well: Send's ground, the process group's frame, and the model list's group headers.

  • The composer is one card, with its controls on a row above the text line and Stop coming out onto that row while a turn runs rather than staying inside a menu.
  • Send is the app's own mark on a phone, and keeps that dark ground without the mark everywhere else, where upstream paints the stock accent.
  • Every control on that row is 44pt to a thumb without being drawn at 44 — a transparent extender behind each one is what the browser hit-tests.
  • The top bar floats over the transcript, at 44pt, with the session name centred and the context window drawn as a ring beside it. The session panel is a full dialog.
  • The drawer takes 70% of the screen and gives the session list the room: the file explorer starts collapsed on a phone unless asked for.
  • An empty new session stays centred, and drops onto the keyboard when one opens.
  • The model list is reachable by thumb, hung off the button that opened it, its provider headings without upstream's upper case.
  • A turn's process details are one enclosed group, the model named once at its header.
  • The turn line says "cache read" rather than "cache R", and how long the turn took.
  • It is called PAI, with its own mark and wordmark.

Added

  • Swipe a session row left for rename and delete.
  • Swipe in from the left edge to open the drawer — installed app only, where that edge is not already the browser's back gesture.
  • Pull the transcript down to put the keyboard away.
  • A notice when the server has been rebuilt under an open page, with a reload. An installed web app resumes from memory rather than reloading.
  • A way back to the latest message.
  • A way out of the exported history.

Building from source

npm install
npm test        # upstream's suite, 1020 tests
npm run build
npm start

License and attribution

MIT, and a derivative work of pi-web by agegr, whose copyright notice is reproduced in LICENSE as that license requires. The changes carried here are © 2026 Perturbation AI, under the same terms.

The agent underneath is pi (@earendil-works/pi-coding-agent) by Mario Zechner, also MIT. It is a dependency rather than something this build changes, and it is named here because it is what does the work.

Neither project endorses this one. PAI is not official, and carries none of their marks.