A focused web UI for @earendil-works/pi-coding-agent, designed for mobile, desktop, and tablet.
pi-web's goal is simple: provide the best interface for pi on every device. It stays close to the core agent experience while giving pi the web-specific context it needs to render artifacts, images, sessions, diffs, diagrams, and tool output clearly.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
- Every-device UI: a responsive experience for phone, tablet, and desktop browsers
- Minimal by design: a focused agent UI, not a full IDE replacement
- Self-aware: pi-web injects web UI context so sessions understand artifacts, images, restarts, and browser-specific behavior
- Code-review friendly: inspect tool output, edits, Git status, commits, and diffs
- Session-oriented: organize ongoing work with reorderable pinned tabs, drawers, colors, filters, metadata, and conversation navigation
- Rich output: preview artifacts and open Mermaid diagrams in a full-screen viewer
0.5.0 expands the session workspace and improves everyday interaction across devices:
- reorder pinned session tabs and assign colors directly from the tab menu
- inspect session metadata and use new artifact actions
- open Mermaid diagrams in a dedicated full-screen viewer
- see queued steering and follow-up messages before they are sent
- use the improved model picker and tighter mobile folder selector
- recover more easily from connection warnings and session switches
- benefit from more reliable conversation-tree layouts and updated Pi 0.82.0 runtime support
See the 0.5.0 release notes for the fuller changelog.
For development:
npm installFrom npm:
npm i -g @ashwin-pc/pi-web
pi-webOr run without a global install:
npx -y @ashwin-pc/pi-web@latestFirst run: if pi-web does not find an existing Pi provider login, API key, or custom model config, it prompts in the same terminal to open the bundled Pi CLI. Run /login there, connect your provider, exit Pi, and pi-web continues starting. You can skip this prompt with PI_WEB_SKIP_PROVIDER_ONBOARDING=1.
From a GitHub release asset:
# Download pi-web-<version>.tgz from the release page, then:
npm install -g ./pi-web-*.tgz
pi-webpi-web starts the production server on http://127.0.0.1:8787 by default. It runs Pi in the directory where you call the command; override with PI_WEB_CWD=/path/to/project pi-web.
npm run devThis starts a stable TypeScript supervisor on 8787 and a restartable child server on 8788. The public URL still serves:
- Vite frontend with HMR
- Pi API routes under
/api/* - Pi WebSocket at
/ws
The supervisor also exposes:
POST /api/restart- restart the child server safelyGET /__supervisor/status- inspect child PID/generation
Open:
http://127.0.0.1:8787
Edit files under src/ and Vite will update the UI live. If the agent edits server.ts, call POST /api/restart instead of killing the public server; the supervisor stays alive and the browser reconnects.
By default, Pi operates in the directory where you start this server. To point Pi at another project:
PI_WEB_CWD=/Users/ashwin/projects/comfy-lan-webapp npm run devThe session UI is built for small screens first, then scales up to desktop. Tabs, the session drawer, pinned sessions, bucket filters, and conversation navigation are designed to keep long-running pi work reachable from a phone without hiding the desktop workflow.
A shared diff viewer supports side-by-side or stacked layouts with intraline highlighting. It is used by both edit tool cards and Git diffs, so code review feels consistent across agent changes and repository history.
The Git button in the header opens a responsive Git panel for repo status, commit history, per-file diffs, per-commit diffs, and sync with fetch + rebase pull.
contexts/web-ui.md is injected into agent sessions so pi understands pi-web behavior such as artifact links, image rendering, and supervised restarts. Bundled pi extensions add pi-web defaults, including automatic session naming from the first prompt.
pi-web supports browser-specific extensions in .pi/web/extensions and ~/.pi/web/extensions. These use pi's extension runtime with a typed pi-web UI API, including ctx.ui.web.setFooter(...) for rendering text or trusted HTML between the composer and pinned session tabs.
See pi-web extensions for locations, types, and examples, including the live git footer in examples/pi-web-extensions/git-footer.ts.
The README references the same deterministic Playwright visual snapshots used by tests/e2e/visual.spec.ts. Desktop and mobile captures are shown side by side, and when visual snapshots are intentionally updated, these images update with them.
New sessions open with a lightweight animated empty state and a compact working-directory control. The visual baseline waits for the animation’s settled final frame so screenshot comparisons stay deterministic.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
| Desktop | Mobile |
|---|---|
![]() |
![]() |
Tabs, pinned sessions, bucket colors, running indicators, and the session drawer are designed to stay usable on mobile while expanding naturally on desktop.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
Desktop uses a split master/detail layout; mobile switches between status, graph, diff, and commit detail views.
| Desktop | Mobile |
|---|---|
![]() |
![]() |
Navigate even elaborate, nested pi session branches with a compact tree drawer. Alternate paths stay grouped beside their fork, globally packed graph lanes keep nested branch fans from colliding, and the highlighted current path remains easy to follow. The default view keeps tool noise hidden, while the full session structure remains available from the filter.
| Nested branches · Desktop | Nested branches · Mobile |
|---|---|
![]() |
![]() |
npm run build
npm startnpm start serves the compiled dist/ app and API from one process.
pi-web binds to localhost by default. If you want remote access, place it behind a secure networking or reverse-proxy solution of your choice and set PI_WEB_TOKEN.
For example, with Tailscale Serve you can keep the Node app localhost-only:
npm run build
PI_WEB_TOKEN="$(openssl rand -hex 32)" \
PI_WEB_CWD=/Users/ashwin/projects/comfy-lan-webapp \
HOST=127.0.0.1 \
PORT=8787 \
npm startIn another terminal:
tailscale serve --bg http://127.0.0.1:8787Then open:
https://<machine-name>.<tailnet>.ts.net
Enter PI_WEB_TOKEN on the token screen, or use Scan QR if another signed-in pi-web tab is showing the Settings → Token sharing QR code.
You can also bind directly to your Tailscale IP:
PI_WEB_TOKEN="$(openssl rand -hex 32)" \
HOST="$(tailscale ip -4)" \
PORT=8787 \
npm startThen open:
http://<machine-name>:8787
HOST- bind host, default127.0.0.1PORT- bind port, default8787PI_WEB_TOKEN- optional bearer token for API/WebSocket accessPI_WEB_CWD- project directory Pi should operate in, default current directoryPI_WEB_NO_SESSION=1- use in-memory sessions onlyPI_WEB_CHILD_HOST- supervised child bind host, default127.0.0.1PI_WEB_CHILD_PORT- supervised child port, defaultPORT + 1(for example8788whenPORT=8787)PI_WEB_RESTART_GRACE_MS- delay between child stop/start, default250
The app is TypeScript end-to-end:
supervisor.tsis a small stable dev supervisor that owns the public port and restarts the app server safelyserver.tsis the restartable Pi API/WebSocket server, run directly withtsxsrc/main.tsbootstraps the modular Vite frontend with HMR; see docs/frontend-architecture.md- in dev,
server.tsembeds Vite middleware whilesupervisor.tsproxies API, WebSocket, and HMR traffic AGENTS.mdprovides normal project-specific pi instructions when the target cwd is this repo
This app can drive Pi tools such as bash, write, and edit. Restrict network access with your chosen security controls and set PI_WEB_TOKEN.











