7.0 KiB
7.0 KiB
Pi Dashboard
What It Is
A terminal-based live dashboard that shows what all pi coding agents are doing across the system. Runs in a Zellij pane or detached tmux session. Shows sub-agent status, current tasks, token consumption, and cost — all in one place.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Background: Detached tmux sessions (nixos-desktop .13) │
│ │
│ tmux session "pi-work" │
│ ├── pi (model: opencode-go/deepseek-v4-flash) ← coder-basic │
│ ├── pi (model: deepseek/deepseek-v4-pro) ← coder-pro │
│ └── pi (model: google/gemini-2.5-flash) ← research │
│ └── Each has extension: dashboard.ts │
│ └── Writes state → ~/.pi/agent/dashboard/<id>.json │
│ │
│ tmux session "pi-explore" │
│ └── pi (model: opencode-go/deepseek-v4-flash) ← explore │
│ └── Extension: dashboard.ts │
│ └── Writes state → ~/.pi/agent/dashboard/<id>.json │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Viewer: Zellij pane (or separate terminal) │
│ │
│ bin/pi-dashboard (standalone TUI binary) │
│ └── Reads all ~/.pi/agent/dashboard/*.json │
│ └── Renders table of all agents with live status │
│ └── Press Enter on a row → attach to that tmux session │
│ │
│ Optional: also serves HTTP on :9876 for phone (Termux) │
└─────────────────────────────────────────────────────────────────┘
Key Insight: Two-Component Design
| Component | What it does | How it runs |
|---|---|---|
| dashboard.ts (pi extension) | Lives inside each pi session. Listens to events (agent_start, agent_end, tool_call). Writes JSON state files. Starts optional HTTP server. |
Loaded by pi at startup from ~/.pi/agent/extensions/ |
| pi-dashboard (standalone TUI) | Separate binary. Reads all state files. Renders the unified dashboard. Lets you jump into sessions. | Run from any terminal — Zellij pane, tmux window, Termux SSH |
Why This Design
- dashboard.ts has access to pi's event system (it runs inside pi)
- But it can only see its own pi session
- pi-dashboard is external and can aggregate all sessions
- Separates concerns: collection (inside pi) vs visualization (outside pi)
- The viewer binary can be written in any language — Go recommended
Required Components
1. dashboard.ts (pi extension)
- Hooks:
agent_start,agent_end,tool_call - Tracks: sub-agent name, model, status, start time, duration, last tool, token count
- Persistence: writes to
~/.pi/agent/dashboard/<session-id>.json - Uses atomic writes (write to
.tmpthen rename) to avoid corruption - Also: small HTTP server on localhost:9876 for real-time polling
Pi's extension API provides everything needed:
pi.on("agent_start", ...)— fired when agent turn startspi.on("agent_end", ...)— fired when agent turn endspi.on("tool_call", ...)— fired on each tool invocationctx.sessionManager— session state access
2. pi-dashboard viewer
- Standalone binary (Go recommended — see Tech Stack below)
- Directory watcher on
~/.pi/agent/dashboard/ - Renders a live table of all agent sessions
- Features per row:
- Agent type/name
- Model/provider
- Status (idle, running, waiting, error, done)
- Current task description
- Duration
- Token count & running cost
- Last activity timestamp
- Keyboard controls:
Enter→ attach to that tmux sessionr→ refreshq→ quit/→ filter/search agents
- Optional web mode:
--webflag starts HTTP server on :9876
Implementation Steps
Phase 1: dashboard.ts extension (1 day)
- Create
~/.pi/agent/extensions/dashboard.ts - Implement event listeners for
agent_start,agent_end,tool_call - Accumulate state: Map<agentId, AgentState>
- Write snapshot to
~/.pi/agent/dashboard/<session-name>.jsonon each event - Use atomic file writes (write to .tmp, rename)
- Register
/dashboardcommand that prints a simple in-extension status list
Phase 2: Go TUI viewer (1-2 days)
- Create
~/bin/pi-dashboard/Go module - Use Bubble Tea for TUI rendering
- Implement file watcher (fsnotify) on the dashboard directory
- Build table view with agent state columns
- Add status indicators with colors
- Add keyboard controls (attach, filter, quit)
- Test: launch two pi sessions in tmux, verify aggregated view
Phase 3: Attach/jump (half day)
- Extract tmux session name from the state file
Enterkey →tmux attach-session -t <name>- Or launch a new pi session from the dashboard
Phase 4: Polish (ongoing)
- Historical cost tracking across sessions
- Notification when an agent stalls or errors
- Web mode for phone access
- Alerts/markers when agents finish tasks
How Sessions Tie Together
The convention for naming:
tmux new-session -d -s pi-work 'pi --model opencode-go/deepseek-v4-flash'
# dashboard.ts writes to ~/.pi/agent/dashboard/pi-work.json
# The session name "pi-work" ties the dashboard entry to the tmux session
When you press Enter on "pi-work" in the dashboard:
tmux attach-session -t pi-work
When running pi without tmux, dashboard.ts writes to ~/.pi/agent/dashboard/unsorted.json — the viewer still picks it up.
Prerequisites Already Met
- ✅ Node.js (everything runs on it)
- ✅ Go (if chosen for TUI — installable via nix)
- ✅ Pi extension system (all hooks available)
- ✅ tmux (already available)
- ✅ Shared filesystem (state files are local)
- ✅ OmniRoute for model routing
Open Questions
- What does the dashboard show when pi is idle (no active agent)?
- Should the viewer support resuming a session or only viewing?
- How far back to keep history? Last N turns? Last 24h?
- Web mode: full dashboard or just alerts / status summary?