@blackbelt-technology/pi-agent-dashboard 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +87 -114
- package/README.md +408 -430
- package/docs/architecture.md +465 -12
- package/package.json +10 -5
- package/packages/extension/package.json +14 -4
- package/packages/extension/src/__tests__/ask-user-tool.test.ts +40 -8
- package/packages/extension/src/__tests__/bridge-entry-id-pi-070.test.ts +174 -0
- package/packages/extension/src/__tests__/enrich-model-metadata.test.ts +201 -0
- package/packages/extension/src/__tests__/event-forwarder.test.ts +30 -0
- package/packages/extension/src/__tests__/fork-entryid-timing.test.ts +64 -76
- package/packages/extension/src/__tests__/git-info.test.ts +67 -55
- package/packages/extension/src/__tests__/multiselect-list.test.ts +137 -0
- package/packages/extension/src/__tests__/no-session-replacement-calls.test.ts +99 -0
- package/packages/extension/src/__tests__/openspec-poller.test.ts +101 -96
- package/packages/extension/src/__tests__/process-scanner-kill.test.ts +61 -0
- package/packages/extension/src/__tests__/provider-register-reload.test.ts +394 -0
- package/packages/extension/src/__tests__/server-auto-start.test.ts +95 -4
- package/packages/extension/src/__tests__/server-launcher.test.ts +16 -0
- package/packages/extension/src/ask-user-tool.ts +5 -4
- package/packages/extension/src/bridge.ts +171 -17
- package/packages/extension/src/dev-build.ts +1 -1
- package/packages/extension/src/git-info.ts +9 -19
- package/packages/extension/src/multiselect-list.ts +146 -0
- package/packages/extension/src/multiselect-polyfill.ts +43 -0
- package/packages/extension/src/pi-env.d.ts +1 -0
- package/packages/extension/src/process-scanner.ts +72 -38
- package/packages/extension/src/provider-register.ts +304 -16
- package/packages/extension/src/server-auto-start.ts +27 -1
- package/packages/extension/src/server-launcher.ts +83 -27
- package/packages/server/package.json +16 -2
- package/packages/server/src/__tests__/bootstrap-queue.test.ts +120 -0
- package/packages/server/src/__tests__/bootstrap-routes.test.ts +125 -0
- package/packages/server/src/__tests__/bootstrap-state.test.ts +119 -0
- package/packages/server/src/__tests__/browse-endpoint.test.ts +17 -0
- package/packages/server/src/__tests__/cli-parse.test.ts +11 -0
- package/packages/server/src/__tests__/concurrent-launch.test.ts +110 -0
- package/packages/server/src/__tests__/config-api.test.ts +68 -0
- package/packages/server/src/__tests__/crash-recovery.test.ts +88 -0
- package/packages/server/src/__tests__/directory-service.test.ts +234 -8
- package/packages/server/src/__tests__/editor-registry.test.ts +28 -15
- package/packages/server/src/__tests__/extension-register-appimage.test.ts +5 -1
- package/packages/server/src/__tests__/extension-register.test.ts +3 -1
- package/packages/server/src/__tests__/find-port-holders.test.ts +94 -0
- package/packages/server/src/__tests__/fixtures/fork-jsonl-roundtrip.jsonl +8 -0
- package/packages/server/src/__tests__/force-kill-handler.test.ts +57 -8
- package/packages/server/src/__tests__/fork-jsonl-roundtrip.test.ts +49 -0
- package/packages/server/src/__tests__/home-lock-escape-hatch.test.ts +60 -0
- package/packages/server/src/__tests__/home-lock-release.test.ts +85 -0
- package/packages/server/src/__tests__/home-lock.test.ts +308 -0
- package/packages/server/src/__tests__/is-pi-process.test.ts +36 -0
- package/packages/server/src/__tests__/node-guard.test.ts +85 -0
- package/packages/server/src/__tests__/package-manager-wrapper-resolve.test.ts +5 -1
- package/packages/server/src/__tests__/package-manager-wrapper.test.ts +45 -10
- package/packages/server/src/__tests__/pi-version-skew.test.ts +237 -0
- package/packages/server/src/__tests__/preferences-store.test.ts +73 -4
- package/packages/server/src/__tests__/process-manager.test.ts +45 -18
- package/packages/server/src/__tests__/provider-probe.test.ts +287 -0
- package/packages/server/src/__tests__/provider-test-route.test.ts +149 -0
- package/packages/server/src/__tests__/restart-helper.test.ts +111 -0
- package/packages/server/src/__tests__/session-action-handler-headless-reload.test.ts +467 -0
- package/packages/server/src/__tests__/session-action-handler-reload-predicate.test.ts +73 -0
- package/packages/server/src/__tests__/session-action-handler-spawn-error.test.ts +74 -0
- package/packages/server/src/__tests__/terminal-manager.test.ts +41 -1
- package/packages/server/src/__tests__/tool-routes.test.ts +277 -0
- package/packages/server/src/__tests__/trusted-networks-config.test.ts +19 -0
- package/packages/server/src/__tests__/trusted-networks-no-oauth-roundtrip.test.ts +126 -0
- package/packages/server/src/__tests__/tunnel-cleanup.test.ts +90 -0
- package/packages/server/src/__tests__/tunnel.test.ts +13 -7
- package/packages/server/src/__tests__/wsl-tmux-probe-cache.test.ts +44 -0
- package/packages/server/src/bootstrap-queue.ts +130 -0
- package/packages/server/src/bootstrap-state.ts +131 -0
- package/packages/server/src/browse.ts +8 -3
- package/packages/server/src/browser-handlers/directory-handler.ts +23 -8
- package/packages/server/src/browser-handlers/session-action-handler.ts +213 -79
- package/packages/server/src/browser-handlers/session-action-helpers.ts +36 -0
- package/packages/server/src/cli.ts +310 -39
- package/packages/server/src/config-api.ts +16 -0
- package/packages/server/src/directory-service.ts +270 -39
- package/packages/server/src/editor-detection.ts +12 -9
- package/packages/server/src/editor-manager.ts +19 -4
- package/packages/server/src/editor-pid-registry.ts +9 -8
- package/packages/server/src/editor-registry.ts +22 -25
- package/packages/server/src/git-operations.ts +1 -1
- package/packages/server/src/headless-pid-registry.ts +7 -20
- package/packages/server/src/home-lock-release.ts +72 -0
- package/packages/server/src/home-lock.ts +389 -0
- package/packages/server/src/node-guard.ts +52 -0
- package/packages/server/src/package-manager-wrapper.ts +207 -47
- package/packages/server/src/pi-core-checker.ts +1 -1
- package/packages/server/src/pi-core-updater.ts +7 -1
- package/packages/server/src/pi-resource-scanner.ts +5 -8
- package/packages/server/src/pi-version-skew.ts +207 -0
- package/packages/server/src/preferences-store.ts +17 -3
- package/packages/server/src/process-manager.ts +403 -222
- package/packages/server/src/provider-probe.ts +234 -0
- package/packages/server/src/restart-helper.ts +141 -0
- package/packages/server/src/routes/bootstrap-routes.ts +88 -0
- package/packages/server/src/routes/openspec-routes.ts +25 -1
- package/packages/server/src/routes/pi-core-routes.ts +24 -1
- package/packages/server/src/routes/provider-auth-routes.ts +8 -8
- package/packages/server/src/routes/provider-routes.ts +43 -0
- package/packages/server/src/routes/recommended-routes.ts +10 -12
- package/packages/server/src/routes/system-routes.ts +20 -33
- package/packages/server/src/routes/tool-routes.ts +153 -0
- package/packages/server/src/server-pid.ts +5 -9
- package/packages/server/src/server.ts +211 -10
- package/packages/server/src/session-api.ts +77 -8
- package/packages/server/src/session-bootstrap.ts +17 -3
- package/packages/server/src/session-diff.ts +21 -21
- package/packages/server/src/terminal-manager.ts +61 -20
- package/packages/server/src/tunnel.ts +42 -28
- package/packages/shared/package.json +10 -3
- package/packages/shared/src/__tests__/{tool-resolver.test.ts → binary-lookup.test.ts} +32 -12
- package/packages/shared/src/__tests__/bootstrap/README.md +133 -0
- package/packages/shared/src/__tests__/bootstrap/__snapshots__/cube.test.ts.snap +370 -0
- package/packages/shared/src/__tests__/bootstrap/assertions.ts +136 -0
- package/packages/shared/src/__tests__/bootstrap/cube.test.ts +47 -0
- package/packages/shared/src/__tests__/bootstrap/cube.ts +66 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/a-electron.test.ts.snap +83 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/b-npm-global.test.ts.snap +89 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/c-dev-monorepo.test.ts.snap +33 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/d-overrides.test.ts.snap +20 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/e-stale-partial.test.ts.snap +61 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/f-cwd-variants.test.ts.snap +33 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/g-windows-specifics.test.ts.snap +46 -0
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/j-path-gui-minimal.test.ts.snap +12 -0
- package/packages/shared/src/__tests__/bootstrap/families/a-electron.test.ts +156 -0
- package/packages/shared/src/__tests__/bootstrap/families/b-npm-global.test.ts +157 -0
- package/packages/shared/src/__tests__/bootstrap/families/c-dev-monorepo.test.ts +102 -0
- package/packages/shared/src/__tests__/bootstrap/families/d-overrides.test.ts +76 -0
- package/packages/shared/src/__tests__/bootstrap/families/e-stale-partial.test.ts +94 -0
- package/packages/shared/src/__tests__/bootstrap/families/f-cwd-variants.test.ts +87 -0
- package/packages/shared/src/__tests__/bootstrap/families/g-windows-specifics.test.ts +143 -0
- package/packages/shared/src/__tests__/bootstrap/families/h-home-drift.test.ts +64 -0
- package/packages/shared/src/__tests__/bootstrap/families/i-malformed-settings.test.ts +77 -0
- package/packages/shared/src/__tests__/bootstrap/families/index.ts +19 -0
- package/packages/shared/src/__tests__/bootstrap/families/j-path-gui-minimal.test.ts +61 -0
- package/packages/shared/src/__tests__/bootstrap/families/k-dashboard-absent.test.ts +50 -0
- package/packages/shared/src/__tests__/bootstrap/families/l-instance-coordination.test.ts +272 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/dev-monorepo.ts +58 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/electron-layout.ts +84 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/index.ts +9 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/managed-install.ts +85 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/npm-global-layout.ts +122 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/pi-versions.ts +36 -0
- package/packages/shared/src/__tests__/bootstrap/fixtures/settings-json.ts +39 -0
- package/packages/shared/src/__tests__/bootstrap/harness.smoke.test.ts +220 -0
- package/packages/shared/src/__tests__/bootstrap/harness.ts +413 -0
- package/packages/shared/src/__tests__/bootstrap/scenarios-skipped.ts +125 -0
- package/packages/shared/src/__tests__/bootstrap/scenarios.ts +132 -0
- package/packages/shared/src/__tests__/bridge-register.test.ts +29 -6
- package/packages/shared/src/__tests__/config-openspec.test.ts +106 -0
- package/packages/shared/src/__tests__/config.test.ts +56 -0
- package/packages/shared/src/__tests__/detached-spawn.test.ts +243 -0
- package/packages/shared/src/__tests__/managed-paths.test.ts +60 -0
- package/packages/shared/src/__tests__/no-direct-child-process.test.ts +112 -0
- package/packages/shared/src/__tests__/no-direct-platform-branch.test.ts +174 -0
- package/packages/shared/src/__tests__/no-direct-process-kill.test.ts +105 -0
- package/packages/shared/src/__tests__/no-hardcoded-node-modules-paths.test.ts +176 -0
- package/packages/shared/src/__tests__/no-raw-node-import.test.ts +146 -0
- package/packages/shared/src/__tests__/node-spawn.test.ts +210 -0
- package/packages/shared/src/__tests__/platform-commands.test.ts +108 -0
- package/packages/shared/src/__tests__/platform-exec.test.ts +103 -0
- package/packages/shared/src/__tests__/platform-git.test.ts +194 -0
- package/packages/shared/src/__tests__/platform-npm.test.ts +137 -0
- package/packages/shared/src/__tests__/platform-openspec.test.ts +92 -0
- package/packages/shared/src/__tests__/platform-paths.test.ts +284 -0
- package/packages/shared/src/__tests__/platform-process-scan.test.ts +55 -0
- package/packages/shared/src/__tests__/platform-process.test.ts +160 -0
- package/packages/shared/src/__tests__/platform-runner.test.ts +173 -0
- package/packages/shared/src/__tests__/platform-shell.test.ts +74 -0
- package/packages/shared/src/__tests__/process-identify.test.ts +113 -0
- package/packages/shared/src/__tests__/recommended-extensions.test.ts +40 -7
- package/packages/shared/src/__tests__/resolve-jiti.test.ts +43 -7
- package/packages/shared/src/__tests__/resolve-tool-cli.test.ts +105 -0
- package/packages/shared/src/__tests__/semaphore.test.ts +119 -0
- package/packages/shared/src/__tests__/spawn-mechanism.test.ts +131 -0
- package/packages/shared/src/__tests__/state-replay-entry-id.test.ts +69 -0
- package/packages/shared/src/__tests__/tool-registry-definitions.test.ts +239 -0
- package/packages/shared/src/__tests__/tool-registry-overrides.test.ts +137 -0
- package/packages/shared/src/__tests__/tool-registry-registry.test.ts +343 -0
- package/packages/shared/src/bootstrap-install.ts +212 -0
- package/packages/shared/src/bridge-register.ts +87 -20
- package/packages/shared/src/browser-protocol.ts +71 -1
- package/packages/shared/src/config.ts +87 -15
- package/packages/shared/src/managed-paths.ts +31 -4
- package/packages/shared/src/openspec-poller.ts +63 -46
- package/packages/shared/src/{tool-resolver.ts → platform/binary-lookup.ts} +125 -25
- package/packages/shared/src/platform/commands.ts +100 -0
- package/packages/shared/src/platform/detached-spawn.ts +305 -0
- package/packages/shared/src/platform/exec.ts +220 -0
- package/packages/shared/src/platform/git.ts +155 -0
- package/packages/shared/src/platform/index.ts +16 -0
- package/packages/shared/src/platform/node-spawn.ts +154 -0
- package/packages/shared/src/platform/npm.ts +162 -0
- package/packages/shared/src/platform/openspec.ts +91 -0
- package/packages/shared/src/platform/paths.ts +276 -0
- package/packages/shared/src/platform/process-identify.ts +126 -0
- package/packages/shared/src/platform/process-scan.ts +94 -0
- package/packages/shared/src/platform/process.ts +168 -0
- package/packages/shared/src/platform/runner.ts +369 -0
- package/packages/shared/src/platform/shell.ts +44 -0
- package/packages/shared/src/platform/spawn-mechanism.ts +124 -0
- package/packages/shared/src/platform/subprocess-adapter.ts +124 -0
- package/packages/shared/src/protocol.ts +23 -0
- package/packages/shared/src/recommended-extensions.ts +18 -2
- package/packages/shared/src/resolve-jiti.ts +62 -3
- package/packages/shared/src/rest-api.ts +26 -0
- package/packages/shared/src/semaphore.ts +83 -0
- package/packages/shared/src/state-replay.ts +9 -0
- package/packages/shared/src/tool-registry/definitions.ts +434 -0
- package/packages/shared/src/tool-registry/index.ts +56 -0
- package/packages/shared/src/tool-registry/overrides.ts +118 -0
- package/packages/shared/src/tool-registry/registry.ts +262 -0
- package/packages/shared/src/tool-registry/strategies.ts +198 -0
- package/packages/shared/src/tool-registry/types.ts +180 -0
package/README.md
CHANGED
|
@@ -1,193 +1,168 @@
|
|
|
1
1
|
# PI Dashboard
|
|
2
2
|
|
|
3
3
|
[](https://github.com/BlackBeltTechnology/pi-agent-dashboard/actions/workflows/ci.yml)
|
|
4
|
-
[](https://www.npmjs.com/package/@blackbelt-technology/pi-dashboard)
|
|
4
|
+
[](https://www.npmjs.com/package/@blackbelt-technology/pi-agent-dashboard)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
7
|
A web-based dashboard for monitoring and interacting with [pi](https://github.com/badlogic/pi-mono) agent sessions from any browser, including mobile.
|
|
8
8
|
|
|
9
|
-
**Website:** [blackbelttechnology.github.io/pi-agent-dashboard](https://blackbelttechnology.github.io/pi-agent-dashboard) — animated tour, screenshots, and install guide.
|
|
9
|
+
🌐 **Website & demo:** [blackbelttechnology.github.io/pi-agent-dashboard](https://blackbelttechnology.github.io/pi-agent-dashboard) — animated tour, screenshots, and install guide.
|
|
10
|
+
📝 **Changelog:** [`CHANGELOG.md`](CHANGELOG.md)
|
|
10
11
|
|
|
11
|
-
**
|
|
12
|
+
> **Note:** This dashboard only works with [pi](https://github.com/badlogic/pi-mono). Oh My Pi is **not** supported.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
---
|
|
14
15
|
|
|
15
|
-
##
|
|
16
|
-
|
|
17
|
-
- **Real-time session mirroring** — See all active pi sessions with live streaming messages
|
|
18
|
-
- **Bidirectional interaction** — Send prompts and commands from the browser
|
|
19
|
-
- **Workspace management** — Organize sessions by project folder with pinned directories and drag-to-reorder
|
|
20
|
-
- **Command autocomplete** — `/` prefix triggers command dropdown with filtering
|
|
21
|
-
- **Session statistics** — Token counts, costs, model info, thinking level, context usage bar
|
|
22
|
-
- **Elapsed time tracking** — Live ticking counters on running operations, final duration on completed tool calls and reasoning blocks
|
|
23
|
-
- **Mobile-friendly** — Responsive layout with swipe drawer, touch targets, and mobile action menus
|
|
24
|
-
- **Session spawning** — Launch new pi sessions from the dashboard (headless by default, or via tmux)
|
|
25
|
-
- **PromptBus architecture** — Unified prompt routing with adapters (TUI, dashboard, custom). Interactive dialogs (confirm/select/input/editor/multiselect) survive page refresh and server restart. First-response-wins semantics with cross-adapter dismissal.
|
|
26
|
-
- **On-demand session loading** — Browse historical sessions with lazy-loaded content from pi session files
|
|
27
|
-
- **Integrated terminal** — Full browser-based terminal emulator (xterm.js + node-pty) with ANSI color support, scrollback, and keep-alive
|
|
28
|
-
- **pi-flows integration** — Live flow execution dashboard with agent cards, detail views, flow graph visualization, summary, abort/auto controls. Launch flows and design new ones with the Flow Architect — all from the browser. Fork decisions and subagent dialogs forwarded via PromptBus.
|
|
29
|
-
- **Force kill escalation** — Two-click Stop button (in command bar and on running tool cards): first click sends soft abort, second click force-kills the process (SIGTERM → SIGKILL). Session preserved as "ended" for resume/fork. Repeated tool calls (e.g. health check loops) are auto-collapsed with a count badge.
|
|
30
|
-
- **Searchable select dialogs** — Keyboard-navigable picker with real-time filtering for OpenSpec changes and flow commands
|
|
31
|
-
- **Browser-based provider auth** — Sign in to Anthropic, OpenAI Codex, GitHub Copilot, Gemini CLI, and Antigravity directly from Settings. Enter API keys for other providers. Credentials saved to `~/.pi/agent/auth.json` and live-synced to running sessions.
|
|
32
|
-
- **Package management** — Browse, install, update, and remove pi packages from the dashboard. Search the npm registry for pi-package extensions/skills/themes, install from npm or git URL, manage global packages in Settings and local packages per workspace. All active sessions auto-reload after changes.
|
|
33
|
-
- **OpenSpec integration** — Browse specs, view archive history, manage changes, and create new changes from the session sidebar
|
|
34
|
-
- **Diff viewer** — Side-by-side and unified diff views with file tree navigation for reviewing agent changes
|
|
35
|
-
- **Editor integration** — Open files in your preferred editor (VS Code, Cursor, etc.) directly from tool call cards
|
|
36
|
-
- **Markdown preview** — Rendered markdown views with search, mermaid diagrams, and syntax highlighting
|
|
37
|
-
- **Network discovery** — mDNS-based auto-discovery of other dashboard servers on the local network; connect to known remote servers
|
|
38
|
-
|
|
39
|
-
## Architecture
|
|
40
|
-
|
|
41
|
-
```mermaid
|
|
42
|
-
graph LR
|
|
43
|
-
subgraph "Per pi session"
|
|
44
|
-
B[Bridge Extension]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
subgraph "Dashboard Server (Node.js)"
|
|
48
|
-
PG[Pi Gateway :9999]
|
|
49
|
-
BG[Browser Gateway :8000]
|
|
50
|
-
HTTP[HTTP / Static Files]
|
|
51
|
-
MEM[(In-Memory Store)]
|
|
52
|
-
JSON[(JSON Files)]
|
|
53
|
-
end
|
|
16
|
+
## Table of contents
|
|
54
17
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
| Component | Location | Role |
|
|
70
|
-
|-----------|----------|------|
|
|
71
|
-
| **Bridge Extension** | `packages/extension/` | Runs in every pi session. Forwards events, relays commands, auto-starts server, hosts PromptBus. |
|
|
72
|
-
| **Dashboard Server** | `packages/server/` | Aggregates events in-memory, persists metadata to JSON, serves the web client, manages terminals. |
|
|
73
|
-
| **Web Client** | `packages/client/` | React + Tailwind UI with real-time WebSocket updates. |
|
|
74
|
-
| **Shared** | `packages/shared/` | TypeScript types, protocols, and utilities shared across all packages. |
|
|
18
|
+
- [Quickstart](#quickstart)
|
|
19
|
+
- [Features](#features)
|
|
20
|
+
- [Prerequisites](#prerequisites)
|
|
21
|
+
- [Configuration](#configuration)
|
|
22
|
+
- [Usage](#usage)
|
|
23
|
+
- [Recommended extensions](#recommended-extensions)
|
|
24
|
+
- [Troubleshooting](#troubleshooting)
|
|
25
|
+
- [Architecture](#architecture)
|
|
26
|
+
- [Monitoring](#monitoring)
|
|
27
|
+
- [Development](#development)
|
|
28
|
+
- [Building the Electron app](#building-the-electron-app)
|
|
29
|
+
- [CI/CD & releasing](#cicd--releasing)
|
|
30
|
+
- [License](#license)
|
|
75
31
|
|
|
76
|
-
|
|
32
|
+
---
|
|
77
33
|
|
|
78
|
-
##
|
|
34
|
+
## Quickstart
|
|
79
35
|
|
|
80
|
-
|
|
36
|
+
Three install paths, pick one:
|
|
81
37
|
|
|
82
|
-
###
|
|
38
|
+
### A — Electron desktop app (no prerequisites)
|
|
83
39
|
|
|
84
|
-
Download a pre-built installer from [GitHub Releases](https://github.com/BlackBeltTechnology/pi-agent-dashboard/releases)
|
|
40
|
+
Download a pre-built installer from [GitHub Releases](https://github.com/BlackBeltTechnology/pi-agent-dashboard/releases):
|
|
85
41
|
|
|
86
42
|
| Platform | Download |
|
|
87
43
|
|----------|----------|
|
|
88
|
-
| **macOS** (Apple Silicon) | `.dmg` (arm64) |
|
|
89
|
-
| **
|
|
90
|
-
| **
|
|
91
|
-
| **Linux** (ARM64) | `.deb` |
|
|
92
|
-
| **Windows** (x64) | `.exe` (NSIS installer), `.zip`, or portable `.exe` |
|
|
93
|
-
| **Windows** (ARM64) | `.zip` or portable `.exe` |
|
|
94
|
-
|
|
95
|
-
On first launch, a setup wizard guides you through:
|
|
96
|
-
|
|
97
|
-
1. **Choose a mode:**
|
|
98
|
-
- **Standalone** — Bundles Node.js and auto-installs pi + dashboard + openspec into `~/.pi-dashboard/`. No Node.js, npm, or build tools needed.
|
|
99
|
-
- **Power User** — Uses your existing system-installed pi and dashboard.
|
|
100
|
-
2. **Configure an API key** — Enter your Anthropic/OpenAI key or sign in via browser-based OAuth.
|
|
101
|
-
3. **Recommended extensions** — Install the curated set of pi extensions the dashboard is built to work with (see [Recommended extensions](#recommended-extensions) below). You can skip and manage them later from the Packages tab.
|
|
102
|
-
4. **Done** — The app discovers or spawns a dashboard server automatically.
|
|
103
|
-
|
|
104
|
-
> **No terminal, no npm, no Node.js required.** The Electron app is fully self-contained in standalone mode. It bundles a Node.js runtime, spawns the dashboard server internally, and manages all dependencies. System tray integration keeps it running in the background.
|
|
44
|
+
| **macOS** (Apple Silicon / Intel) | `.dmg` (arm64 / x64) |
|
|
45
|
+
| **Linux** (x64 / ARM64) | `.deb` or `.AppImage` |
|
|
46
|
+
| **Windows** (x64 / ARM64) | `.exe` (NSIS), `.zip`, or portable `.exe` |
|
|
105
47
|
|
|
106
|
-
|
|
48
|
+
On first launch a setup wizard walks you through mode selection (standalone vs. power-user), API key / OAuth sign-in, and [recommended extensions](#recommended-extensions). The standalone mode bundles Node.js and auto-installs pi + dashboard + openspec into `~/.pi-dashboard/` — **no terminal, npm, or Node.js required**.
|
|
107
49
|
|
|
108
|
-
|
|
50
|
+
### B — pi package (recommended for CLI users)
|
|
109
51
|
|
|
110
52
|
```bash
|
|
111
|
-
pi install npm:@blackbelt-technology/pi-dashboard
|
|
53
|
+
pi install npm:@blackbelt-technology/pi-agent-dashboard
|
|
112
54
|
pi
|
|
113
55
|
```
|
|
114
56
|
|
|
115
|
-
The bridge extension auto-starts the dashboard server on first launch
|
|
57
|
+
The bridge extension auto-starts the dashboard server on first launch:
|
|
116
58
|
|
|
117
59
|
```
|
|
118
60
|
🌐 Dashboard started at http://localhost:8000
|
|
119
61
|
```
|
|
120
62
|
|
|
121
|
-
Open **http://localhost:8000** in any browser. All active pi sessions appear automatically.
|
|
63
|
+
Open **http://localhost:8000** in any browser. All active pi sessions appear automatically. See [Prerequisites](#prerequisites) for Node.js / build-tool requirements.
|
|
122
64
|
|
|
123
|
-
###
|
|
65
|
+
### C — From source (contributors)
|
|
124
66
|
|
|
125
67
|
```bash
|
|
126
68
|
git clone https://github.com/BlackBeltTechnology/pi-agent-dashboard.git
|
|
127
69
|
cd pi-agent-dashboard
|
|
128
70
|
npm install
|
|
129
|
-
pi install /path/to/pi-agent-dashboard
|
|
71
|
+
pi install /path/to/pi-agent-dashboard # global
|
|
72
|
+
# or: pi install -l /path/to/pi-agent-dashboard # project-local only
|
|
130
73
|
```
|
|
131
74
|
|
|
132
|
-
## Recommended extensions
|
|
133
|
-
|
|
134
|
-
The dashboard integrates tightly with a small, curated set of pi extensions
|
|
135
|
-
— for custom tool rendering, the Flow dashboard, and anthropic-messages
|
|
136
|
-
protocol compatibility. The wizard's Recommended-extensions step installs
|
|
137
|
-
them in one go; the **Packages** tab and a top-of-page **banner** keep
|
|
138
|
-
them discoverable afterwards.
|
|
139
|
-
|
|
140
|
-
| Extension | Source | Status | Unlocks |
|
|
141
|
-
|---|---|---|---|
|
|
142
|
-
| `pi-anthropic-messages` | `git@github.com:BlackBeltTechnology/pi-anthropic-messages.git` | **required** | Tool calls on Claude-model Anthropic OAuth / 9Router `cc/*` / pi-model-proxy providers. Without it, tool calls fall back to Claude Code's built-in `bash_ide` sandbox and fail. |
|
|
143
|
-
| `@tintinweb/pi-subagents` | `npm:@tintinweb/pi-subagents` | strongly suggested | `Agent` tool card UI, subagent activity badge, `get_subagent_result` / `steer_subagent` renderers. |
|
|
144
|
-
| `pi-flows` | `git@github.com:BlackBeltTechnology/pi-flows.git` | strongly suggested | Flow dashboard, role aliases (`@planning`, `@coding`, …), subagent / flow_write / flow_results / agent_write / ask_user / skill_read / finish tools. |
|
|
145
|
-
| `pi-web-access` | `npm:pi-web-access` | strongly suggested | `web_search`, `code_search`, `fetch_content`, `get_search_content`. |
|
|
146
|
-
| `pi-agent-browser` | `npm:pi-agent-browser` | optional | `browser` tool (open, snapshot, click, screenshot). |
|
|
147
|
-
|
|
148
|
-
Authoritative source of truth: `packages/shared/src/recommended-extensions.ts`.
|
|
149
|
-
Descriptions, versions, and installed-state are enriched live at runtime via
|
|
150
|
-
`GET /api/packages/recommended` (falling back to offline descriptions on
|
|
151
|
-
network failure).
|
|
152
|
-
|
|
153
|
-
### GitHub SSH notes
|
|
154
|
-
|
|
155
|
-
The `pi-flows` and `pi-anthropic-messages` entries install via `pi install
|
|
156
|
-
git@github.com:…` (SSH). If your system doesn't have a GitHub SSH key
|
|
157
|
-
configured the clone will fail with a "Permission denied (publickey)"
|
|
158
|
-
error. Set up a key by following
|
|
159
|
-
[GitHub's SSH docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh),
|
|
160
|
-
or substitute the equivalent HTTPS URL in the manifest if your fork is
|
|
161
|
-
public.
|
|
162
|
-
|
|
163
|
-
### Quick test (without installing)
|
|
164
|
-
|
|
165
75
|
To try the extension in a single pi session without registering it:
|
|
166
76
|
|
|
167
77
|
```bash
|
|
168
78
|
pi -e /path/to/pi-agent-dashboard/packages/extension/src/bridge.ts
|
|
169
79
|
```
|
|
170
80
|
|
|
81
|
+
Remove with `pi remove /path/to/pi-agent-dashboard`. Alternatively, add the package path directly to `~/.pi/agent/settings.json` (global) or `.pi/settings.json` (project) under `"packages": [...]`.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
**Sessions & chat**
|
|
88
|
+
- **Real-time session mirroring** — all active pi sessions with live streaming messages
|
|
89
|
+
- **Bidirectional interaction** — send prompts and commands from the browser
|
|
90
|
+
- **Session statistics** — token counts, costs, model info, thinking level, context usage bar
|
|
91
|
+
- **Elapsed time tracking** — live ticking counters on running operations, final duration on completed tool calls and reasoning blocks
|
|
92
|
+
- **Session spawning** — launch new pi sessions from the dashboard (headless by default, or via tmux)
|
|
93
|
+
- **On-demand session loading** — browse historical sessions with lazy-loaded content from pi session files
|
|
94
|
+
- **Force kill escalation** — two-click Stop button; first click sends soft abort, second force-kills (SIGTERM → SIGKILL). Session preserved as "ended" for resume/fork.
|
|
95
|
+
|
|
96
|
+
**Workspace & UI**
|
|
97
|
+
- **Workspace management** — organize sessions by project folder with pinned directories and drag-to-reorder
|
|
98
|
+
- **Command autocomplete** — `/` prefix triggers a filtering dropdown
|
|
99
|
+
- **Mobile-friendly** — responsive layout with swipe drawer, touch targets, and mobile action menus
|
|
100
|
+
- **Markdown preview** — rendered markdown views with search, mermaid diagrams, and syntax highlighting
|
|
101
|
+
- **Searchable select dialogs** — keyboard-navigable picker with real-time filtering (OpenSpec changes, flow commands)
|
|
102
|
+
|
|
103
|
+
**Integrations**
|
|
104
|
+
- **PromptBus architecture** — unified prompt routing with adapters (TUI, dashboard, custom). Interactive dialogs (confirm/select/input/editor/multiselect) survive page refresh and server restart. First-response-wins semantics with cross-adapter dismissal.
|
|
105
|
+
- **pi-flows integration** — live flow execution dashboard with agent cards, detail views, flow graph, summary, abort/auto controls. Launch flows and design new ones with Flow Architect, all from the browser. Fork decisions and subagent dialogs forwarded via PromptBus.
|
|
106
|
+
- **OpenSpec integration** — browse specs, view archive history, manage changes, create new changes from the sidebar
|
|
107
|
+
- **Browser-based provider auth** — sign in to Anthropic, OpenAI Codex, GitHub Copilot, Gemini CLI, and Antigravity from Settings. Enter API keys for other providers. Credentials saved to `~/.pi/agent/auth.json` and live-synced to running sessions.
|
|
108
|
+
- **Custom LLM providers** — add OpenAI-compatible, Anthropic-compatible, or Google Generative AI endpoints (Settings → Providers → LLM Providers). **Test** button verifies the base URL + API key before saving. Adding / editing / removing takes effect live in every running session — no restart.
|
|
109
|
+
- **Package management** — browse, install, update, and remove pi packages. Search the npm registry for pi-package extensions/skills/themes; install from npm or git URL. Active sessions auto-reload after changes.
|
|
110
|
+
|
|
111
|
+
**Dev tools**
|
|
112
|
+
- **Integrated terminal** — full browser-based terminal emulator (xterm.js + node-pty) with ANSI colors, scrollback, and keep-alive
|
|
113
|
+
- **Diff viewer** — side-by-side and unified diff views with file tree navigation
|
|
114
|
+
- **Editor integration** — open files in VS Code, Cursor, etc. directly from tool call cards
|
|
115
|
+
|
|
116
|
+
**Networking & distribution**
|
|
117
|
+
- **Network discovery** — mDNS-based auto-discovery of other dashboard servers on the local network
|
|
118
|
+
- **Zrok tunnel** — optional persistent public URL via reserved shares (see [Configuration → Tunnel](#tunnel-zrok))
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
171
122
|
## Prerequisites
|
|
172
123
|
|
|
173
|
-
Only needed for
|
|
124
|
+
**Only needed for Quickstart paths B and C.** The Electron app (path A) bundles everything in standalone mode.
|
|
174
125
|
|
|
175
126
|
| Requirement | Why | Install |
|
|
176
127
|
|-------------|-----|---------|
|
|
177
|
-
| **[pi](https://github.com/badlogic/pi-mono)**
|
|
178
|
-
| **Node.js ≥
|
|
179
|
-
| **C++ build tools** | Required by `node-pty` native addon for terminal
|
|
128
|
+
| **[pi](https://github.com/badlogic/pi-mono)** | The AI coding agent the dashboard monitors | `npm i -g @mariozechner/pi-coding-agent` |
|
|
129
|
+
| **Node.js ≥ 22.18.0** | Server runtime. Older 22.x / 24.x < 24.3.0 are affected by [nodejs/node#58515](https://github.com/nodejs/node/issues/58515) which crashes Fastify at startup. | [nodejs.org](https://nodejs.org/) |
|
|
130
|
+
| **C++ build tools** | Required by `node-pty` native addon for the integrated terminal | Xcode CLI Tools (macOS) / `build-essential` (Linux) |
|
|
180
131
|
|
|
181
|
-
|
|
132
|
+
Optional:
|
|
182
133
|
|
|
183
134
|
| Tool | Purpose | When needed |
|
|
184
135
|
|------|---------|-------------|
|
|
185
|
-
| **tmux** | Spawn new pi sessions
|
|
186
|
-
| **[zrok](https://zrok.io/)** |
|
|
136
|
+
| **tmux** | Spawn new pi sessions in a tmux window | When `spawnStrategy` is `"tmux"` |
|
|
137
|
+
| **[zrok](https://zrok.io/)** | Public tunnel with persistent URLs | When `tunnel.enabled` is `true` (default) |
|
|
138
|
+
|
|
139
|
+
---
|
|
187
140
|
|
|
188
141
|
## Configuration
|
|
189
142
|
|
|
190
|
-
Config file
|
|
143
|
+
- **Config file:** `~/.pi/dashboard/config.json` (auto-created with defaults on first run)
|
|
144
|
+
- **Tool overrides (machine-local):** `~/.pi/dashboard/tool-overrides.json` — see [Tool overrides](#tool-overrides)
|
|
145
|
+
- **Settings UI:** click the ⚙ gear icon in the sidebar header to edit all fields from the browser
|
|
146
|
+
|
|
147
|
+
### Precedence & keys
|
|
148
|
+
|
|
149
|
+
CLI flags → environment variables → config file → built-in defaults.
|
|
150
|
+
|
|
151
|
+
| CLI flag | Env var | Config key | Default | Description |
|
|
152
|
+
|----------|---------|------------|---------|-------------|
|
|
153
|
+
| `--port` | `PI_DASHBOARD_PORT` | `port` | `8000` | HTTP + browser WebSocket port |
|
|
154
|
+
| `--pi-port` | `PI_DASHBOARD_PI_PORT` | `piPort` | `9999` | Pi extension WebSocket port |
|
|
155
|
+
| `--dev` | — | — | `false` | Development mode (proxy to Vite) |
|
|
156
|
+
| `--no-tunnel` | — | `tunnel.enabled` | `true` | Disable zrok tunnel |
|
|
157
|
+
| — | — | `autoStart` | `true` | Bridge auto-starts server if not running |
|
|
158
|
+
| — | — | `autoShutdown` | `false` | Server shuts down when idle |
|
|
159
|
+
| — | — | `shutdownIdleSeconds` | `300` | Seconds idle before auto-shutdown |
|
|
160
|
+
| — | — | `spawnStrategy` | `"headless"` | Session spawn mode: `"headless"` or `"tmux"` |
|
|
161
|
+
| — | — | `devBuildOnReload` | `false` | Rebuild client + restart server on `/reload` |
|
|
162
|
+
|
|
163
|
+
The bridge also honours `PI_DASHBOARD_URL=ws://host:port` to point at a remote server instead of localhost.
|
|
164
|
+
|
|
165
|
+
### Minimal `config.json`
|
|
191
166
|
|
|
192
167
|
```json
|
|
193
168
|
{
|
|
@@ -198,32 +173,28 @@ Config file: **`~/.pi/dashboard/config.json`** (auto-created with defaults on fi
|
|
|
198
173
|
"shutdownIdleSeconds": 300,
|
|
199
174
|
"spawnStrategy": "headless",
|
|
200
175
|
"tunnel": { "enabled": true, "reservedToken": "auto-created-on-first-run" },
|
|
201
|
-
"devBuildOnReload": false
|
|
176
|
+
"devBuildOnReload": false,
|
|
177
|
+
"openspec": {
|
|
178
|
+
"pollIntervalSeconds": 30,
|
|
179
|
+
"maxConcurrentSpawns": 3,
|
|
180
|
+
"changeDetection": "mtime",
|
|
181
|
+
"jitterSeconds": 5
|
|
182
|
+
}
|
|
202
183
|
}
|
|
203
184
|
```
|
|
204
185
|
|
|
205
|
-
### Authentication (
|
|
186
|
+
### Authentication (optional)
|
|
206
187
|
|
|
207
|
-
|
|
188
|
+
OAuth2 authentication guards external (tunnel) access. Localhost is always unguarded.
|
|
208
189
|
|
|
209
190
|
```json
|
|
210
191
|
{
|
|
211
192
|
"auth": {
|
|
212
193
|
"secret": "auto-generated-if-omitted",
|
|
213
194
|
"providers": {
|
|
214
|
-
"github":
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
},
|
|
218
|
-
"google": {
|
|
219
|
-
"clientId": "your-google-client-id",
|
|
220
|
-
"clientSecret": "your-google-client-secret"
|
|
221
|
-
},
|
|
222
|
-
"keycloak": {
|
|
223
|
-
"clientId": "your-keycloak-client-id",
|
|
224
|
-
"clientSecret": "your-keycloak-client-secret",
|
|
225
|
-
"issuerUrl": "https://keycloak.example.com/realms/myrealm"
|
|
226
|
-
}
|
|
195
|
+
"github": { "clientId": "...", "clientSecret": "..." },
|
|
196
|
+
"google": { "clientId": "...", "clientSecret": "..." },
|
|
197
|
+
"keycloak": { "clientId": "...", "clientSecret": "...", "issuerUrl": "https://keycloak.example.com/realms/myrealm" }
|
|
227
198
|
},
|
|
228
199
|
"allowedUsers": ["octocat", "user@example.com", "*@company.com"]
|
|
229
200
|
}
|
|
@@ -233,101 +204,70 @@ Add an `auth` section to enable OAuth2 authentication for external (tunnel) acce
|
|
|
233
204
|
| Key | Required | Description |
|
|
234
205
|
|-----|----------|-------------|
|
|
235
206
|
| `auth.secret` | No | JWT signing secret (auto-generated if omitted) |
|
|
236
|
-
| `auth.providers` | Yes | Map of provider
|
|
237
|
-
| `auth.allowedUsers` | No |
|
|
207
|
+
| `auth.providers` | Yes | Map of provider → `{ clientId, clientSecret, issuerUrl? }` |
|
|
208
|
+
| `auth.allowedUsers` | No | Allowlist: usernames, emails, or `*@domain` wildcards. Empty = allow all |
|
|
238
209
|
|
|
239
210
|
**Supported providers:** `github`, `google`, `keycloak`, `oidc` (generic OIDC with `issuerUrl`).
|
|
240
211
|
|
|
241
|
-
**Callback URL:**
|
|
242
|
-
|
|
243
|
-
**Settings UI:** Click the ⚙ gear icon in the sidebar header to open the Settings panel, where all config fields (including auth) can be edited from the browser.
|
|
244
|
-
|
|
245
|
-
**Precedence:** CLI flags → environment variables → config file → built-in defaults.
|
|
246
|
-
|
|
247
|
-
| CLI Flag | Env Var | Config Key | Default | Description |
|
|
248
|
-
|----------|---------|------------|---------|-------------|
|
|
249
|
-
| `--port` | `PI_DASHBOARD_PORT` | `port` | `8000` | HTTP + Browser WebSocket port |
|
|
250
|
-
| `--pi-port` | `PI_DASHBOARD_PI_PORT` | `piPort` | `9999` | Pi extension WebSocket port |
|
|
251
|
-
| `--dev` | — | — | `false` | Development mode (proxy to Vite) |
|
|
252
|
-
| `--no-tunnel` | — | `tunnel.enabled` | `true` | Disable zrok tunnel |
|
|
253
|
-
| — | — | `autoStart` | `true` | Bridge auto-starts server if not running |
|
|
254
|
-
| — | — | `autoShutdown` | `false` | Server shuts down when idle |
|
|
255
|
-
| — | — | `shutdownIdleSeconds` | `300` | Seconds idle before auto-shutdown |
|
|
256
|
-
| — | — | `spawnStrategy` | `"headless"` | Session spawn mode: `"headless"` or `"tmux"` |
|
|
257
|
-
| — | — | `devBuildOnReload` | `false` | Rebuild client + restart server on `/reload` |
|
|
258
|
-
|
|
259
|
-
### Override the server URL
|
|
260
|
-
|
|
261
|
-
By default the bridge connects to `ws://localhost:{piPort}`. To point at a remote server:
|
|
262
|
-
|
|
263
|
-
```bash
|
|
264
|
-
PI_DASHBOARD_URL=ws://192.168.1.100:9999 pi
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Installation Methods
|
|
268
|
-
|
|
269
|
-
### Electron Desktop App (standalone)
|
|
212
|
+
**Callback URL:** register `https://<tunnel-url>/auth/callback/<provider>` in your OAuth provider settings. The tunnel URL is stable across restarts (reserved shares are auto-created).
|
|
270
213
|
|
|
271
|
-
|
|
214
|
+
### Tunnel (zrok)
|
|
272
215
|
|
|
273
|
-
|
|
216
|
+
The dashboard auto-connects a [zrok](https://zrok.io/) tunnel on start when `tunnel.enabled` is `true`. Install with `brew install zrok` (macOS) and run `zrok enable <token>` to enrol — the dashboard reads zrok's own config (`~/.zrok2/environment.json`), no keys are stored in the dashboard. Reserved shares provide persistent URLs across restarts.
|
|
274
217
|
|
|
275
|
-
|
|
276
|
-
# pi
|
|
277
|
-
pi install npm:@blackbelt-technology/pi-dashboard
|
|
278
|
-
|
|
279
|
-
# Oh My Pi
|
|
280
|
-
omp install npm:@blackbelt-technology/pi-dashboard
|
|
281
|
-
```
|
|
218
|
+
### OpenSpec background polling
|
|
282
219
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
### Local development install
|
|
286
|
-
|
|
287
|
-
```bash
|
|
288
|
-
cd /path/to/pi-agent-dashboard
|
|
289
|
-
npm install
|
|
220
|
+
Tune how often the server polls known directories for OpenSpec updates (`openspec` block):
|
|
290
221
|
|
|
291
|
-
|
|
292
|
-
|
|
222
|
+
| Key | Default | Range | Description |
|
|
223
|
+
|-----|---------|-------|-------------|
|
|
224
|
+
| `pollIntervalSeconds` | `30` | `5–3600` | How often each known directory is polled |
|
|
225
|
+
| `maxConcurrentSpawns` | `3` | `1–16` | Cap on concurrent `openspec` CLI invocations |
|
|
226
|
+
| `changeDetection` | `"mtime"` | `"mtime" \| "always"` | `mtime` skips unchanged proposals; `always` polls unconditionally |
|
|
227
|
+
| `jitterSeconds` | `5` | `0–60` | Per-directory phase offset so polls don't align on the same tick |
|
|
293
228
|
|
|
294
|
-
|
|
295
|
-
pi install -l /path/to/pi-agent-dashboard
|
|
296
|
-
```
|
|
229
|
+
Live-reconfigurable via Settings → Advanced → "Background polling (OpenSpec)" or `PUT /api/config` — no server restart needed. See [docs/architecture.md](docs/architecture.md) for the cost model.
|
|
297
230
|
|
|
298
|
-
|
|
231
|
+
### Tool overrides
|
|
299
232
|
|
|
300
|
-
|
|
233
|
+
The dashboard resolves every external tool it calls (`pi`, `pi-coding-agent`, `openspec`, `npm`, `node`, `tsx`, `git`, `zrok`, `pi-dashboard`) through a single `ToolRegistry`. Each tool has an ordered strategy chain (override → managed install → bare-import / npm-global → PATH search), and every resolution records a diagnostic trail.
|
|
301
234
|
|
|
302
|
-
|
|
235
|
+
**Inspecting and overriding** — Settings → General → **Tools** shows every resolved tool, its source, and the trail. You can set a per-tool override path, rescan individually or all at once, and export the full diagnostic report.
|
|
303
236
|
|
|
304
|
-
**
|
|
305
|
-
```json
|
|
306
|
-
{
|
|
307
|
-
"packages": ["/path/to/pi-agent-dashboard"]
|
|
308
|
-
}
|
|
309
|
-
```
|
|
237
|
+
**Overrides file** — `~/.pi/dashboard/tool-overrides.json`:
|
|
310
238
|
|
|
311
|
-
**Project-local** (`.pi/settings.json`):
|
|
312
239
|
```json
|
|
313
240
|
{
|
|
314
|
-
"
|
|
241
|
+
"version": 1,
|
|
242
|
+
"overrides": {
|
|
243
|
+
"pi": { "path": "C:\\custom\\pi.cmd" },
|
|
244
|
+
"pi-coding-agent": { "path": "D:\\dev\\pi-coding-agent\\dist\\index.js" }
|
|
245
|
+
}
|
|
315
246
|
}
|
|
316
247
|
```
|
|
317
248
|
|
|
318
|
-
|
|
249
|
+
The file is deliberately separate from `config.json` so machine-specific paths don't follow a dotfiles sync. Invalid overrides (path doesn't exist) are recorded in the trail and the registry falls through to the next strategy automatically.
|
|
319
250
|
|
|
320
|
-
|
|
321
|
-
pi remove /path/to/pi-agent-dashboard
|
|
322
|
-
```
|
|
251
|
+
---
|
|
323
252
|
|
|
324
253
|
## Usage
|
|
325
254
|
|
|
326
255
|
### Auto-start (default)
|
|
327
256
|
|
|
328
|
-
The bridge extension **automatically starts the dashboard server** when pi launches if it's not already running.
|
|
257
|
+
The bridge extension **automatically starts the dashboard server** when pi launches if it's not already running. Disable with `"autoStart": false` in `~/.pi/dashboard/config.json`.
|
|
329
258
|
|
|
330
|
-
|
|
259
|
+
### Daemon mode
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
pi-dashboard start # background daemon (production)
|
|
263
|
+
pi-dashboard start --dev # dev mode (proxy to Vite, fallback to production build)
|
|
264
|
+
pi-dashboard stop # stop daemon (also kills stale port holders)
|
|
265
|
+
pi-dashboard restart # restart (production)
|
|
266
|
+
pi-dashboard restart --dev # restart in dev mode
|
|
267
|
+
pi-dashboard status # daemon status
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Daemon stdout/stderr is logged to `~/.pi/dashboard/server.log` (append mode with timestamped headers per start).
|
|
331
271
|
|
|
332
272
|
### Manual server start
|
|
333
273
|
|
|
@@ -337,76 +277,183 @@ npx tsx packages/server/src/cli.ts --port 8000 --pi-port 9999
|
|
|
337
277
|
npx tsx packages/server/src/cli.ts --dev # proxy to Vite dev server
|
|
338
278
|
```
|
|
339
279
|
|
|
340
|
-
### Daemon mode
|
|
341
|
-
|
|
342
|
-
```bash
|
|
343
|
-
pi-dashboard start # Start as background daemon (production)
|
|
344
|
-
pi-dashboard start --dev # Start in dev mode (proxy to Vite, fallback to production build)
|
|
345
|
-
pi-dashboard stop # Stop running daemon (also kills stale port holders)
|
|
346
|
-
pi-dashboard restart # Restart daemon (production)
|
|
347
|
-
pi-dashboard restart --dev # Restart in dev mode
|
|
348
|
-
pi-dashboard status # Show daemon status
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
Daemon stdout/stderr is logged to `~/.pi/dashboard/server.log` for crash diagnosis.
|
|
352
|
-
|
|
353
280
|
### Graceful restart via API
|
|
354
281
|
|
|
355
|
-
Restart without CLI — useful from scripts, other sessions, or the dashboard skill:
|
|
356
|
-
|
|
357
282
|
```bash
|
|
358
|
-
# Restart in same mode
|
|
283
|
+
# Restart in the same mode
|
|
359
284
|
curl -X POST http://localhost:8000/api/restart
|
|
360
285
|
|
|
361
|
-
# Switch to dev
|
|
286
|
+
# Switch to dev / production
|
|
362
287
|
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":true}'
|
|
363
|
-
|
|
364
|
-
# Switch to production mode
|
|
365
288
|
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":false}'
|
|
366
289
|
|
|
367
290
|
# Check current mode
|
|
368
291
|
curl -s http://localhost:8000/api/health | jq .mode
|
|
369
292
|
```
|
|
370
293
|
|
|
371
|
-
The restart endpoint waits for the old server to exit, starts the new one, and verifies health.
|
|
294
|
+
The restart endpoint waits for the old server to exit, starts the new one, and verifies health. It works identically on Windows, macOS, and Linux (no `sh` / `lsof` / `curl` dependency).
|
|
372
295
|
|
|
373
296
|
### Dev mode with production fallback
|
|
374
297
|
|
|
375
|
-
When started with `--dev`, the server proxies client requests to the Vite dev server for HMR. If Vite is **not running**,
|
|
298
|
+
When started with `--dev`, the server proxies client requests to the Vite dev server for HMR. If Vite is **not running**, it automatically falls back to serving the production build from `dist/client/`:
|
|
376
299
|
|
|
377
300
|
- `pi-dashboard start --dev` **always works** — no 502 errors
|
|
378
301
|
- Start/stop Vite independently without restarting the dashboard
|
|
379
|
-
-
|
|
302
|
+
- Start Vite later and refresh the browser to get HMR
|
|
380
303
|
|
|
381
|
-
###
|
|
304
|
+
### Dev build on reload
|
|
382
305
|
|
|
383
|
-
|
|
306
|
+
Set `"devBuildOnReload": true` in `config.json` for a one-command full-stack refresh:
|
|
384
307
|
|
|
385
|
-
|
|
308
|
+
```
|
|
309
|
+
/reload → build client → stop server → reload extension → auto-start fresh server
|
|
310
|
+
```
|
|
386
311
|
|
|
387
|
-
|
|
312
|
+
> Blocks pi for ~2–5s during the build. The server shutdown affects all connected sessions — they auto-reconnect when one restarts the server.
|
|
313
|
+
|
|
314
|
+
### Session spawning
|
|
315
|
+
|
|
316
|
+
**Headless** (default) — runs pi as a background process with no terminal attached. Interaction through the web UI.
|
|
317
|
+
|
|
318
|
+
**tmux** — runs pi inside a tmux session named `pi-dashboard`, each spawned session as a new window:
|
|
388
319
|
|
|
389
320
|
```bash
|
|
390
|
-
|
|
391
|
-
tmux
|
|
321
|
+
tmux attach -t pi-dashboard # attach
|
|
322
|
+
tmux list-windows -t pi-dashboard # list windows
|
|
323
|
+
# inside tmux: Ctrl-b n / p / w # next / prev / picker
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Switch with `"spawnStrategy": "tmux"` in `~/.pi/dashboard/config.json`.
|
|
327
|
+
|
|
328
|
+
### Keyboard shortcuts in chat input
|
|
329
|
+
|
|
330
|
+
Bash-style history recall and per-session draft persistence:
|
|
331
|
+
|
|
332
|
+
| Key | Action |
|
|
333
|
+
|-----|--------|
|
|
334
|
+
| `Enter` | Send the prompt |
|
|
335
|
+
| `Shift+Enter` | Insert a newline |
|
|
336
|
+
| `ArrowUp` | Recall previous user prompt (caret on first line, no dropdown open). Repeat to walk back |
|
|
337
|
+
| `ArrowDown` | Walk forward through history (caret on last line). Past the newest entry, restores the in-progress draft |
|
|
338
|
+
| `Escape` | Restore in-progress draft and exit history mode; also cancels pending prompt / dismisses dropdown |
|
|
339
|
+
| `Tab` / `Enter` in dropdown | Accept the highlighted `/command` or `@file` suggestion |
|
|
392
340
|
|
|
393
|
-
|
|
394
|
-
|
|
341
|
+
Drafts (typed-but-unsent text) are persisted per session in `localStorage` under `chat-draft:<sessionId>` and survive navigation (Settings, OpenSpec preview, diffs, …) and full page reloads. Drafts never leak between sessions.
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Recommended extensions
|
|
346
|
+
|
|
347
|
+
The dashboard integrates tightly with a small, curated set of pi extensions — for custom tool rendering, the Flow dashboard, and anthropic-messages protocol compatibility. The Electron wizard installs them in one go; the **Packages** tab and a top-of-page banner keep them discoverable afterwards.
|
|
348
|
+
|
|
349
|
+
| Extension | Source | Status | Unlocks |
|
|
350
|
+
|---|---|---|---|
|
|
351
|
+
| `pi-anthropic-messages` | `git@github.com:BlackBeltTechnology/pi-anthropic-messages.git` | **required** | Tool calls on Claude-model Anthropic OAuth / 9Router `cc/*` / pi-model-proxy providers. Without it, tool calls fall back to Claude Code's built-in `bash_ide` sandbox and fail. |
|
|
352
|
+
| `@tintinweb/pi-subagents` | `npm:@tintinweb/pi-subagents` | strongly suggested | `Agent` tool card UI, subagent activity badge, `get_subagent_result` / `steer_subagent` renderers |
|
|
353
|
+
| `pi-flows` | `git@github.com:BlackBeltTechnology/pi-flows.git` | strongly suggested | Flow dashboard, role aliases (`@planning`, `@coding`, …), subagent / flow_write / flow_results / agent_write / ask_user / skill_read / finish tools |
|
|
354
|
+
| `pi-web-access` | `npm:pi-web-access` | strongly suggested | `web_search`, `code_search`, `fetch_content`, `get_search_content` |
|
|
355
|
+
| `pi-agent-browser` | `npm:pi-agent-browser` | optional | `browser` tool (open, snapshot, click, screenshot) |
|
|
395
356
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
357
|
+
Authoritative source: `packages/shared/src/recommended-extensions.ts`. Descriptions, versions, and installed-state are enriched live via `GET /api/packages/recommended` (offline fallback).
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Troubleshooting
|
|
362
|
+
|
|
363
|
+
### Dashboard server doesn't start
|
|
364
|
+
|
|
365
|
+
If `pi` launches but the dashboard never becomes reachable, inspect the launch log:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
cat ~/.pi/dashboard/server.log # Linux / macOS
|
|
369
|
+
type %USERPROFILE%\.pi\dashboard\server.log # Windows
|
|
400
370
|
```
|
|
401
371
|
|
|
402
|
-
|
|
372
|
+
The log is append-mode with timestamped headers per start attempt, so previous crashes are preserved. Common issues:
|
|
403
373
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
374
|
+
- **`ERR_UNSUPPORTED_ESM_URL_SCHEME` on Windows** — fully fixed in 0.4.0+. The 0.2.10 release wrapped the `--import` loader position as a `file://` URL, but the entry-script position stayed a raw Windows path — which crashed Node on non-`C:` drives (`A:\`, `B:\`, …) because the drive-letter heuristic has gaps there. 0.4.0 routes all four server-spawn call sites through a single `spawnNodeScript` / `toFileUrl` helper that wraps both positions unconditionally, and a repo-level lint test prevents regression. Upgrade the package.
|
|
375
|
+
- **`Cannot find pi's TypeScript loader`** — pi is not installed globally. Run `npm install -g @mariozechner/pi-coding-agent`.
|
|
376
|
+
- **Fastify crash at startup** — you're on Node 22.0.0–22.17.x or 24.1.0–24.2.x which are affected by [nodejs/node#58515](https://github.com/nodejs/node/issues/58515). Upgrade to 22.18+ or 24.3+.
|
|
377
|
+
|
|
378
|
+
### Port already in use
|
|
379
|
+
|
|
380
|
+
- **Windows:** `netstat -ano | findstr :8000` then `taskkill /F /PID <pid>`
|
|
381
|
+
- **Unix:** `lsof -t -i :8000 | xargs kill`
|
|
382
|
+
- Or change `port` in `~/.pi/dashboard/config.json`.
|
|
383
|
+
|
|
384
|
+
### UI is empty or stuck after switching servers
|
|
385
|
+
|
|
386
|
+
Since the `safe-server-switch` release, switching servers via the header dropdown is **transactional**: the UI verifies the target through a short-lived staging WebSocket (5 s timeout) **before** clearing state or writing `localStorage`. If the target is unreachable, nothing changes — a toast appears and you stay on the previous server.
|
|
387
|
+
|
|
388
|
+
If the currently-active server drops for more than 3 s, a yellow **“Disconnected from \<host\>. Retrying…”** banner appears at the top with a **Switch server** button — use it to pick a reachable server.
|
|
389
|
+
|
|
390
|
+
You should no longer need to manually `localStorage.removeItem("pi-dashboard-last-server")` to recover from a bad switch. If you still get stuck, please file an issue.
|
|
391
|
+
|
|
392
|
+
### Windows: sessions die when the dashboard restarts
|
|
393
|
+
|
|
394
|
+
Since the `consolidate-windows-spawn-and-platform-handlers` release, pi sessions on Windows **survive dashboard restart**, matching macOS/Linux behaviour. Previously, killing the dashboard process (Task Manager, Ctrl+C, `/api/restart`, crash) terminated every running pi session because the children were in the server's libuv kill-on-close Job Object. The fix uses `detached: true` so children are excluded from the parent's job.
|
|
395
|
+
|
|
396
|
+
If you previously relied on "closing the dashboard cleans everything up," use the per-session **Force Kill** action instead (or `POST /api/session/:id/force-kill`).
|
|
397
|
+
|
|
398
|
+
### Windows Terminal tab doesn't appear
|
|
399
|
+
|
|
400
|
+
Install Windows Terminal (`wt.exe`) for tabbed interactive sessions — the dashboard prefers it over WSL tmux / headless when available. Windows 11 ships with it; on Windows 10 install from the Microsoft Store.
|
|
401
|
+
|
|
402
|
+
If `wt.exe` is on PATH but launching does nothing, check **Settings → Apps → Advanced app settings → App execution aliases**. If the "wt" alias is disabled, `wt.exe` is found but can't be executed. Enable the alias or uninstall/reinstall Windows Terminal.
|
|
403
|
+
|
|
404
|
+
### Sessions don't group under my pinned folder
|
|
405
|
+
|
|
406
|
+
Since v0.3+, session grouping uses OS-aware path equality (`platform/paths.ts`). Sessions group correctly under a pinned folder even across trailing-separator, separator-style, or case differences (on Windows and macOS).
|
|
407
|
+
|
|
408
|
+
If you still see two entries for what should be one folder, the paths are likely on different Windows drives (`A:\Foo` and `B:\Foo` are different filesystems and never merge) — that's correct behaviour. If the paths really are the same filesystem, file an issue with both the pinned path (Settings → Tools → Export diagnostics) and the session `cwd` from `/api/sessions`.
|
|
409
|
+
|
|
410
|
+
### Tool not found (pi / openspec / npm / …)
|
|
411
|
+
|
|
412
|
+
Open **Settings → General → Tools**, click the chevron next to the failing tool to see the full `tried[]` trail, then either (a) install the missing tool on PATH / in the managed location shown in the trail, or (b) set an explicit override via the row's path input. Hit **Rescan** to pick up the change without a server restart.
|
|
413
|
+
|
|
414
|
+
### Recommended extensions: "Permission denied (publickey)"
|
|
415
|
+
|
|
416
|
+
`pi-flows` and `pi-anthropic-messages` install via SSH (`git@github.com:…`). If your system has no GitHub SSH key, set one up following [GitHub's SSH docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh), or substitute the equivalent HTTPS URL in the manifest if your fork is public.
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Architecture
|
|
421
|
+
|
|
422
|
+
```mermaid
|
|
423
|
+
graph LR
|
|
424
|
+
subgraph "Per pi session"
|
|
425
|
+
B[Bridge Extension]
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
subgraph "Dashboard Server (Node.js)"
|
|
429
|
+
PG[Pi Gateway :9999]
|
|
430
|
+
BG[Browser Gateway :8000]
|
|
431
|
+
HTTP[HTTP / Static Files]
|
|
432
|
+
MEM[(In-Memory Store)]
|
|
433
|
+
JSON[(JSON Files)]
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
subgraph "Browser"
|
|
437
|
+
UI[React Web Client]
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
B <-->|WebSocket| PG
|
|
441
|
+
UI <-->|WebSocket| BG
|
|
442
|
+
UI -->|HTTP| HTTP
|
|
443
|
+
PG --- MEM
|
|
444
|
+
PG --- JSON
|
|
445
|
+
BG --- MEM
|
|
408
446
|
```
|
|
409
447
|
|
|
448
|
+
| Component | Location | Role |
|
|
449
|
+
|-----------|----------|------|
|
|
450
|
+
| **Bridge Extension** | `packages/extension/` | Runs in every pi session. Forwards events, relays commands, auto-starts server, hosts PromptBus. |
|
|
451
|
+
| **Dashboard Server** | `packages/server/` | Aggregates events in-memory, persists metadata to JSON, serves the web client, manages terminals. |
|
|
452
|
+
| **Web Client** | `packages/client/` | React + Tailwind UI with real-time WebSocket updates. |
|
|
453
|
+
| **Shared** | `packages/shared/` | TypeScript types, protocols, and utilities shared across all packages. |
|
|
454
|
+
|
|
455
|
+
See [docs/architecture.md](docs/architecture.md) for detailed data flows, reconnection logic, and persistence model.
|
|
456
|
+
|
|
410
457
|
### Auto-start flow
|
|
411
458
|
|
|
412
459
|
```mermaid
|
|
@@ -424,15 +471,25 @@ flowchart TD
|
|
|
424
471
|
|
|
425
472
|
The server is spawned detached (`child_process.spawn` with `detached: true`, `unref()`), so it outlives the pi session. Duplicate spawn attempts from concurrent pi sessions fail harmlessly with `EADDRINUSE`.
|
|
426
473
|
|
|
427
|
-
|
|
474
|
+
---
|
|
428
475
|
|
|
429
|
-
|
|
476
|
+
## Monitoring
|
|
430
477
|
|
|
478
|
+
The health endpoint provides server and agent process metrics:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
curl -s http://localhost:8000/api/health | jq
|
|
431
482
|
```
|
|
432
|
-
/reload → build client → stop server → reload extension → auto-start fresh server
|
|
433
|
-
```
|
|
434
483
|
|
|
435
|
-
|
|
484
|
+
Returns:
|
|
485
|
+
- `mode` — `"dev"` or `"production"`
|
|
486
|
+
- `server.rss`, `server.heapUsed`, `server.heapTotal` — server memory
|
|
487
|
+
- `server.activeSessions`, `server.totalSessions` — session counts
|
|
488
|
+
- `agents[]` — per-agent metrics (CPU%, RSS, heap, event loop max delay, system load)
|
|
489
|
+
|
|
490
|
+
Agent metrics are collected every 15s via heartbeats and include `eventLoopMaxMs` — useful for diagnosing connection drops during long-running operations.
|
|
491
|
+
|
|
492
|
+
---
|
|
436
493
|
|
|
437
494
|
## Development
|
|
438
495
|
|
|
@@ -467,8 +524,6 @@ pi -e packages/extension/src/bridge.ts # or just `pi` if installed
|
|
|
467
524
|
|
|
468
525
|
### Deploy after changes
|
|
469
526
|
|
|
470
|
-
The `pi-dashboard` command is available globally when the package is installed. After making changes, restart the appropriate components:
|
|
471
|
-
|
|
472
527
|
```bash
|
|
473
528
|
# After client changes (production mode)
|
|
474
529
|
npm run build
|
|
@@ -478,125 +533,15 @@ curl -X POST http://localhost:8000/api/restart
|
|
|
478
533
|
curl -X POST http://localhost:8000/api/restart
|
|
479
534
|
|
|
480
535
|
# After bridge extension changes
|
|
481
|
-
npm run reload
|
|
536
|
+
npm run reload
|
|
482
537
|
|
|
483
538
|
# Full rebuild (e.g., after pulling updates)
|
|
484
539
|
npm run build
|
|
485
540
|
curl -X POST http://localhost:8000/api/restart
|
|
486
541
|
npm run reload
|
|
487
|
-
|
|
488
|
-
# Switch between dev and production mode
|
|
489
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":true}'
|
|
490
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":false}'
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### Project Structure
|
|
494
|
-
|
|
495
|
-
The project is a monorepo with npm workspaces:
|
|
496
|
-
|
|
497
|
-
```
|
|
498
|
-
packages/
|
|
499
|
-
├── shared/ # Shared TypeScript types & utilities
|
|
500
|
-
│ └── src/
|
|
501
|
-
│ ├── protocol.ts # Extension ↔ Server messages
|
|
502
|
-
│ ├── browser-protocol.ts # Server ↔ Browser messages (incl. PromptBus types)
|
|
503
|
-
│ ├── types.ts # Data models
|
|
504
|
-
│ ├── config.ts # Shared config loader
|
|
505
|
-
│ ├── rest-api.ts # REST API types
|
|
506
|
-
│ ├── session-meta.ts # Session metadata sidecar (.meta.json) read/write
|
|
507
|
-
│ ├── state-replay.ts # Event synthesis on reconnect
|
|
508
|
-
│ ├── stats-extractor.ts # Token/cost stats extraction
|
|
509
|
-
│ ├── server-identity.ts # Server detection & identity
|
|
510
|
-
│ ├── mdns-discovery.ts # mDNS network auto-discovery
|
|
511
|
-
│ └── openspec-poller.ts # OpenSpec change data polling
|
|
512
|
-
├── extension/ # Bridge extension (runs in pi)
|
|
513
|
-
│ └── src/
|
|
514
|
-
│ ├── bridge.ts # Main extension entry
|
|
515
|
-
│ ├── connection.ts # WebSocket with reconnection
|
|
516
|
-
│ ├── event-forwarder.ts # Event mapping
|
|
517
|
-
│ ├── flow-event-wiring.ts # pi-flows event forwarding
|
|
518
|
-
│ ├── prompt-bus.ts # PromptBus — unified prompt routing with adapters
|
|
519
|
-
│ ├── dashboard-default-adapter.ts # Default PromptBus adapter for dashboard UI
|
|
520
|
-
│ ├── prompt-expander.ts # Prompt template expansion from disk
|
|
521
|
-
│ ├── provider-register.ts # Provider auth registration & sync
|
|
522
|
-
│ ├── model-tracker.ts # Model selection tracking
|
|
523
|
-
│ ├── source-detector.ts # Session source detection (via .meta.json sidecar)
|
|
524
|
-
│ ├── command-handler.ts # Command relay
|
|
525
|
-
│ ├── server-probe.ts # TCP probe for server detection
|
|
526
|
-
│ ├── server-auto-start.ts # Auto-start logic on session launch
|
|
527
|
-
│ ├── server-launcher.ts # Spawn server as detached process
|
|
528
|
-
│ ├── session-sync.ts # Session history sync
|
|
529
|
-
│ ├── process-metrics.ts # Agent process CPU/memory metrics
|
|
530
|
-
│ ├── process-scanner.ts # Running process detection
|
|
531
|
-
│ ├── git-info.ts # Git branch/remote/PR detection
|
|
532
|
-
│ ├── git-link-builder.ts # GitHub/GitLab permalink generation
|
|
533
|
-
│ └── dev-build.ts # Dev build-on-reload helper
|
|
534
|
-
├── server/ # Dashboard server
|
|
535
|
-
│ └── src/
|
|
536
|
-
│ ├── cli.ts # CLI entry (start/stop/restart/status)
|
|
537
|
-
│ ├── server.ts # HTTP + WebSocket server
|
|
538
|
-
│ ├── pi-gateway.ts # Extension WebSocket gateway
|
|
539
|
-
│ ├── browser-gateway.ts # Browser WebSocket gateway
|
|
540
|
-
│ ├── memory-event-store.ts # In-memory event buffer (LRU, per-session cap, truncation)
|
|
541
|
-
│ ├── memory-session-manager.ts # In-memory session registry
|
|
542
|
-
│ ├── preferences-store.ts # User prefs: hidden sessions, pinned dirs
|
|
543
|
-
│ ├── meta-persistence.ts # Session metadata persistence
|
|
544
|
-
│ ├── session-order-manager.ts # Per-cwd session ordering
|
|
545
|
-
│ ├── session-discovery.ts # Session file scanning & loading
|
|
546
|
-
│ ├── process-manager.ts # tmux/headless session spawning
|
|
547
|
-
│ ├── headless-pid-registry.ts # Track headless process PIDs
|
|
548
|
-
│ ├── editor-registry.ts # Available editor detection
|
|
549
|
-
│ ├── editor-manager.ts # Editor launch & file opening
|
|
550
|
-
│ ├── provider-auth-storage.ts # Provider credential persistence
|
|
551
|
-
│ ├── provider-auth-handlers.ts # OAuth flow handlers
|
|
552
|
-
│ ├── npm-search-proxy.ts # npm registry search proxy
|
|
553
|
-
│ ├── package-manager-wrapper.ts # pi package install/remove
|
|
554
|
-
│ ├── pending-fork-registry.ts # Flow fork decision persistence
|
|
555
|
-
│ ├── tunnel.ts # Zrok tunnel with reserved shares
|
|
556
|
-
│ ├── terminal-manager.ts # Browser terminal sessions (xterm.js + node-pty)
|
|
557
|
-
│ ├── server-pid.ts # PID file for daemon management
|
|
558
|
-
│ ├── auth.ts # OAuth2 authentication
|
|
559
|
-
│ └── json-store.ts # Atomic JSON file helpers
|
|
560
|
-
├── client/ # React web client
|
|
561
|
-
│ └── src/
|
|
562
|
-
│ ├── App.tsx
|
|
563
|
-
│ ├── hooks/ # WebSocket hooks, mobile detection
|
|
564
|
-
│ ├── lib/ # Event reducer, command filter
|
|
565
|
-
│ └── components/ # UI components
|
|
566
|
-
│ ├── FlowDashboard.tsx # Live flow execution view
|
|
567
|
-
│ ├── FlowAgentCard.tsx # Per-agent status cards
|
|
568
|
-
│ ├── FlowGraph.tsx # DAG visualization
|
|
569
|
-
│ ├── FlowArchitect.tsx # Flow designer UI
|
|
570
|
-
│ ├── FlowSummary.tsx # Post-flow result summary
|
|
571
|
-
│ ├── DiffView.tsx # Side-by-side diff viewer
|
|
572
|
-
│ ├── TerminalView.tsx # Browser terminal emulator
|
|
573
|
-
│ ├── PackageBrowser.tsx # Package search & install
|
|
574
|
-
│ ├── ProviderAuthSection.tsx # Provider sign-in UI
|
|
575
|
-
│ ├── SettingsPanel.tsx # Config editor
|
|
576
|
-
│ └── ... # 80+ components
|
|
577
|
-
└── electron/ # Electron desktop app wrapper
|
|
578
|
-
├── src/main.ts
|
|
579
|
-
├── scripts/
|
|
580
|
-
└── resources/
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
## Monitoring
|
|
584
|
-
|
|
585
|
-
The health endpoint provides server and agent process metrics:
|
|
586
|
-
|
|
587
|
-
```bash
|
|
588
|
-
curl -s http://localhost:8000/api/health | jq
|
|
589
542
|
```
|
|
590
543
|
|
|
591
|
-
|
|
592
|
-
- `mode` — `"dev"` or `"production"`
|
|
593
|
-
- `server.rss`, `server.heapUsed`, `server.heapTotal` — server memory
|
|
594
|
-
- `server.activeSessions`, `server.totalSessions` — session counts
|
|
595
|
-
- `agents[]` — per-agent metrics (CPU%, RSS, heap, event loop max delay, system load)
|
|
596
|
-
|
|
597
|
-
Agent metrics are collected every 15s via heartbeats and include `eventLoopMaxMs` — useful for diagnosing connection drops during long-running operations.
|
|
598
|
-
|
|
599
|
-
## Extension UI Events
|
|
544
|
+
### Extension UI events
|
|
600
545
|
|
|
601
546
|
Your own extensions can broadcast UI events to the dashboard:
|
|
602
547
|
|
|
@@ -610,40 +555,40 @@ pi.events.emit("dashboard:ui", {
|
|
|
610
555
|
|
|
611
556
|
Supported methods: `confirm`, `select`, `input`, `notify`.
|
|
612
557
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
The project includes an Electron wrapper at `packages/electron/` that bundles the dashboard as a **fully standalone native desktop app**. Pre-built installers for all platforms are available on [GitHub Releases](https://github.com/BlackBeltTechnology/pi-agent-dashboard/releases) — see [Getting Started](#getting-started) above.
|
|
558
|
+
### Project structure
|
|
616
559
|
|
|
617
|
-
|
|
560
|
+
Monorepo with npm workspaces — top-level layout only. See [AGENTS.md](AGENTS.md) for the full file-by-file index.
|
|
618
561
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
562
|
+
```
|
|
563
|
+
packages/
|
|
564
|
+
├── shared/ # Shared TypeScript types, protocols, config, session-meta helpers
|
|
565
|
+
├── extension/ # Bridge extension (runs inside pi) — WS client, PromptBus, event forwarding, auto-start
|
|
566
|
+
├── server/ # Dashboard server — HTTP + dual WebSocket gateways, in-memory store, terminals, auth, tunnel
|
|
567
|
+
├── client/ # React + Tailwind web client — 80+ components, hooks, event reducer
|
|
568
|
+
└── electron/ # Electron desktop wrapper — wizard, system tray, auto-update, bundled Node.js
|
|
569
|
+
```
|
|
625
570
|
|
|
626
|
-
|
|
571
|
+
---
|
|
627
572
|
|
|
628
|
-
|
|
573
|
+
## Building the Electron app
|
|
629
574
|
|
|
630
|
-
|
|
575
|
+
> **Prerequisites:** Node.js 22.12+; platform-specific tools handled by Electron Forge automatically.
|
|
631
576
|
|
|
632
|
-
|
|
577
|
+
### Native build (current platform)
|
|
633
578
|
|
|
634
579
|
```bash
|
|
635
|
-
npm run electron:build
|
|
636
|
-
npm run electron:build -- --arch x64
|
|
637
|
-
npm run electron:build -- --skip-client
|
|
580
|
+
npm run electron:build # Build for current platform & arch
|
|
581
|
+
npm run electron:build -- --arch x64 # Override architecture
|
|
582
|
+
npm run electron:build -- --skip-client # Skip client rebuild
|
|
638
583
|
```
|
|
639
584
|
|
|
640
585
|
Or step by step:
|
|
641
586
|
|
|
642
587
|
```bash
|
|
643
|
-
npm run build
|
|
588
|
+
npm run build # Build web client
|
|
644
589
|
cd packages/electron
|
|
645
|
-
bash scripts/download-node.sh
|
|
646
|
-
npm run make
|
|
590
|
+
bash scripts/download-node.sh # Download Node.js for bundling
|
|
591
|
+
npm run make # Build installer
|
|
647
592
|
```
|
|
648
593
|
|
|
649
594
|
Output by platform:
|
|
@@ -652,25 +597,22 @@ Output by platform:
|
|
|
652
597
|
|----------|--------|----------|
|
|
653
598
|
| macOS | `.dmg` | `packages/electron/out/make/` |
|
|
654
599
|
| Linux | `.deb` + `.AppImage` | `packages/electron/out/make/` |
|
|
655
|
-
| Windows | `.exe` (NSIS
|
|
600
|
+
| Windows | `.exe` (NSIS) + `.zip` + portable `.exe` | `packages/electron/out/make/` |
|
|
656
601
|
|
|
657
|
-
### Cross-
|
|
602
|
+
### Cross-platform builds (Docker)
|
|
658
603
|
|
|
659
|
-
From macOS or Linux,
|
|
604
|
+
From macOS or Linux, build installers for all platforms:
|
|
660
605
|
|
|
661
606
|
```bash
|
|
662
|
-
npm run electron:build -- --all
|
|
663
|
-
npm run electron:build -- --linux
|
|
664
|
-
npm run electron:build -- --windows
|
|
607
|
+
npm run electron:build -- --all # macOS (native) + Linux + Windows (Docker)
|
|
608
|
+
npm run electron:build -- --linux # Linux .deb + .AppImage only
|
|
609
|
+
npm run electron:build -- --windows # Windows .exe (NSIS) only
|
|
665
610
|
npm run electron:build -- --linux --windows # Both, skip native
|
|
666
611
|
```
|
|
667
612
|
|
|
668
|
-
Docker builds use a Node 22 Debian container with NSIS installed for Windows cross-compilation.
|
|
669
|
-
All output goes to `packages/electron/out/make/`.
|
|
613
|
+
Docker builds use a Node 22 Debian container with NSIS installed for Windows cross-compilation. Output goes to `packages/electron/out/make/`.
|
|
670
614
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
### Development Mode
|
|
615
|
+
### Electron dev mode
|
|
674
616
|
|
|
675
617
|
```bash
|
|
676
618
|
# Start the dashboard server and Vite dev server first
|
|
@@ -682,7 +624,7 @@ cd packages/electron
|
|
|
682
624
|
npm run start:dev
|
|
683
625
|
```
|
|
684
626
|
|
|
685
|
-
### Regenerating
|
|
627
|
+
### Regenerating icons
|
|
686
628
|
|
|
687
629
|
All platform icon variants are generated from the master icon at `packages/electron/resources/icon.png`:
|
|
688
630
|
|
|
@@ -691,9 +633,31 @@ cd packages/electron
|
|
|
691
633
|
npm run icons # Generates .icns (macOS), .ico (Windows), and resized PNGs
|
|
692
634
|
```
|
|
693
635
|
|
|
694
|
-
|
|
636
|
+
---
|
|
637
|
+
|
|
638
|
+
## CI/CD & releasing
|
|
639
|
+
|
|
640
|
+
See [`docs/release-process.md`](docs/release-process.md) for the full cut-a-release workflow.
|
|
641
|
+
|
|
642
|
+
### Continuous integration
|
|
643
|
+
|
|
644
|
+
Every push to `develop` and every pull request against `develop` triggers [`ci.yml`](.github/workflows/ci.yml):
|
|
645
|
+
|
|
646
|
+
1. `npm ci` — install dependencies
|
|
647
|
+
2. `npm run lint` — type check
|
|
648
|
+
3. `npm test` — run tests
|
|
649
|
+
4. `npm run build` — build web client
|
|
650
|
+
|
|
651
|
+
### Releasing
|
|
695
652
|
|
|
696
|
-
The
|
|
653
|
+
The publish workflow ([`publish.yml`](.github/workflows/publish.yml)) triggers on `v*` tags:
|
|
654
|
+
|
|
655
|
+
```bash
|
|
656
|
+
npm version patch # or minor / major
|
|
657
|
+
git push --follow-tags
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
This runs CI, publishes to npm with `--provenance` for supply-chain transparency, and builds Electron installers for all platforms on native runners:
|
|
697
661
|
|
|
698
662
|
| Runner | Platform | Outputs |
|
|
699
663
|
|--------|----------|---------|
|
|
@@ -703,37 +667,51 @@ The release workflow (`.github/workflows/publish.yml`) builds Electron installer
|
|
|
703
667
|
| `windows-latest` | Windows x64 | `.exe` (NSIS) + `.zip` + portable |
|
|
704
668
|
| `windows-latest` | Windows arm64 | `.zip` + portable (x64 Node.js via WoW64) |
|
|
705
669
|
|
|
706
|
-
All artifacts are uploaded to a **draft GitHub Release
|
|
670
|
+
All artifacts are uploaded to a **draft GitHub Release**. Release notes are extracted automatically from the matching `## [<version>]` section of [`CHANGELOG.md`](CHANGELOG.md).
|
|
707
671
|
|
|
708
|
-
|
|
672
|
+
### Trusted Publisher (OIDC) setup
|
|
709
673
|
|
|
710
|
-
|
|
674
|
+
The publish workflow uses **[npm Trusted Publishers](https://docs.npmjs.com/trusted-publishers)** over OIDC — **no `NPM_TOKEN` secret required**. Short-lived, workflow-scoped credentials are exchanged between GitHub and npm at publish time, and every release carries automatic [npm provenance](https://docs.npmjs.com/generating-provenance-statements) tying the published artifact to the exact workflow run.
|
|
711
675
|
|
|
712
|
-
|
|
676
|
+
**Requirements** (already configured in [`publish.yml`](.github/workflows/publish.yml)):
|
|
713
677
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
678
|
+
```yaml
|
|
679
|
+
permissions:
|
|
680
|
+
contents: write # draft GitHub Release + tag push
|
|
681
|
+
id-token: write # OIDC token exchange with the npm registry
|
|
682
|
+
environment: npm-publish
|
|
683
|
+
```
|
|
718
684
|
|
|
719
|
-
|
|
685
|
+
Trusted Publishing requires **npm CLI ≥ 11.5.1**. The workflow upgrades npm automatically (`npm install -g npm@latest`) before publishing.
|
|
720
686
|
|
|
721
|
-
|
|
687
|
+
**One-time npm-side setup** — repeat once per published package (five scoped workspaces; `@blackbelt-technology/pi-dashboard-electron` is private and skipped):
|
|
722
688
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
689
|
+
| Package |
|
|
690
|
+
|---|
|
|
691
|
+
| `@blackbelt-technology/pi-agent-dashboard` (root) |
|
|
692
|
+
| `@blackbelt-technology/pi-dashboard-shared` |
|
|
693
|
+
| `@blackbelt-technology/pi-dashboard-extension` |
|
|
694
|
+
| `@blackbelt-technology/pi-dashboard-server` |
|
|
695
|
+
| `@blackbelt-technology/pi-dashboard-web` |
|
|
696
|
+
|
|
697
|
+
For each:
|
|
698
|
+
|
|
699
|
+
1. Go to [npmjs.com](https://www.npmjs.com/) → the package → **Settings** → **Trusted Publisher** → **GitHub Actions**
|
|
700
|
+
2. Fill in:
|
|
701
|
+
- **Organization or user:** `BlackBeltTechnology`
|
|
702
|
+
- **Repository:** `pi-agent-dashboard`
|
|
703
|
+
- **Workflow filename:** `publish.yml` *(filename only, not the full path)*
|
|
704
|
+
- **Environment name:** `npm-publish` *(must match the `environment:` field in the workflow)*
|
|
705
|
+
3. Save
|
|
727
706
|
|
|
728
|
-
|
|
707
|
+
**GitHub Environment (recommended)** — configures an optional human-approval gate on every release:
|
|
729
708
|
|
|
730
|
-
|
|
709
|
+
1. GitHub repo → **Settings** → **Environments** → **New environment** → name `npm-publish`
|
|
710
|
+
2. Optionally add **required reviewers** and/or **deployment branch/tag protection rules** (e.g. restrict to `v*` tags)
|
|
731
711
|
|
|
732
|
-
|
|
712
|
+
No secrets to rotate, no tokens to leak.
|
|
733
713
|
|
|
734
|
-
|
|
735
|
-
2. Grant publish access to `@blackbelt-technology` packages
|
|
736
|
-
3. Add it as a repository secret: GitHub repo → Settings → Secrets and variables → Actions → New repository secret → Name: `NPM_TOKEN`
|
|
714
|
+
---
|
|
737
715
|
|
|
738
716
|
## License
|
|
739
717
|
|