Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pi-panel

A Manus-style, zero-dependency local web UI for the pi coding agent.

Dark three-column layout: sessions sidebar, streaming chat, and an "Agent Computer" panel with Steps, Terminal, and Files tabs that follow the agent as it works.

pi-panel

Why

pi already has a great terminal UI. pi-panel is for when you want a browser tab instead — multiple sessions side by side, streaming tool output, and a click-through view of what the agent is doing (steps, shell output, edited files), without leaving localhost.

Requirements

  • Node.js 20+
  • pi installed and authenticated (see pi's docs for install/login instructions)

That's it. No npm install, no package.json, no third-party dependencies. The entire backend is one file (server.mjs) built on Node's standard library (http, child_process, crypto, fs, path, url), and the frontend (web/) is plain HTML/CSS/JS with no framework and no CDN scripts. This is a deliberate design choice, not a limitation — see Security.

Quick start

git clone https://github.com/<you>/pi-panel.git
cd pi-panel
node server.mjs

The server prints something like:

pi-panel listening on http://127.0.0.1:8788
Bearer token stored at /Users/you/.pi-panel-token
Use: Authorization: Bearer <token>

Open this URL to sign in automatically:
  http://127.0.0.1:8788/#token=<token>

Open the last URL (the one with #token=...) in your browser — the page reads the token from the URL fragment, stores it in localStorage, and strips it from the address bar. You only need to do this once per browser; after that, reloading http://127.0.0.1:8788 just works. The same token also lives at ~/.pi-panel-token if you ever need to paste it back in manually (see Troubleshooting).

Security

pi-panel gives a browser tab the ability to spawn pi subprocesses that can read, write, and execute code in your filesystem. Treat it accordingly:

  • Bound to 127.0.0.1 only. The server never listens on 0.0.0.0 or any externally reachable interface. It is not reachable from other devices on your network by default.
  • Bearer token on every API call. All /api/* endpoints (including the SSE event stream) require Authorization: Bearer <token>, or ?token= for the SSE connection. Static files are served without auth, but they contain no data.
  • Zero third-party dependencies, on purpose. There is no npm install step, so there is no dependency tree that can auto-update, get compromised upstream, or pull in a malicious transitive package. Every line of code that runs is in this repository. This matters more than usual for a tool that shells out to an AI agent with filesystem and command execution access — we'd rather not run npx some-web-ui@latest and trust that whatever version resolves today is safe.

Do not port-forward, reverse-proxy, or otherwise expose pi-panel to the internet. There is no TLS, no per-user auth, and no rate limiting — it is built exclusively for local, single-user use on your own machine.

Usage

  • New Task in the sidebar creates a new session. Each session spawns its own pi --mode rpc subprocess, rooted at a working directory you choose (default: ~/pi-workspace).
  • The sidebar shows all sessions with a status dot that pulses while a session is streaming a response.
  • Above the composer, pick the model and thinking level for the active session.
  • Cmd+K / Ctrl+K opens a command palette to jump between sessions.
  • The settings modal (gear icon) holds your bearer token and the default working directory used for new sessions.
  • The right-hand panel mirrors what the agent is doing in real time:
    • Steps — a timeline of tool calls (spinner → check/x).
    • Terminal — live output from shell/bash tool calls.
    • Files — files the agent has edited or written, with diffs when available.

Architecture

┌─────────┐   HTTP + SSE    ┌────────────┐   stdin/stdout JSONL   ┌───────────────────┐
│ browser │ ─────────────▶  │ server.mjs │ ─────────────────────▶│ pi --mode rpc      │
│  (SPA)  │ ◀─────────────  │            │ ◀──────────────────── │ (one child/session)│
└─────────┘                 └────────────┘                       └───────────────────┘
  • server.mjs is a plain Node http server. Every REST call maps to an RPC request written to a session's pi --mode rpc child (matched by id, 30s timeout).
  • Each session keeps a ring buffer of the last 5000 RPC events. When a browser tab (re)connects to GET /api/sessions/:id/events (Server-Sent Events), the buffer is replayed first so the UI can catch up, then live events stream in.
  • pi's RPC stdout is framed by splitting on \n only (not Node's readline, which also splits on line-separator Unicode characters and would corrupt the protocol).
  • Sessions and their child processes live only in server memory; all pi children are killed on SIGINT/SIGTERM.

See SPEC.md for the full API surface and event wiring.

Troubleshooting

  • 401 Unauthorized — your stored token doesn't match the server's. Open Settings and paste the token from ~/.pi-panel-token, or reopen the printed #token= URL from server startup.
  • Port already in use — run with a different port: node server.mjs --port 8899 (or set PORT=8899).
  • "pi not found" / spawn errors — pi-panel shells out to the pi binary on your PATH. Make sure pi is installed and pi --version works in your terminal before starting pi-panel.

License

MIT — see LICENSE.

About

Manus-style zero-dependency local web UI for the pi coding agent

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages