156 lines
7.0 KiB
Markdown
156 lines
7.0 KiB
Markdown
# 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 `.tmp` then 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 starts
|
|
- `pi.on("agent_end", ...)` — fired when agent turn ends
|
|
- `pi.on("tool_call", ...)` — fired on each tool invocation
|
|
- `ctx.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 session
|
|
- `r` → refresh
|
|
- `q` → quit
|
|
- `/` → filter/search agents
|
|
- Optional web mode: `--web` flag starts HTTP server on :9876
|
|
|
|
## Implementation Steps
|
|
|
|
### Phase 1: dashboard.ts extension (1 day)
|
|
|
|
1. Create `~/.pi/agent/extensions/dashboard.ts`
|
|
2. Implement event listeners for `agent_start`, `agent_end`, `tool_call`
|
|
3. Accumulate state: Map<agentId, AgentState>
|
|
4. Write snapshot to `~/.pi/agent/dashboard/<session-name>.json` on each event
|
|
5. Use atomic file writes (write to .tmp, rename)
|
|
6. Register `/dashboard` command that prints a simple in-extension status list
|
|
|
|
### Phase 2: Go TUI viewer (1-2 days)
|
|
|
|
1. Create `~/bin/pi-dashboard/` Go module
|
|
2. Use Bubble Tea for TUI rendering
|
|
3. Implement file watcher (fsnotify) on the dashboard directory
|
|
4. Build table view with agent state columns
|
|
5. Add status indicators with colors
|
|
6. Add keyboard controls (attach, filter, quit)
|
|
7. Test: launch two pi sessions in tmux, verify aggregated view
|
|
|
|
### Phase 3: Attach/jump (half day)
|
|
|
|
1. Extract tmux session name from the state file
|
|
2. `Enter` key → `tmux attach-session -t <name>`
|
|
3. 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:
|
|
|
|
```bash
|
|
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:
|
|
```bash
|
|
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
|
|
|
|
1. What does the dashboard show when pi is idle (no active agent)?
|
|
2. Should the viewer support resuming a session or only viewing?
|
|
3. How far back to keep history? Last N turns? Last 24h?
|
|
4. Web mode: full dashboard or just alerts / status summary?
|