3.9 KiB
3.9 KiB
Agent Guidelines for pi-webui
Project overview
This is a full-stack web UI for the Pi coding agent. The server runs a real Pi AgentSession with system-level tools (bash, file I/O, extensions). The client is a Lit-based SPA using @earendil-works/pi-web-ui components. They communicate over a JSON WebSocket protocol defined in shared/protocol.ts.
Key conventions
- No client framework beyond Lit templates — the app uses module-level state plus plain Lit
htmltemplates inclient/main.ts; callrenderApp()after state mutation. - Pi SDK types come from
@earendil-works/pi-coding-agent(server) and@earendil-works/pi-agent-core/@earendil-works/pi-ai(shared types). Do not duplicate SDK types — import them. - Protocol changes must update
shared/protocol.ts(theClientMessageandServerMessageunions), the server handler inhandleClientMessage(), and the client handler inhandleServerMessage(). - CSS uses Tailwind utility classes in Lit templates plus custom CSS in
client/app.css. Theme variables come from@earendil-works/pi-web-ui/app.css— override them inapp.css:root/.darkblocks. - The sidebar uses plain CSS transitions. Desktop uses
position: relativewith width animation; mobile usesposition: fixedwith transform.
Runtime and security posture
- The agent session defaults to
os.homedir(). This is passed ascwdtocreateAgentSessionandSessionManager.create(). - The WebSocket endpoint controls a real coding agent. Treat any reachable instance as remote-code-execution access for the server user.
HOST=127.0.0.1is the safe default. BindHOST=0.0.0.0only on a trusted network and preferably withPI_WEBUI_TOKENset.PI_WEBUI_TOKENis optional. If set, open/?token=<token>once; the client persists it in local storage. If unset, WebSocket access relies on Origin checks.- Do not add hosted CI/CD, deploy hooks, scheduled jobs, webhooks, or other external automation unless explicitly requested.
Build and run
npm run dev— concurrent dev server (tsx watch + vite)npm run build— Vite production build todist/npm start— run production server (servesdist/static files)- Typical local command:
HOST=127.0.0.1 PORT=3001 npm start
After making changes
- Run
npx tsc --noEmit. - Run
npm run build. - If validating a running production server, restart that server because it serves built
dist/output. - Before pushing to a public remote, check for secrets, private hostnames/IPs, local-only docs, and hosted automation configs.
File layout
server/index.ts— backend (Express, authenticated/origin-checked WebSocket, per-client Pi SDK sessions, optional LiteLLM integration, session management)client/main.ts— frontend (WebSocket client, state management, UI rendering)client/app.css— theme overrides, font rules, sidebar CSS, session item stylesshared/protocol.ts— WebSocket message types shared between client and servervite.config.ts— Vite config with Tailwind plugin and dev proxy for/api/ws
Things to watch out for
- The
pi-web-uicustom elements (message-list,message-editor,streaming-message-container) must be imported and referenced withvoidto prevent tree-shaking. client/main.tslocally overridesAssistantMessage.prototype.renderto append response metadata. Re-audit that copy afterpi-web-uiupdates, especially around chunk/tool rendering.AgentSessionEventobjects may contain circular references — the server usessafeSerializeEvent()before sending them over WebSocket.- Express 5 uses
path-to-regexpv8, which requires/{*path}syntax for catch-all routes, not*. - The model dropdown uses
position: fixedwithz-index: 200to escape stacking contexts. - Session state is per WebSocket. Avoid debug clients that mutate sessions unexpectedly while someone is actively using the UI.