@blackbelt-technology/pi-agent-dashboard 0.4.5 → 0.5.0

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.
Files changed (133) hide show
  1. package/AGENTS.md +342 -267
  2. package/README.md +51 -2
  3. package/docs/architecture.md +266 -25
  4. package/package.json +14 -4
  5. package/packages/extension/package.json +2 -2
  6. package/packages/extension/src/__tests__/build-provider-catalogue.test.ts +176 -0
  7. package/packages/extension/src/__tests__/markdown-image-inliner.test.ts +355 -0
  8. package/packages/extension/src/__tests__/openspec-activity-detector.test.ts +68 -0
  9. package/packages/extension/src/__tests__/prompt-bus.test.ts +44 -0
  10. package/packages/extension/src/__tests__/prompt-expander.test.ts +45 -0
  11. package/packages/extension/src/__tests__/server-launcher.test.ts +24 -1
  12. package/packages/extension/src/__tests__/vcs-info-jj.test.ts +145 -0
  13. package/packages/extension/src/__tests__/{git-info.test.ts → vcs-info.test.ts} +6 -6
  14. package/packages/extension/src/bridge-context.ts +7 -0
  15. package/packages/extension/src/bridge.ts +142 -4
  16. package/packages/extension/src/command-handler.ts +6 -0
  17. package/packages/extension/src/markdown-image-inliner.ts +268 -0
  18. package/packages/extension/src/model-tracker.ts +35 -1
  19. package/packages/extension/src/prompt-bus.ts +4 -3
  20. package/packages/extension/src/prompt-expander.ts +50 -2
  21. package/packages/extension/src/provider-register.ts +117 -0
  22. package/packages/extension/src/server-launcher.ts +18 -1
  23. package/packages/extension/src/session-sync.ts +6 -1
  24. package/packages/extension/src/vcs-info.ts +184 -0
  25. package/packages/server/package.json +4 -4
  26. package/packages/server/src/__tests__/auto-attach-slug-defense.test.ts +104 -0
  27. package/packages/server/src/__tests__/bootstrap-install-from-list.test.ts +263 -0
  28. package/packages/server/src/__tests__/browser-gateway-snapshot-on-connect.test.ts +143 -0
  29. package/packages/server/src/__tests__/build-auth-status.test.ts +190 -0
  30. package/packages/server/src/__tests__/cold-boot-openspec-broadcast.test.ts +161 -0
  31. package/packages/server/src/__tests__/doctor-route.test.ts +132 -0
  32. package/packages/server/src/__tests__/event-wiring-providers-list.test.ts +87 -0
  33. package/packages/server/src/__tests__/has-openspec-dir.test.ts +64 -0
  34. package/packages/server/src/__tests__/health-shape.test.ts +43 -0
  35. package/packages/server/src/__tests__/idle-timer-respects-terminals.test.ts +115 -0
  36. package/packages/server/src/__tests__/is-unread-trigger.test.ts +4 -2
  37. package/packages/server/src/__tests__/jj-routes.test.ts +93 -0
  38. package/packages/server/src/__tests__/openspec-connect-snapshot.test.ts +92 -0
  39. package/packages/server/src/__tests__/openspec-tasks-parser.test.ts +114 -0
  40. package/packages/server/src/__tests__/pi-core-updater-managed-path.test.ts +177 -0
  41. package/packages/server/src/__tests__/process-manager-codes.test.ts +80 -0
  42. package/packages/server/src/__tests__/process-manager-managed-path.test.ts +73 -0
  43. package/packages/server/src/__tests__/provider-auth-storage.test.ts +42 -11
  44. package/packages/server/src/__tests__/provider-catalogue-cache.test.ts +54 -0
  45. package/packages/server/src/__tests__/session-action-handler-spawn-error.test.ts +17 -2
  46. package/packages/server/src/__tests__/session-action-handler-spawn.test.ts +150 -0
  47. package/packages/server/src/__tests__/session-diff-vcs.test.ts +61 -0
  48. package/packages/server/src/__tests__/session-discovery-skill-firstmessage.test.ts +95 -0
  49. package/packages/server/src/__tests__/spawn-failure-log.test.ts +118 -0
  50. package/packages/server/src/__tests__/spawn-preflight.test.ts +91 -0
  51. package/packages/server/src/__tests__/spawn-register-watchdog.test.ts +166 -0
  52. package/packages/server/src/__tests__/subscription-handler.test.ts +98 -6
  53. package/packages/server/src/__tests__/system-routes-reextract.test.ts +91 -0
  54. package/packages/server/src/__tests__/system-routes-restart.test.ts +4 -4
  55. package/packages/server/src/__tests__/system-routes-spawn-failures.test.ts +84 -0
  56. package/packages/server/src/__tests__/terminal-manager.test.ts +45 -0
  57. package/packages/server/src/bootstrap-install-from-list.ts +232 -0
  58. package/packages/server/src/bootstrap-state.ts +18 -0
  59. package/packages/server/src/browser-gateway.ts +58 -21
  60. package/packages/server/src/browser-handlers/directory-handler.ts +4 -0
  61. package/packages/server/src/browser-handlers/session-action-handler.ts +60 -2
  62. package/packages/server/src/browser-handlers/subscription-handler.ts +50 -3
  63. package/packages/server/src/cli.ts +22 -0
  64. package/packages/server/src/directory-service.ts +31 -0
  65. package/packages/server/src/event-wiring.ts +57 -2
  66. package/packages/server/src/home-lock.d.ts +124 -0
  67. package/packages/server/src/home-lock.js +330 -0
  68. package/packages/server/src/home-lock.js.map +1 -0
  69. package/packages/server/src/idle-timer.ts +15 -1
  70. package/packages/server/src/openspec-tasks.ts +50 -19
  71. package/packages/server/src/pi-core-updater.ts +65 -9
  72. package/packages/server/src/pi-gateway.ts +6 -0
  73. package/packages/server/src/process-manager.ts +62 -11
  74. package/packages/server/src/provider-auth-handlers.ts +9 -0
  75. package/packages/server/src/provider-auth-storage.ts +83 -51
  76. package/packages/server/src/provider-catalogue-cache.ts +41 -0
  77. package/packages/server/src/routes/doctor-routes.ts +140 -0
  78. package/packages/server/src/routes/jj-routes.ts +386 -0
  79. package/packages/server/src/routes/provider-auth-routes.ts +9 -0
  80. package/packages/server/src/routes/session-routes.ts +12 -3
  81. package/packages/server/src/routes/system-routes.ts +38 -1
  82. package/packages/server/src/server.ts +16 -9
  83. package/packages/server/src/session-bootstrap.ts +27 -12
  84. package/packages/server/src/session-diff.ts +118 -1
  85. package/packages/server/src/session-discovery.ts +10 -3
  86. package/packages/server/src/session-scanner.ts +4 -2
  87. package/packages/server/src/spawn-failure-log.ts +130 -0
  88. package/packages/server/src/spawn-preflight.ts +82 -0
  89. package/packages/server/src/spawn-register-watchdog.ts +236 -0
  90. package/packages/server/src/terminal-manager.ts +12 -1
  91. package/packages/shared/package.json +1 -1
  92. package/packages/shared/src/__tests__/bootstrap/__snapshots__/cube.test.ts.snap +1 -0
  93. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/g-windows-specifics.test.ts.snap +1 -0
  94. package/packages/shared/src/__tests__/bootstrap-install-resolve-npm.test.ts +72 -0
  95. package/packages/shared/src/__tests__/browser-protocol-types.test.ts +47 -1
  96. package/packages/shared/src/__tests__/config.test.ts +48 -0
  97. package/packages/shared/src/__tests__/dashboard-starter.test.ts +40 -0
  98. package/packages/shared/src/__tests__/detached-spawn.test.ts +24 -0
  99. package/packages/shared/src/__tests__/doctor-core.test.ts +134 -0
  100. package/packages/shared/src/__tests__/doctor-fault-tolerance.test.ts +218 -0
  101. package/packages/shared/src/__tests__/doctor-format.test.ts +121 -0
  102. package/packages/shared/src/__tests__/install-managed-node-bootstrap-order.test.ts +68 -0
  103. package/packages/shared/src/__tests__/install-managed-node.test.ts +192 -0
  104. package/packages/shared/src/__tests__/installable-list.test.ts +130 -0
  105. package/packages/shared/src/__tests__/managed-node-path.test.ts +122 -0
  106. package/packages/shared/src/__tests__/managed-runtime-strategy.test.ts +74 -0
  107. package/packages/shared/src/__tests__/no-installable-list-in-bridge.test.ts +52 -0
  108. package/packages/shared/src/__tests__/no-raw-openspec-status-in-skills.test.ts +6 -1
  109. package/packages/shared/src/__tests__/platform-jj.test.ts +339 -0
  110. package/packages/shared/src/__tests__/skill-block-parser.test.ts +153 -0
  111. package/packages/shared/src/__tests__/tool-registry-definitions.test.ts +18 -2
  112. package/packages/shared/src/bootstrap-install.ts +196 -2
  113. package/packages/shared/src/browser-protocol.ts +112 -1
  114. package/packages/shared/src/config.ts +29 -0
  115. package/packages/shared/src/dashboard-starter.ts +33 -0
  116. package/packages/shared/src/diff-types.ts +17 -0
  117. package/packages/shared/src/doctor-core.ts +821 -0
  118. package/packages/shared/src/index.ts +9 -0
  119. package/packages/shared/src/installable-list.ts +152 -0
  120. package/packages/shared/src/launch-source-flag.ts +14 -0
  121. package/packages/shared/src/launch-source-types.ts +18 -0
  122. package/packages/shared/src/openspec-activity-detector.ts +25 -7
  123. package/packages/shared/src/platform/detached-spawn.ts +13 -2
  124. package/packages/shared/src/platform/jj.ts +405 -0
  125. package/packages/shared/src/platform/managed-node-path.ts +77 -0
  126. package/packages/shared/src/protocol.ts +60 -2
  127. package/packages/shared/src/rest-api.ts +4 -0
  128. package/packages/shared/src/skill-block-parser.ts +115 -0
  129. package/packages/shared/src/tool-registry/__tests__/managed-runtime-strategy.test.ts +166 -0
  130. package/packages/shared/src/tool-registry/definitions.ts +19 -5
  131. package/packages/shared/src/tool-registry/strategies.ts +42 -0
  132. package/packages/shared/src/types.ts +91 -0
  133. package/packages/extension/src/git-info.ts +0 -55
