diff --git a/300 areas/350 AI/Pi Agent Extensions & Skills.md b/300 areas/350 AI/Pi Agent Extensions & Skills.md index 2bea217..94e2f2c 100644 --- a/300 areas/350 AI/Pi Agent Extensions & Skills.md +++ b/300 areas/350 AI/Pi Agent Extensions & Skills.md @@ -537,57 +537,139 @@ code-review-graph build # parses codebase → .code-review-graph/graph.db ## 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 ``` -pi sessions (each machine) - └─ dashboard.ts extension ── writes ──► ~/.pi/agent/dashboard/.json - │ - pi-dashboard (Go TUI) - reads all state files - │ - Enter → tmux attach d → Hunk diff - Tab → Tuxedo tasks q → quit +pi session (any machine, any terminal: zellij / tmux / plain) + └─ dashboard.ts extension + ├─ writes ~/.pi/agent/dashboard/.json (heartbeat every 15s + on events) + ├─ tracks tasks → /.pi/dashboard/tasks/todo.txt + └─ sends NTFY / Apprise / notify-send notifications + │ SSH pull (cat *.json) +pi-dashboard (Go TUI on .27) ◄───────────────────────┴── .13 + .51 state dirs ``` | 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 | -| **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 | -| **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 | -| **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 | +| **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 over all machines' state files | +| **Tuxedo** | Rust binary (`tuxedo`, nix) | todo.txt task manager (vim keys, phone capture QR) — per-project boards | +| **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` -- **Events:** `agent_start` (status→running), `agent_end` (status→completed, send notification), `tool_call` (track last tool, count) -- **Tasks:** Registers tools `register_task`, `complete_task`, `list_tasks` — writes to todo.txt -- **Notifications:** Calls NTFY (`$PI_NTFY_TOPIC`) and Apprise on agent completion and blocked state -- **State files:** `~/.pi/agent/dashboard/.json` (atomic writes) -- **Session naming:** Derives from tmux session name when in tmux, otherwise working directory basename +```bash +pi-dashboard # full TUI +pi-dashboard --list # plain-text snapshot of local sessions +pi-dashboard --help # keybindings + config reference +``` -### pi-dashboard TUI viewer +### Day-to-day usage (the mental model) -- **Location:** `~/src/pi-dashboard/` (Go module), `~/.local/bin/pi-dashboard` (binary) -- **Built with:** Go + Bubble Tea v2 -- **Reads:** Local `~/.pi/agent/dashboard/*.json` + SSH pull from remote machines -- **Config:** `~/.config/pi-dashboard.yaml` +**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. + +| You want to… | What you do | What happens | +|---|---|---| +| 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 `/.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 && 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 ` 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/.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 `#<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 | |-----|--------| | `↑↓` | Select agent | -| `Enter` | `tmux attach -t ` (local) or `ssh -t user@host tmux attach` (remote) | -| `d` | Open Hunk diff in agent's worktree | -| `Tab` | Launch Tuxedo with task todo.txt | +| `Enter` | Attach: `tmux attach -t ` / `zellij attach ` (dashboard outside zellij) / `zellij action switch-session ` (dashboard inside zellij) — local, or over SSH for remote rows | +| `d` | **Hunk** — review the selected agent's changes *in its own folder*: `cd && hunk diff --watch` | +| `Tab` | **Tuxedo** — open the selected agent's **project** task board: `/.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 | | `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 +``` + +> 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**: `/.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`) ```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: path: /home/sam/.pi/agent/dashboard/ remote: @@ -599,24 +681,14 @@ remote: path: /home/sam/.pi/agent/dashboard/ ``` +Remote polling is plain `ssh … "cat /*.json"` (BatchMode, 5 s connect timeout); unreachable remotes are skipped silently. + ### 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. - -### Tuxedo - -- **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 +- **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`. +- 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. --- @@ -793,5 +865,6 @@ compress_for_agent({ content }) - [x] Update pi-subagents to v0.10.3 ✅ 2026-06-14 - [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] 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 - [ ] Clean up workspace-map.json entries for any stale memory packs