sam-4screen-desktop 2026-8-4:11:29:15

This commit is contained in:
2026-08-04 11:29:15 +10:00
parent 977e78be26
commit efe2db9e25

View File

@@ -537,57 +537,139 @@ code-review-graph build # parses codebase → .code-review-graph/graph.db
## Pi Dashboard ## Pi Dashboard
A multi-component system for live agent visibility across all machines. Built in this conversation (Jul 2026). A multi-component system for live agent visibility across all machines. Every pi session on every machine (plus sub-agents) reports its state; the TUI shows them all in one table and can attach to them, review their diffs, or open their task boards.
### Architecture ### Architecture
``` ```
pi sessions (each machine) pi session (any machine, any terminal: zellij / tmux / plain)
└─ dashboard.ts extension ── writes ──► ~/.pi/agent/dashboard/<session>.json └─ dashboard.ts extension
├─ writes ~/.pi/agent/dashboard/<session>.json (heartbeat every 15s + on events)
pi-dashboard (Go TUI) ├─ tracks tasks → <project>/.pi/dashboard/tasks/todo.txt
reads all state files └─ sends NTFY / Apprise / notify-send notifications
│ SSH pull (cat *.json)
Enter → tmux attach d → Hunk diff pi-dashboard (Go TUI on .27) ◄───────────────────────┴── .13 + .51 state dirs
Tab → Tuxedo tasks q → quit
``` ```
| Component | Type | Purpose | | Component | Type | Purpose |
|-----------|------|---------| |-----------|------|---------|
| **dashboard.ts** | pi extension (`~/.pi/agent/extensions/`) | Listens to `agent_start`/`agent_end`/`tool_call`, writes JSON state files, tracks tasks via todo.txt, sends NTFY/Apprise notifications | | **dashboard.ts** | pi extension (`~/.pi/agent/extensions/dashboard.ts`; source `~/.agents/extensions/dashboard.ts` → Gitea `pi-config`) | Per-session telemetry: heartbeat, cwd, started/closed times, agent status, tool count; task tools; notifications |
| **pi-dashboard** | Go binary (`~/.local/bin/pi-dashboard`) | Bubble Tea TUI. Reads state files from all machines (local + SSH pull). Renders agent table with keyboard controls | | **pi-dashboard** | Go binary (`~/.local/bin/pi-dashboard`) | Bubble Tea TUI over all machines' state files |
| **Tuxedo** | Companion TUI (Rust binary, `tuxedo`) | todo.txt task manager. The dashboard extension writes tasks to `~/.pi/agent/dashboard/tasks/todo.txt` in standard todo.txt format, Tuxedo reads it natively with vim keys, phone capture QR, project/context filters | | **Tuxedo** | Rust binary (`tuxedo`, nix) | todo.txt task manager (vim keys, phone capture QR) — per-project boards |
| **Hunk** | Companion TUI (Node CL | npx hunk) | Review-first terminal diff viewer for agent-authored changesets. Triggered from dashboard with `d` key. Supports split/stack/responsive layouts, inline AI annotations, watch mode, Git/jj/Sapling | | **Hunk** | Node CLI (`hunk`, nix / npm `hunkdiff`) | Review-first terminal diff viewer for agent-authored changes |
### dashboard.ts extension ### Quick start
- **Location:** `~/.pi/agent/extensions/dashboard.ts` ```bash
- **Events:** `agent_start` (status→running), `agent_end` (status→completed, send notification), `tool_call` (track last tool, count) pi-dashboard # full TUI
- **Tasks:** Registers tools `register_task`, `complete_task`, `list_tasks` — writes to todo.txt pi-dashboard --list # plain-text snapshot of local sessions
- **Notifications:** Calls NTFY (`$PI_NTFY_TOPIC`) and Apprise on agent completion and blocked state pi-dashboard --help # keybindings + config reference
- **State files:** `~/.pi/agent/dashboard/<session>.json` (atomic writes) ```
- **Session naming:** Derives from tmux session name when in tmux, otherwise working directory basename
### pi-dashboard TUI viewer ### Day-to-day usage (the mental model)
- **Location:** `~/src/pi-dashboard/` (Go module), `~/.local/bin/pi-dashboard` (binary) **The pi terminal is for talking; the dashboard TUI is for watching.** You never type tool names or run hunk/tuxedo inside the pi input.
- **Built with:** Go + Bubble Tea v2
- **Reads:** Local `~/.pi/agent/dashboard/*.json` + SSH pull from remote machines | You want to… | What you do | What happens |
- **Config:** `~/.config/pi-dashboard.yaml` |---|---|---|
| Add / list / complete tasks | Tell pi: *"add a task: …"*, *"what tasks do I have?"*, *"mark … done"* | The agent calls `register_task` / `list_tasks` / `complete_task`, which write lines to `<project>/.pi/dashboard/tasks/todo.txt` |
| See the task board | Press `Tab` in the dashboard TUI | Tuxedo opens the selected session's `todo.txt` (vim keys: `j/k`, `dd` complete, `u` undo, `s` phone QR) |
| Review what an agent changed | Press `d` on its row in the dashboard TUI | Hunk opens in the agent's folder: `cd <cwd> && hunk diff --watch` — shows **all uncommitted changes** in that repo (not a two-file compare) |
| Jump into a session | Press `Enter` on its row | `tmux attach` / `zellij attach` / `zellij action switch-session` |
Key points:
- `register_task`/`complete_task`/`list_tasks` are **agent tools** — you ask in English, the AI calls them. They feed todo.txt, which is what Tuxedo displays.
- **Hunk's "first/second file" mode** is `hunk diff <left> <right>` for comparing two concrete files. The dashboard `d` key uses `hunk diff --watch` (whole working tree) instead.
- Both task systems coexist: the **dashboard tools** → todo.txt → Tuxedo (vim board), while **@tintinweb/pi-tasks** (`TaskCreate`, `TaskExecute`, `/tasks`) is a separate dependency-tracked task engine that can spawn subagents.
### State model
Each session writes `~/.pi/agent/dashboard/<session>.json` (atomic write):
| Field | Meaning |
|-------|---------|
| `session` | pi session name |
| `cwd` | full working directory the session runs in (the **Folder** column) |
| `session_started_at` / `closed_at` | session start / graceful-close times |
| `last_seen_at` | heartbeat — refreshed every 15 s + on every event |
| `agent_status` | `idle` / `running` / `blocked` / `error` (the *agent turn*) |
| `session_state` | `open` / `closed` (the *process liveness*) |
| `terminal_type` | `tmux` / `zellij` / `tmux+zellij` / `direct` |
| `zellij_session` / `tmux_session` / `pid` | attach targets for Enter |
| `is_subagent` | true for rows named `<Agent>#<8hex>` (pi-subagents) |
**Closed detection** — a session counts as closed when:
- the extension wrote `session_state: "closed"` on graceful shutdown, **or**
- `last_seen_at` is older than `stale_after` (default 45 s) — the terminal was killed (pane closed, `kill -9`) without a shutdown event.
Status labels: `● running` · `○ idle` · `⚠ blocked` · `✕ error` · `✗ closed` (graceful) · `✗ lost` (died without shutdown).
### TUI keybindings
| Key | Action | | Key | Action |
|-----|--------| |-----|--------|
| `↑↓` | Select agent | | `↑↓` | Select agent |
| `Enter` | `tmux attach -t <session>` (local) or `ssh -t user@host tmux attach` (remote) | | `Enter` | Attach: `tmux attach -t <name>` / `zellij attach <name>` (dashboard outside zellij) / `zellij action switch-session <name>` (dashboard inside zellij) — local, or over SSH for remote rows |
| `d` | Open Hunk diff in agent's worktree | | `d` | **Hunk** — review the selected agent's changes *in its own folder*: `cd <cwd> && hunk diff --watch` |
| `Tab` | Launch Tuxedo with task todo.txt | | `Tab` | **Tuxedo** — open the selected agent's **project** task board: `<cwd>/.pi/dashboard/tasks/todo.txt` (created if missing; falls back to global board) |
| `s` | Cycle sort: **smart** (live first → running first → last activity) → activity → started → folder |
| `x` | Toggle hiding closed sessions (dead sessions sink to the bottom by default; `x` removes them from the view, press again to restore) |
| `z` | Toggle hiding sub-agent rows (marked `◇`) |
| `r` | Force refresh | | `r` | Force refresh |
| `q` | Quit | | `q` | Quit |
Selecting a row shows a detail pane: full folder path, started / closed / last-seen times, terminal + zellij/tmux session + pid, model, tool count, current task, blocked prompt.
### Session naming & rename
Name resolution order on start: pi session name → `PI_SESSION` env → tmux session name → **zellij session name** (only when it isn't zellij's auto-generated `word-word` animal name like `chatty-echidna`) → working-directory basename.
**Recommended workflow — one named zellij session per pi session, same name for both:**
```bash
zellij -s computer_software # create a named zellij session…
# …pi started inside it auto-inherits "computer_software" as its pi session name
```
**Rename mid-session (pi session + zellij session + dashboard row together):**
```text
/dash-name <name>
```
> pi's built-in `/name` only renames the pi session and cannot be hooked by extensions — `/dash-name` renames all three (pi, zellij, dashboard row). Use `/name` or `Ctrl+R` in `/tree` when you only want to rename the pi session.
### Long-running / background sessions (tmux survival layer)
To keep a pi session running after zellij (or the terminal) closes — e.g. a long agent job on a remote machine — run pi inside a tmux session **inside** the zellij pane:
```bash
tmux new -s deploy-job # inside the zellij pane
pi # start pi inside tmux
# detach with Ctrl-b d — tmux (and pi) keep running after zellij closes
tmux attach -t deploy-job # reattach whenever
```
The extension detects the `TMUX` env var: rows show `Ⓣ`, and `Enter` does `tmux attach` — the session survives zellij closing. Rows in bare zellij panes show `Ⓩ`; `tmux+zellij` shows `ⓉⓏ`; plain terminals show `·`.
### Tasks & Tuxedo
- Agents register tasks via the `register_task` / `complete_task` / `list_tasks` tools.
- Task files are **per project**: `<project>/.pi/dashboard/tasks/todo.txt` (standard todo.txt format).
- In the dashboard, `Tab` opens Tuxedo on the **selected row's** project board; with nothing selected it falls back to `~/.pi/agent/dashboard/tasks/todo.txt`.
- Tuxedo: vim keys (`j/k`, `dd`, `gg/G`), `u` undo (50 levels), `s` QR phone capture → https://github.com/webstonehq/tuxedo
### Hunk
- `d` in the dashboard runs `hunk diff --watch` in the selected agent's folder (over SSH for remote rows) — review exactly what that agent changed.
- Standalone: `hunk diff --watch` (live review of the working tree), `hunk show` (last commit). Multi-file sidebar, inline AI annotations, split/stack/responsive layouts. → https://github.com/modem-dev/hunk
### Cross-machine config (`~/.config/pi-dashboard.yaml`) ### Cross-machine config (`~/.config/pi-dashboard.yaml`)
```yaml ```yaml
poll_interval: 2s poll_interval: 2
stale_after: 45 # seconds without heartbeat ⇒ session considered closed
hide_closed: false # start with closed sessions hidden (toggle with x)
local: local:
path: /home/sam/.pi/agent/dashboard/ path: /home/sam/.pi/agent/dashboard/
remote: remote:
@@ -599,24 +681,14 @@ remote:
path: /home/sam/.pi/agent/dashboard/ path: /home/sam/.pi/agent/dashboard/
``` ```
Remote polling is plain `ssh … "cat <path>/*.json"` (BatchMode, 5 s connect timeout); unreachable remotes are skipped silently.
### Deployment ### Deployment
The extension deploys via Gitea (in `pi-config`) or manually placed in `~/.pi/agent/extensions/`. The Go binary is built from source and scp'd to remote machines. - **Extension** — source of truth: `~/.agents/extensions/dashboard.ts` (Gitea `pi-config`). Edit there, commit + push, then copy to `~/.pi/agent/extensions/dashboard.ts` on each machine (`.27`, `.13`, `.51`).
- **Binary** — `cd ~/src/pi-dashboard && CGO_ENABLED=0 go build -o ~/.local/bin/pi-dashboard .`, then `scp` to `.13`/`.51`.
### Tuxedo - After updating the extension on a machine, run `/reload` in running pi sessions (or restart) to activate it.
- Dead state files accumulate by design (they just show as closed); the `archive/` subfolder holds pruned files.
- **Site:** https://github.com/webstonehq/tuxedo
- **Install:** Built from source via nix
- **Format:** Standard todo.txt — `~/.pi/agent/dashboard/tasks/todo.txt`
- **Phone capture:** Press `s` for QR code pointing at LAN PWA — type tasks from phone
- **Vim keys:** `j/k`, `dd`, `gg/G`, `u` (undo, 50 levels)
### Hunk
- **Site:** https://github.com/modem-dev/hunk
- **Install:** `npm i -g hunkdiff` (also available in nixpkgs)
- **Usage:** `hunk diff --watch` (live review), `hunk show` (review last commit)
- **Features:** Multi-file review with sidebar, inline AI annotations, split/stack/responsive layouts, watch mode for auto-reloading
--- ---
@@ -793,5 +865,6 @@ compress_for_agent({ content })
- [x] Update pi-subagents to v0.10.3 ✅ 2026-06-14 - [x] Update pi-subagents to v0.10.3 ✅ 2026-06-14
- [x] Update pi-tasks to v0.7.0 ✅ 2026-06-13 - [x] Update pi-tasks to v0.7.0 ✅ 2026-06-13
- [x] Install pi-langfuse tracing extension (pi → Langfuse on .13:3001) ✅ 2026-08-03 - [x] Install pi-langfuse tracing extension (pi → Langfuse on .13:3001) ✅ 2026-08-03
- [x] Pi Dashboard v2: heartbeat + cwd + started/closed columns, hide/sort, /dash-name (pi+zellij), hunk in agent folder, tuxedo project boards, zellij/tmux attach ✅ 2026-08-04
- [ ] Verify video-extract works with Gemini - [ ] Verify video-extract works with Gemini
- [ ] Clean up workspace-map.json entries for any stale memory packs - [ ] Clean up workspace-map.json entries for any stale memory packs