package/README.md CHANGED
@@ -21,6 +21,7 @@ A web-based dashboard for monitoring and interacting with [pi](https://github.co
21
21
  - [Configuration](#configuration)
22
22
  - [Usage](#usage)
23
23
  - [Recommended extensions](#recommended-extensions)
24
+ - [Authoring a dashboard plugin](#authoring-a-dashboard-plugin)
24
25
  - [Troubleshooting](#troubleshooting)
25
26
  - [Architecture](#architecture)
26
27
  - [Monitoring](#monitoring)
@@ -47,6 +48,10 @@ Download a pre-built installer from [GitHub Releases](https://github.com/BlackBe
47
48
 
48
49
  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**.
49
50
 
51
+ **Picking the right macOS DMG:** run `uname -m` in Terminal — `arm64` means Apple Silicon (M1/M2/M3/M4), `x86_64` means Intel. Or open  Apple menu → About This Mac and read the chip name. Download the matching DMG; if you grab the wrong one macOS will refuse to launch the app with a "cannot be opened" error.
52
+
53
+ > **Note:** A future release will rename the macOS DMGs to `PI-Dashboard-darwin-arm64-<ver>.dmg` and `PI-Dashboard-darwin-x64-<ver>.dmg` (previously a single `PI Dashboard.dmg` was produced and silently overwrote one arch on each release). Direct download links pointing at the unsuffixed filename will 404 from that release onward; please link to the [Releases page](https://github.com/BlackBeltTechnology/pi-agent-dashboard/releases) instead. See OpenSpec change `fix-darwin-dmg-arch-collision`.
54
+
50
55
  ### B — pi package (recommended for CLI users)
51
56
 
52
57
  ```bash
@@ -98,6 +103,7 @@ Remove with `pi remove /path/to/pi-agent-dashboard`. Alternatively, add the pack
98
103
  - **Command autocomplete** — `/` prefix triggers a filtering dropdown
99
104
  - **Mobile-friendly** — responsive layout with swipe drawer, touch targets, and mobile action menus
100
105
  - **Markdown preview** — rendered markdown views with search, mermaid diagrams, syntax highlighting, and safe handling for raw HTML `ref` attributes
106
+ - **Local-image inlining + LaTeX math in chat** — agents can reference local screenshots inline as `![alt](/abs/path.png)` or `![alt](./relative.png)` and they render in chat (the bridge inlines bytes via a streaming-safe `pi-asset:<hash>` channel — each unique image's bytes ride exactly once per session, no matter how many streaming chunks repeat the token). Math expressions — inline `$x = \beta$` and display `$$\sum_i^n i$$` (block-level) — are typeset via KaTeX. PNG / JPEG / GIF / WebP / SVG / AVIF / BMP supported with a 5 MB-per-image, 20 MB-per-message cap; oversized or unreadable references render as a visible placeholder rather than a broken-image glyph. The dashboard server adds zero new HTTP routes.
101
107
  - **Searchable select dialogs** — keyboard-navigable picker with real-time filtering (OpenSpec changes, flow commands)
102
108
 
103
109
  **Integrations**
@@ -111,8 +117,9 @@ Remove with `pi remove /path/to/pi-agent-dashboard`. Alternatively, add the pack
111
117
 
112
118
  **Dev tools**
113
119
  - **Integrated terminal** — full browser-based terminal emulator (xterm.js + node-pty) with ANSI colors, scrollback, and keep-alive
114
- - **Diff viewer** — side-by-side and unified diff views with file tree navigation
120
+ - **Diff viewer** — side-by-side and unified diff views with file tree navigation. In Jujutsu workspaces the diff is regime-aware: shows the cumulative changes since the workspace's branch point, not just the working-copy delta.
115
121
  - **Editor integration** — open files in VS Code, Cursor, etc. directly from tool call cards
122
+ - **Jujutsu workspaces (optional)** — when `jj` is on PATH and the session is inside a `.jj/` repo, the dashboard surfaces a workspace badge, a `+ Workspace` action that creates `jj workspace add` + spawns a fresh agent in it, and a `Fold back` action that drives the [`jj-workspace-fold-back`](.pi/skills/jj-workspace-fold-back/SKILL.md) skill (jj-native rebase + push, never `git commit`/`git merge`). Activates silently — zero UI when `jj` is not installed. See [docs/architecture.md](docs/architecture.md#jujutsu-workspaces) for the data flow.
116
123
 
117
124
  **Networking & distribution**
118
125
  - **Network discovery** — mDNS-based auto-discovery of other dashboard servers on the local network
@@ -161,6 +168,7 @@ CLI flags → environment variables → config file → built-in defaults.
161
168
  | — | — | `spawnStrategy` | `"headless"` | Session spawn mode: `"headless"` or `"tmux"` |
162
169
  | — | — | `reattachPlacement` | `"always"` | After a dashboard restart, where re-registering bridges land in folder lists. `"always"` (top), `"streaming-only"` (only mid-completion), `"preserve"` (legacy: keep prior drag order) |
163
170
  | — | — | `devBuildOnReload` | `false` | Rebuild client + restart server on `/reload` |
171
+ | — | — | `askUserPromptTimeoutSeconds` | `300` | `ask_user` prompt timeout in seconds. `≤ 0` (e.g. `-1`) = wait indefinitely |
164
172
 
165
173
  The bridge also honours `PI_DASHBOARD_URL=ws://host:port` to point at a remote server instead of localhost.
166
174
 
@@ -176,6 +184,7 @@ The bridge also honours `PI_DASHBOARD_URL=ws://host:port` to point at a remote s
176
184
  "spawnStrategy": "headless",
177
185
  "tunnel": { "enabled": true, "reservedToken": "auto-created-on-first-run" },
178
186
  "devBuildOnReload": false,
187
+ "askUserPromptTimeoutSeconds": 300,
179
188
  "openspec": {
180
189
  "pollIntervalSeconds": 30,
181
190
  "maxConcurrentSpawns": 3,
@@ -213,6 +222,8 @@ OAuth2 authentication guards external (tunnel) access. Localhost is always ungua
213
222
 
214
223
  **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).
215
224
 
225
+ > **Security note:** `/api/spawn-failures` is reachable to any caller on deployments without auth; entries contain `cwd` paths. Enable auth before exposing via tunnel.
226
+
216
227
  ### Tunnel (zrok)
217
228
 
218
229
  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.
@@ -258,6 +269,10 @@ The file is deliberately separate from `config.json` so machine-specific paths d
258
269
 
259
270
  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`.
260
271
 
272
+ In the Electron app, if the initial launch attempts fail (or the server is stopped externally), the **loading page exposes a Start server button**, an **Open Doctor link**, and a collapsible **Server log** panel showing the last 20 lines of `~/.pi/dashboard/server.log`. The system tray menu also includes a **Start server / Restart server** item that reflects current server state. All entry points share a single idempotent launch routine in the Electron main process.
273
+
274
+ **Doctor diagnostics.** Help → Doctor (or the loading-page link) opens a styled `BrowserWindow` (`doctor.html`) that runs the same checks the Electron app already performed — grouped into sections (Runtime, Pi, Server, Bundles, Diagnostics) with status pills, paths, and per-row suggestion callouts; toolbar offers Re-run, Copy as Markdown / Plain, Open server log, Open doctor log, Run setup wizard. The web client exposes the portable subset at **Settings → Diagnostics**, which fetches `/api/doctor` and renders the same sections (Electron-only rows omitted). Both surfaces share `packages/shared/src/doctor-core.ts`, so a check defined once shows up everywhere.
275
+
261
276
  ### Daemon mode
262
277
 
263
278
  ```bash
@@ -360,6 +375,29 @@ Authoritative source: `packages/shared/src/recommended-extensions.ts`. Descripti
360
375
 
361
376
  ---
362
377
 
378
+ ## Authoring a dashboard plugin
379
+
380
+ The dashboard's UI is composed of named **slots** that plugins claim with React components. To create a new plugin, install the scaffolding skill:
381
+
382
+ ```bash
383
+ npm i -g @blackbelt-technology/pi-dashboard-plugin-skill
384
+ ```
385
+
386
+ Then, from any pi session:
387
+
388
+ ```
389
+ /skill dashboard-plugin-scaffold
390
+ ```
391
+
392
+ The skill has two modes:
393
+
394
+ - **`new`** — scaffold a fresh `packages/<id>-plugin/` inside this monorepo. Pick which of the 10 React slots to claim (`session-card-badge`, `content-view`, `settings-section`, `tool-renderer`, …); the skill renders package.json (with `pi-dashboard-plugin` manifest), `src/client.tsx` with stubs, optional `src/server/index.ts`, optional `src/bridge/index.ts`, `configSchema.json`, and tests.
395
+ - **`augment`** — retrofit an existing pi-extension project on disk. The skill greps for TUI surface (`ctx.ui.*`, `pi.registerTool`, …), drives the agent through a canonical mapping table, asks per-callsite what to port, then injects a manifest field into `package.json` and adds `src/dashboard/`. Purely additive — your existing TUI keeps working in pure-pi sessions.
396
+
397
+ For the slot taxonomy, the manifest schema, and the plugin context API, see the skill's reference docs (or the runtime: [`@blackbelt-technology/dashboard-plugin-runtime`](https://www.npmjs.com/package/@blackbelt-technology/dashboard-plugin-runtime)). The reference fixture is [`packages/demo-plugin/`](packages/demo-plugin/).
398
+
399
+ ---
400
+
363
401
  ## Troubleshooting
364
402
 
365
403
  ### Dashboard server doesn't start
@@ -615,6 +653,16 @@ npm run electron:build -- --windows # Windows .exe (NSIS) only
615
653
  npm run electron:build -- --linux --windows # Both, skip native
616
654
  ```
617
655
 
656
+ ### Building both macOS DMGs locally (`--mac-both`)
657
+
658
+ On an Apple Silicon mac, produce both the arm64 and Intel x64 DMGs in one invocation:
659
+
660
+ ```bash
661
+ npm run electron:build -- --mac-both
662
+ ```
663
+
664
+ Requires Rosetta 2 (`softwareupdate --install-rosetta --agree-to-license`) so node-pty's x64 prebuilt binary can be unpacked during the cross-arch run. The script wipes per-arch caches between the two builds (`resources/.last-arch` sentinel) so back-to-back runs don't accidentally ship arm64 binaries inside an x64 DMG. Intel macs cannot cross-build arm64 locally (Rosetta is one-way) — use CI for arm64 validation.
665
+
618
666
  Docker builds use a Node 22 Debian container with NSIS installed for Windows cross-compilation. Output goes to `packages/electron/out/make/`.
619
667
 
620
668
  ### Electron dev mode
@@ -666,7 +714,8 @@ This runs CI, publishes to npm with `--provenance` for supply-chain transparency
666
714
 
667
715
  | Runner | Platform | Outputs |
668
716
  |--------|----------|---------|
669
- | `macos-14` | macOS arm64 | `.dmg` |
717
+ | `macos-14` | macOS arm64 | `.dmg` (Apple Silicon) |
718
+ | `macos-15-intel` | macOS x64 | `.dmg` (Intel; last GitHub-hosted x86_64 image, EOL 2027-08) |
670
719
  | `ubuntu-latest` | Linux x64 | `.deb` + `.AppImage` |
671
720
  | `ubuntu-24.04-arm` | Linux arm64 | `.deb` |
672
721
  | `windows-latest` | Windows x64 | `.exe` (NSIS) + `.zip` + portable |