@blackbelt-technology/pi-agent-dashboard 0.4.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 +30 -8
- package/README.md +386 -494
- package/docs/architecture.md +63 -9
- package/package.json +8 -5
- package/packages/extension/package.json +6 -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__/event-forwarder.test.ts +30 -0
- package/packages/extension/src/__tests__/fork-entryid-timing.test.ts +64 -76
- 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/ask-user-tool.ts +5 -4
- package/packages/extension/src/bridge.ts +102 -15
- package/packages/extension/src/multiselect-list.ts +146 -0
- package/packages/extension/src/multiselect-polyfill.ts +43 -0
- package/packages/extension/src/server-launcher.ts +15 -3
- package/packages/server/package.json +5 -5
- package/packages/server/src/__tests__/fixtures/fork-jsonl-roundtrip.jsonl +8 -0
- package/packages/server/src/__tests__/fork-jsonl-roundtrip.test.ts +49 -0
- package/packages/server/src/__tests__/pi-version-skew.test.ts +72 -0
- package/packages/server/src/__tests__/restart-helper.test.ts +34 -6
- package/packages/server/src/cli.ts +56 -9
- package/packages/server/src/pi-version-skew.ts +12 -1
- package/packages/server/src/restart-helper.ts +13 -2
- package/packages/shared/package.json +1 -1
- 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__/resolve-tool-cli.test.ts +105 -0
- package/packages/shared/src/__tests__/state-replay-entry-id.test.ts +69 -0
- package/packages/shared/src/platform/index.ts +1 -0
- package/packages/shared/src/platform/node-spawn.ts +154 -0
- package/packages/shared/src/protocol.ts +23 -0
- package/packages/shared/src/state-replay.ts +9 -0
- package/packages/shared/src/tool-registry/definitions.ts +92 -0
package/README.md
CHANGED
|
@@ -6,191 +6,163 @@
|
|
|
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
|
-
- **Custom LLM providers** — Add OpenAI-compatible, Anthropic-compatible, or Google Generative AI endpoints (Settings → Providers → LLM Providers). Each card has a **Test** button that pings the provider's `/models` endpoint to verify your base URL + API key combination before saving. Adding, editing, or removing a provider takes effect live in every running pi session — no restart required.
|
|
33
|
-
- **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.
|
|
34
|
-
- **OpenSpec integration** — Browse specs, view archive history, manage changes, and create new changes from the session sidebar
|
|
35
|
-
- **Diff viewer** — Side-by-side and unified diff views with file tree navigation for reviewing agent changes
|
|
36
|
-
- **Editor integration** — Open files in your preferred editor (VS Code, Cursor, etc.) directly from tool call cards
|
|
37
|
-
- **Markdown preview** — Rendered markdown views with search, mermaid diagrams, and syntax highlighting
|
|
38
|
-
- **Network discovery** — mDNS-based auto-discovery of other dashboard servers on the local network; connect to known remote servers
|
|
39
|
-
|
|
40
|
-
## Architecture
|
|
41
|
-
|
|
42
|
-
```mermaid
|
|
43
|
-
graph LR
|
|
44
|
-
subgraph "Per pi session"
|
|
45
|
-
B[Bridge Extension]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
subgraph "Dashboard Server (Node.js)"
|
|
49
|
-
PG[Pi Gateway :9999]
|
|
50
|
-
BG[Browser Gateway :8000]
|
|
51
|
-
HTTP[HTTP / Static Files]
|
|
52
|
-
MEM[(In-Memory Store)]
|
|
53
|
-
JSON[(JSON Files)]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
subgraph "Browser"
|
|
57
|
-
UI[React Web Client]
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
B <-->|WebSocket| PG
|
|
61
|
-
UI <-->|WebSocket| BG
|
|
62
|
-
UI -->|HTTP| HTTP
|
|
63
|
-
PG --- MEM
|
|
64
|
-
PG --- JSON
|
|
65
|
-
BG --- MEM
|
|
66
|
-
```
|
|
16
|
+
## Table of contents
|
|
67
17
|
|
|
68
|
-
|
|
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)
|
|
69
31
|
|
|
70
|
-
|
|
71
|
-
|-----------|----------|------|
|
|
72
|
-
| **Bridge Extension** | `packages/extension/` | Runs in every pi session. Forwards events, relays commands, auto-starts server, hosts PromptBus. |
|
|
73
|
-
| **Dashboard Server** | `packages/server/` | Aggregates events in-memory, persists metadata to JSON, serves the web client, manages terminals. |
|
|
74
|
-
| **Web Client** | `packages/client/` | React + Tailwind UI with real-time WebSocket updates. |
|
|
75
|
-
| **Shared** | `packages/shared/` | TypeScript types, protocols, and utilities shared across all packages. |
|
|
76
|
-
|
|
77
|
-
See [docs/architecture.md](docs/architecture.md) for detailed data flows, reconnection logic, and persistence model.
|
|
32
|
+
---
|
|
78
33
|
|
|
79
|
-
##
|
|
34
|
+
## Quickstart
|
|
80
35
|
|
|
81
|
-
|
|
36
|
+
Three install paths, pick one:
|
|
82
37
|
|
|
83
|
-
###
|
|
38
|
+
### A — Electron desktop app (no prerequisites)
|
|
84
39
|
|
|
85
|
-
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):
|
|
86
41
|
|
|
87
42
|
| Platform | Download |
|
|
88
43
|
|----------|----------|
|
|
89
|
-
| **macOS** (Apple Silicon) | `.dmg` (arm64) |
|
|
90
|
-
| **
|
|
91
|
-
| **
|
|
92
|
-
| **Linux** (ARM64) | `.deb` |
|
|
93
|
-
| **Windows** (x64) | `.exe` (NSIS installer), `.zip`, or portable `.exe` |
|
|
94
|
-
| **Windows** (ARM64) | `.zip` or portable `.exe` |
|
|
95
|
-
|
|
96
|
-
On first launch, a setup wizard guides you through:
|
|
97
|
-
|
|
98
|
-
1. **Choose a mode:**
|
|
99
|
-
- **Standalone** — Bundles Node.js and auto-installs pi + dashboard + openspec into `~/.pi-dashboard/`. No Node.js, npm, or build tools needed.
|
|
100
|
-
- **Power User** — Uses your existing system-installed pi and dashboard.
|
|
101
|
-
2. **Configure an API key** — Enter your Anthropic/OpenAI key or sign in via browser-based OAuth.
|
|
102
|
-
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.
|
|
103
|
-
4. **Done** — The app discovers or spawns a dashboard server automatically.
|
|
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` |
|
|
104
47
|
|
|
105
|
-
|
|
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**.
|
|
106
49
|
|
|
107
|
-
###
|
|
108
|
-
|
|
109
|
-
Requires [pi](https://github.com/badlogic/pi-mono) (or [Oh My Pi](https://www.npmjs.com/package/@oh-my-pi/pi-coding-agent)) and Node.js **≥ 22.18.0** (or ≥ 24.3.0). Older Node 22.x / 24.x builds are affected by [nodejs/node#58515](https://github.com/nodejs/node/issues/58515) which crashes Fastify at startup.
|
|
50
|
+
### B — pi package (recommended for CLI users)
|
|
110
51
|
|
|
111
52
|
```bash
|
|
112
53
|
pi install npm:@blackbelt-technology/pi-agent-dashboard
|
|
113
54
|
pi
|
|
114
55
|
```
|
|
115
56
|
|
|
116
|
-
The bridge extension auto-starts the dashboard server on first launch
|
|
57
|
+
The bridge extension auto-starts the dashboard server on first launch:
|
|
117
58
|
|
|
118
59
|
```
|
|
119
60
|
🌐 Dashboard started at http://localhost:8000
|
|
120
61
|
```
|
|
121
62
|
|
|
122
|
-
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.
|
|
123
64
|
|
|
124
|
-
###
|
|
65
|
+
### C — From source (contributors)
|
|
125
66
|
|
|
126
67
|
```bash
|
|
127
68
|
git clone https://github.com/BlackBeltTechnology/pi-agent-dashboard.git
|
|
128
69
|
cd pi-agent-dashboard
|
|
129
70
|
npm install
|
|
130
|
-
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
|
|
131
73
|
```
|
|
132
74
|
|
|
133
|
-
## Recommended extensions
|
|
134
|
-
|
|
135
|
-
The dashboard integrates tightly with a small, curated set of pi extensions
|
|
136
|
-
— for custom tool rendering, the Flow dashboard, and anthropic-messages
|
|
137
|
-
protocol compatibility. The wizard's Recommended-extensions step installs
|
|
138
|
-
them in one go; the **Packages** tab and a top-of-page **banner** keep
|
|
139
|
-
them discoverable afterwards.
|
|
140
|
-
|
|
141
|
-
| Extension | Source | Status | Unlocks |
|
|
142
|
-
|---|---|---|---|
|
|
143
|
-
| `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. |
|
|
144
|
-
| `@tintinweb/pi-subagents` | `npm:@tintinweb/pi-subagents` | strongly suggested | `Agent` tool card UI, subagent activity badge, `get_subagent_result` / `steer_subagent` renderers. |
|
|
145
|
-
| `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. |
|
|
146
|
-
| `pi-web-access` | `npm:pi-web-access` | strongly suggested | `web_search`, `code_search`, `fetch_content`, `get_search_content`. |
|
|
147
|
-
| `pi-agent-browser` | `npm:pi-agent-browser` | optional | `browser` tool (open, snapshot, click, screenshot). |
|
|
148
|
-
|
|
149
|
-
Authoritative source of truth: `packages/shared/src/recommended-extensions.ts`.
|
|
150
|
-
Descriptions, versions, and installed-state are enriched live at runtime via
|
|
151
|
-
`GET /api/packages/recommended` (falling back to offline descriptions on
|
|
152
|
-
network failure).
|
|
153
|
-
|
|
154
|
-
### GitHub SSH notes
|
|
155
|
-
|
|
156
|
-
The `pi-flows` and `pi-anthropic-messages` entries install via `pi install
|
|
157
|
-
git@github.com:…` (SSH). If your system doesn't have a GitHub SSH key
|
|
158
|
-
configured the clone will fail with a "Permission denied (publickey)"
|
|
159
|
-
error. Set up a key by following
|
|
160
|
-
[GitHub's SSH docs](https://docs.github.com/en/authentication/connecting-to-github-with-ssh),
|
|
161
|
-
or substitute the equivalent HTTPS URL in the manifest if your fork is
|
|
162
|
-
public.
|
|
163
|
-
|
|
164
|
-
### Quick test (without installing)
|
|
165
|
-
|
|
166
75
|
To try the extension in a single pi session without registering it:
|
|
167
76
|
|
|
168
77
|
```bash
|
|
169
78
|
pi -e /path/to/pi-agent-dashboard/packages/extension/src/bridge.ts
|
|
170
79
|
```
|
|
171
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
|
+
|
|
172
122
|
## Prerequisites
|
|
173
123
|
|
|
174
|
-
Only needed for
|
|
124
|
+
**Only needed for Quickstart paths B and C.** The Electron app (path A) bundles everything in standalone mode.
|
|
175
125
|
|
|
176
126
|
| Requirement | Why | Install |
|
|
177
127
|
|-------------|-----|---------|
|
|
178
|
-
| **[pi](https://github.com/badlogic/pi-mono)**
|
|
179
|
-
| **Node.js ≥ 22.18.0** |
|
|
180
|
-
| **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) |
|
|
181
131
|
|
|
182
|
-
|
|
132
|
+
Optional:
|
|
183
133
|
|
|
184
134
|
| Tool | Purpose | When needed |
|
|
185
135
|
|------|---------|-------------|
|
|
186
|
-
| **tmux** | Spawn new pi sessions
|
|
187
|
-
| **[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
|
+
---
|
|
188
140
|
|
|
189
141
|
## Configuration
|
|
190
142
|
|
|
191
|
-
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.
|
|
192
150
|
|
|
193
|
-
|
|
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`
|
|
194
166
|
|
|
195
167
|
```json
|
|
196
168
|
{
|
|
@@ -211,22 +183,56 @@ Tool path overrides (optional, machine-local): **`~/.pi/dashboard/tool-overrides
|
|
|
211
183
|
}
|
|
212
184
|
```
|
|
213
185
|
|
|
214
|
-
|
|
186
|
+
### Authentication (optional)
|
|
187
|
+
|
|
188
|
+
OAuth2 authentication guards external (tunnel) access. Localhost is always unguarded.
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"auth": {
|
|
193
|
+
"secret": "auto-generated-if-omitted",
|
|
194
|
+
"providers": {
|
|
195
|
+
"github": { "clientId": "...", "clientSecret": "..." },
|
|
196
|
+
"google": { "clientId": "...", "clientSecret": "..." },
|
|
197
|
+
"keycloak": { "clientId": "...", "clientSecret": "...", "issuerUrl": "https://keycloak.example.com/realms/myrealm" }
|
|
198
|
+
},
|
|
199
|
+
"allowedUsers": ["octocat", "user@example.com", "*@company.com"]
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
| Key | Required | Description |
|
|
205
|
+
|-----|----------|-------------|
|
|
206
|
+
| `auth.secret` | No | JWT signing secret (auto-generated if omitted) |
|
|
207
|
+
| `auth.providers` | Yes | Map of provider → `{ clientId, clientSecret, issuerUrl? }` |
|
|
208
|
+
| `auth.allowedUsers` | No | Allowlist: usernames, emails, or `*@domain` wildcards. Empty = allow all |
|
|
209
|
+
|
|
210
|
+
**Supported providers:** `github`, `google`, `keycloak`, `oidc` (generic OIDC with `issuerUrl`).
|
|
211
|
+
|
|
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).
|
|
213
|
+
|
|
214
|
+
### Tunnel (zrok)
|
|
215
|
+
|
|
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.
|
|
217
|
+
|
|
218
|
+
### OpenSpec background polling
|
|
219
|
+
|
|
220
|
+
Tune how often the server polls known directories for OpenSpec updates (`openspec` block):
|
|
215
221
|
|
|
216
222
|
| Key | Default | Range | Description |
|
|
217
223
|
|-----|---------|-------|-------------|
|
|
218
|
-
| `pollIntervalSeconds` | `30` | `5–3600` | How often each known directory is polled
|
|
219
|
-
| `maxConcurrentSpawns` | `3` | `1–16` | Cap on concurrent `openspec` CLI invocations
|
|
220
|
-
| `changeDetection` | `"mtime"` | `"mtime" \| "always"` | `mtime` skips
|
|
221
|
-
| `jitterSeconds` | `5` | `0–60` | Per-directory phase offset so polls don't
|
|
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 |
|
|
222
228
|
|
|
223
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.
|
|
224
230
|
|
|
225
|
-
### Tool
|
|
231
|
+
### Tool overrides
|
|
226
232
|
|
|
227
|
-
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
|
|
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.
|
|
228
234
|
|
|
229
|
-
**Inspecting and overriding** — Settings → General → **Tools** shows every resolved tool, its source, and the trail. You can set a per-tool override path, rescan
|
|
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.
|
|
230
236
|
|
|
231
237
|
**Overrides file** — `~/.pi/dashboard/tool-overrides.json`:
|
|
232
238
|
|
|
@@ -240,241 +246,213 @@ The dashboard resolves every external tool it calls (`pi`, `pi-coding-agent`, `o
|
|
|
240
246
|
}
|
|
241
247
|
```
|
|
242
248
|
|
|
243
|
-
The file is deliberately separate from `config.json` so machine-specific paths don't follow a dotfiles sync
|
|
244
|
-
|
|
245
|
-
**Troubleshooting** — if the dashboard says it can't find `pi`, `openspec`, `npm`, or any other tool, 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.
|
|
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.
|
|
246
250
|
|
|
247
|
-
|
|
251
|
+
---
|
|
248
252
|
|
|
249
|
-
|
|
253
|
+
## Usage
|
|
250
254
|
|
|
251
|
-
|
|
255
|
+
### Auto-start (default)
|
|
252
256
|
|
|
253
|
-
|
|
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`.
|
|
254
258
|
|
|
255
|
-
|
|
259
|
+
### Daemon mode
|
|
256
260
|
|
|
257
|
-
|
|
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
|
+
```
|
|
258
269
|
|
|
259
|
-
|
|
270
|
+
Daemon stdout/stderr is logged to `~/.pi/dashboard/server.log` (append mode with timestamped headers per start).
|
|
260
271
|
|
|
261
|
-
|
|
272
|
+
### Manual server start
|
|
262
273
|
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
"providers": {
|
|
268
|
-
"github": {
|
|
269
|
-
"clientId": "your-github-client-id",
|
|
270
|
-
"clientSecret": "your-github-client-secret"
|
|
271
|
-
},
|
|
272
|
-
"google": {
|
|
273
|
-
"clientId": "your-google-client-id",
|
|
274
|
-
"clientSecret": "your-google-client-secret"
|
|
275
|
-
},
|
|
276
|
-
"keycloak": {
|
|
277
|
-
"clientId": "your-keycloak-client-id",
|
|
278
|
-
"clientSecret": "your-keycloak-client-secret",
|
|
279
|
-
"issuerUrl": "https://keycloak.example.com/realms/myrealm"
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
"allowedUsers": ["octocat", "user@example.com", "*@company.com"]
|
|
283
|
-
}
|
|
284
|
-
}
|
|
274
|
+
```bash
|
|
275
|
+
npx tsx packages/server/src/cli.ts
|
|
276
|
+
npx tsx packages/server/src/cli.ts --port 8000 --pi-port 9999
|
|
277
|
+
npx tsx packages/server/src/cli.ts --dev # proxy to Vite dev server
|
|
285
278
|
```
|
|
286
279
|
|
|
287
|
-
|
|
288
|
-
|-----|----------|-------------|
|
|
289
|
-
| `auth.secret` | No | JWT signing secret (auto-generated if omitted) |
|
|
290
|
-
| `auth.providers` | Yes | Map of provider name → `{ clientId, clientSecret, issuerUrl? }` |
|
|
291
|
-
| `auth.allowedUsers` | No | User allowlist: usernames, emails, or `*@domain` wildcards. Empty = allow all |
|
|
280
|
+
### Graceful restart via API
|
|
292
281
|
|
|
293
|
-
|
|
282
|
+
```bash
|
|
283
|
+
# Restart in the same mode
|
|
284
|
+
curl -X POST http://localhost:8000/api/restart
|
|
294
285
|
|
|
295
|
-
|
|
286
|
+
# Switch to dev / production
|
|
287
|
+
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":true}'
|
|
288
|
+
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":false}'
|
|
296
289
|
|
|
297
|
-
|
|
290
|
+
# Check current mode
|
|
291
|
+
curl -s http://localhost:8000/api/health | jq .mode
|
|
292
|
+
```
|
|
298
293
|
|
|
299
|
-
|
|
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).
|
|
300
295
|
|
|
301
|
-
|
|
302
|
-
|----------|---------|------------|---------|-------------|
|
|
303
|
-
| `--port` | `PI_DASHBOARD_PORT` | `port` | `8000` | HTTP + Browser WebSocket port |
|
|
304
|
-
| `--pi-port` | `PI_DASHBOARD_PI_PORT` | `piPort` | `9999` | Pi extension WebSocket port |
|
|
305
|
-
| `--dev` | — | — | `false` | Development mode (proxy to Vite) |
|
|
306
|
-
| `--no-tunnel` | — | `tunnel.enabled` | `true` | Disable zrok tunnel |
|
|
307
|
-
| — | — | `autoStart` | `true` | Bridge auto-starts server if not running |
|
|
308
|
-
| — | — | `autoShutdown` | `false` | Server shuts down when idle |
|
|
309
|
-
| — | — | `shutdownIdleSeconds` | `300` | Seconds idle before auto-shutdown |
|
|
310
|
-
| — | — | `spawnStrategy` | `"headless"` | Session spawn mode: `"headless"` or `"tmux"` |
|
|
311
|
-
| — | — | `devBuildOnReload` | `false` | Rebuild client + restart server on `/reload` |
|
|
296
|
+
### Dev mode with production fallback
|
|
312
297
|
|
|
313
|
-
|
|
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/`:
|
|
314
299
|
|
|
315
|
-
|
|
300
|
+
- `pi-dashboard start --dev` **always works** — no 502 errors
|
|
301
|
+
- Start/stop Vite independently without restarting the dashboard
|
|
302
|
+
- Start Vite later and refresh the browser to get HMR
|
|
316
303
|
|
|
317
|
-
|
|
318
|
-
|
|
304
|
+
### Dev build on reload
|
|
305
|
+
|
|
306
|
+
Set `"devBuildOnReload": true` in `config.json` for a one-command full-stack refresh:
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
/reload → build client → stop server → reload extension → auto-start fresh server
|
|
319
310
|
```
|
|
320
311
|
|
|
321
|
-
|
|
312
|
+
> Blocks pi for ~2–5s during the build. The server shutdown affects all connected sessions — they auto-reconnect when one restarts the server.
|
|
322
313
|
|
|
323
|
-
###
|
|
314
|
+
### Session spawning
|
|
324
315
|
|
|
325
|
-
|
|
316
|
+
**Headless** (default) — runs pi as a background process with no terminal attached. Interaction through the web UI.
|
|
326
317
|
|
|
327
|
-
|
|
318
|
+
**tmux** — runs pi inside a tmux session named `pi-dashboard`, each spawned session as a new window:
|
|
328
319
|
|
|
329
320
|
```bash
|
|
330
|
-
#
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
# Oh My Pi
|
|
334
|
-
omp install npm:@blackbelt-technology/pi-agent-dashboard
|
|
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
|
|
335
324
|
```
|
|
336
325
|
|
|
337
|
-
|
|
326
|
+
Switch with `"spawnStrategy": "tmux"` in `~/.pi/dashboard/config.json`.
|
|
338
327
|
|
|
339
|
-
###
|
|
328
|
+
### Keyboard shortcuts in chat input
|
|
340
329
|
|
|
341
|
-
|
|
342
|
-
cd /path/to/pi-agent-dashboard
|
|
343
|
-
npm install
|
|
330
|
+
Bash-style history recall and per-session draft persistence:
|
|
344
331
|
|
|
345
|
-
|
|
346
|
-
|
|
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 |
|
|
347
340
|
|
|
348
|
-
|
|
349
|
-
pi install -l /path/to/pi-agent-dashboard
|
|
350
|
-
```
|
|
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.
|
|
351
342
|
|
|
352
|
-
|
|
343
|
+
---
|
|
353
344
|
|
|
354
|
-
|
|
345
|
+
## Recommended extensions
|
|
355
346
|
|
|
356
|
-
|
|
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.
|
|
357
348
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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) |
|
|
364
356
|
|
|
365
|
-
|
|
366
|
-
```json
|
|
367
|
-
{
|
|
368
|
-
"packages": ["/path/to/pi-agent-dashboard"]
|
|
369
|
-
}
|
|
370
|
-
```
|
|
357
|
+
Authoritative source: `packages/shared/src/recommended-extensions.ts`. Descriptions, versions, and installed-state are enriched live via `GET /api/packages/recommended` (offline fallback).
|
|
371
358
|
|
|
372
|
-
|
|
359
|
+
---
|
|
373
360
|
|
|
374
|
-
|
|
375
|
-
pi remove /path/to/pi-agent-dashboard
|
|
376
|
-
```
|
|
361
|
+
## Troubleshooting
|
|
377
362
|
|
|
378
|
-
|
|
363
|
+
### Dashboard server doesn't start
|
|
379
364
|
|
|
380
|
-
|
|
365
|
+
If `pi` launches but the dashboard never becomes reachable, inspect the launch log:
|
|
381
366
|
|
|
382
|
-
|
|
367
|
+
```bash
|
|
368
|
+
cat ~/.pi/dashboard/server.log # Linux / macOS
|
|
369
|
+
type %USERPROFILE%\.pi\dashboard\server.log # Windows
|
|
370
|
+
```
|
|
383
371
|
|
|
384
|
-
|
|
372
|
+
The log is append-mode with timestamped headers per start attempt, so previous crashes are preserved. Common issues:
|
|
385
373
|
|
|
386
|
-
|
|
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+.
|
|
387
377
|
|
|
388
|
-
|
|
389
|
-
npx tsx packages/server/src/cli.ts
|
|
390
|
-
npx tsx packages/server/src/cli.ts --port 8000 --pi-port 9999
|
|
391
|
-
npx tsx packages/server/src/cli.ts --dev # proxy to Vite dev server
|
|
392
|
-
```
|
|
378
|
+
### Port already in use
|
|
393
379
|
|
|
394
|
-
|
|
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`.
|
|
395
383
|
|
|
396
|
-
|
|
397
|
-
pi-dashboard start # Start as background daemon (production)
|
|
398
|
-
pi-dashboard start --dev # Start in dev mode (proxy to Vite, fallback to production build)
|
|
399
|
-
pi-dashboard stop # Stop running daemon (also kills stale port holders)
|
|
400
|
-
pi-dashboard restart # Restart daemon (production)
|
|
401
|
-
pi-dashboard restart --dev # Restart in dev mode
|
|
402
|
-
pi-dashboard status # Show daemon status
|
|
403
|
-
```
|
|
384
|
+
### UI is empty or stuck after switching servers
|
|
404
385
|
|
|
405
|
-
|
|
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.
|
|
406
387
|
|
|
407
|
-
|
|
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.
|
|
408
389
|
|
|
409
|
-
|
|
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.
|
|
410
391
|
|
|
411
|
-
|
|
412
|
-
|-----|--------|
|
|
413
|
-
| `Enter` | Send the prompt. |
|
|
414
|
-
| `Shift+Enter` | Insert a newline. |
|
|
415
|
-
| `ArrowUp` | Recall the previous user prompt (only when the caret is on the first line and no autocomplete dropdown is open). Repeat to walk further back. |
|
|
416
|
-
| `ArrowDown` | Walk forward through history (only when the caret is on the last line). Past the newest entry, restores the in-progress draft. |
|
|
417
|
-
| `Escape` | While navigating history, restore the in-progress draft and exit history mode. Also cancels a pending prompt or dismisses the autocomplete dropdown. |
|
|
418
|
-
| `Tab` / `Enter` in dropdown | Accept the highlighted `/command` or `@file` suggestion. |
|
|
392
|
+
### Windows: sessions die when the dashboard restarts
|
|
419
393
|
|
|
420
|
-
|
|
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.
|
|
421
395
|
|
|
422
|
-
|
|
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`).
|
|
423
397
|
|
|
424
|
-
|
|
398
|
+
### Windows Terminal tab doesn't appear
|
|
425
399
|
|
|
426
|
-
|
|
427
|
-
# Restart in same mode (preserves current dev/prod)
|
|
428
|
-
curl -X POST http://localhost:8000/api/restart
|
|
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.
|
|
429
401
|
|
|
430
|
-
|
|
431
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":true}'
|
|
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.
|
|
432
403
|
|
|
433
|
-
|
|
434
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":false}'
|
|
404
|
+
### Sessions don't group under my pinned folder
|
|
435
405
|
|
|
436
|
-
|
|
437
|
-
curl -s http://localhost:8000/api/health | jq .mode
|
|
438
|
-
```
|
|
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).
|
|
439
407
|
|
|
440
|
-
|
|
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`.
|
|
441
409
|
|
|
442
|
-
###
|
|
410
|
+
### Tool not found (pi / openspec / npm / …)
|
|
443
411
|
|
|
444
|
-
|
|
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.
|
|
445
413
|
|
|
446
|
-
|
|
447
|
-
- Start/stop Vite independently without restarting the dashboard
|
|
448
|
-
- Seamless transition: start Vite later and refresh the browser to get HMR
|
|
414
|
+
### Recommended extensions: "Permission denied (publickey)"
|
|
449
415
|
|
|
450
|
-
|
|
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.
|
|
451
417
|
|
|
452
|
-
|
|
418
|
+
---
|
|
453
419
|
|
|
454
|
-
|
|
420
|
+
## Architecture
|
|
455
421
|
|
|
456
|
-
|
|
422
|
+
```mermaid
|
|
423
|
+
graph LR
|
|
424
|
+
subgraph "Per pi session"
|
|
425
|
+
B[Bridge Extension]
|
|
426
|
+
end
|
|
457
427
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
|
461
435
|
|
|
462
|
-
|
|
463
|
-
|
|
436
|
+
subgraph "Browser"
|
|
437
|
+
UI[React Web Client]
|
|
438
|
+
end
|
|
464
439
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
440
|
+
B <-->|WebSocket| PG
|
|
441
|
+
UI <-->|WebSocket| BG
|
|
442
|
+
UI -->|HTTP| HTTP
|
|
443
|
+
PG --- MEM
|
|
444
|
+
PG --- JSON
|
|
445
|
+
BG --- MEM
|
|
469
446
|
```
|
|
470
447
|
|
|
471
|
-
|
|
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. |
|
|
472
454
|
|
|
473
|
-
|
|
474
|
-
{
|
|
475
|
-
"spawnStrategy": "tmux"
|
|
476
|
-
}
|
|
477
|
-
```
|
|
455
|
+
See [docs/architecture.md](docs/architecture.md) for detailed data flows, reconnection logic, and persistence model.
|
|
478
456
|
|
|
479
457
|
### Auto-start flow
|
|
480
458
|
|
|
@@ -493,15 +471,25 @@ flowchart TD
|
|
|
493
471
|
|
|
494
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`.
|
|
495
473
|
|
|
496
|
-
|
|
474
|
+
---
|
|
497
475
|
|
|
498
|
-
|
|
476
|
+
## Monitoring
|
|
499
477
|
|
|
478
|
+
The health endpoint provides server and agent process metrics:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
curl -s http://localhost:8000/api/health | jq
|
|
500
482
|
```
|
|
501
|
-
/reload → build client → stop server → reload extension → auto-start fresh server
|
|
502
|
-
```
|
|
503
483
|
|
|
504
|
-
|
|
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
|
+
---
|
|
505
493
|
|
|
506
494
|
## Development
|
|
507
495
|
|
|
@@ -536,8 +524,6 @@ pi -e packages/extension/src/bridge.ts # or just `pi` if installed
|
|
|
536
524
|
|
|
537
525
|
### Deploy after changes
|
|
538
526
|
|
|
539
|
-
The `pi-dashboard` command is available globally when the package is installed. After making changes, restart the appropriate components:
|
|
540
|
-
|
|
541
527
|
```bash
|
|
542
528
|
# After client changes (production mode)
|
|
543
529
|
npm run build
|
|
@@ -547,142 +533,15 @@ curl -X POST http://localhost:8000/api/restart
|
|
|
547
533
|
curl -X POST http://localhost:8000/api/restart
|
|
548
534
|
|
|
549
535
|
# After bridge extension changes
|
|
550
|
-
npm run reload
|
|
536
|
+
npm run reload
|
|
551
537
|
|
|
552
538
|
# Full rebuild (e.g., after pulling updates)
|
|
553
539
|
npm run build
|
|
554
540
|
curl -X POST http://localhost:8000/api/restart
|
|
555
541
|
npm run reload
|
|
556
|
-
|
|
557
|
-
# Switch between dev and production mode
|
|
558
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":true}'
|
|
559
|
-
curl -X POST http://localhost:8000/api/restart -H 'Content-Type: application/json' -d '{"dev":false}'
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### Project Structure
|
|
563
|
-
|
|
564
|
-
The project is a monorepo with npm workspaces:
|
|
565
|
-
|
|
566
|
-
```
|
|
567
|
-
packages/
|
|
568
|
-
├── shared/ # Shared TypeScript types & utilities
|
|
569
|
-
│ └── src/
|
|
570
|
-
│ ├── protocol.ts # Extension ↔ Server messages
|
|
571
|
-
│ ├── browser-protocol.ts # Server ↔ Browser messages (incl. PromptBus types)
|
|
572
|
-
│ ├── types.ts # Data models
|
|
573
|
-
│ ├── config.ts # Shared config loader
|
|
574
|
-
│ ├── rest-api.ts # REST API types
|
|
575
|
-
│ ├── session-meta.ts # Session metadata sidecar (.meta.json) read/write
|
|
576
|
-
│ ├── state-replay.ts # Event synthesis on reconnect
|
|
577
|
-
│ ├── stats-extractor.ts # Token/cost stats extraction
|
|
578
|
-
│ ├── server-identity.ts # Server detection & identity
|
|
579
|
-
│ ├── mdns-discovery.ts # mDNS network auto-discovery
|
|
580
|
-
│ └── openspec-poller.ts # OpenSpec change data polling
|
|
581
|
-
├── extension/ # Bridge extension (runs in pi)
|
|
582
|
-
│ └── src/
|
|
583
|
-
│ ├── bridge.ts # Main extension entry
|
|
584
|
-
│ ├── connection.ts # WebSocket with reconnection
|
|
585
|
-
│ ├── event-forwarder.ts # Event mapping
|
|
586
|
-
│ ├── flow-event-wiring.ts # pi-flows event forwarding
|
|
587
|
-
│ ├── prompt-bus.ts # PromptBus — unified prompt routing with adapters
|
|
588
|
-
│ ├── dashboard-default-adapter.ts # Default PromptBus adapter for dashboard UI
|
|
589
|
-
│ ├── prompt-expander.ts # Prompt template expansion from disk
|
|
590
|
-
│ ├── provider-register.ts # Provider auth registration & sync
|
|
591
|
-
│ ├── model-tracker.ts # Model selection tracking
|
|
592
|
-
│ ├── source-detector.ts # Session source detection (via .meta.json sidecar)
|
|
593
|
-
│ ├── command-handler.ts # Command relay
|
|
594
|
-
│ ├── server-probe.ts # TCP probe for server detection
|
|
595
|
-
│ ├── server-auto-start.ts # Auto-start logic on session launch
|
|
596
|
-
│ ├── server-launcher.ts # Spawn server as detached process
|
|
597
|
-
│ ├── session-sync.ts # Session history sync
|
|
598
|
-
│ ├── process-metrics.ts # Agent process CPU/memory metrics
|
|
599
|
-
│ ├── process-scanner.ts # Running process detection
|
|
600
|
-
│ ├── git-info.ts # Git branch/remote/PR detection
|
|
601
|
-
│ ├── git-link-builder.ts # GitHub/GitLab permalink generation
|
|
602
|
-
│ └── dev-build.ts # Dev build-on-reload helper
|
|
603
|
-
├── server/ # Dashboard server
|
|
604
|
-
│ └── src/
|
|
605
|
-
│ ├── cli.ts # CLI entry (start/stop/restart/status)
|
|
606
|
-
│ ├── server.ts # HTTP + WebSocket server
|
|
607
|
-
│ ├── pi-gateway.ts # Extension WebSocket gateway
|
|
608
|
-
│ ├── browser-gateway.ts # Browser WebSocket gateway
|
|
609
|
-
│ ├── memory-event-store.ts # In-memory event buffer (LRU, per-session cap, truncation)
|
|
610
|
-
│ ├── memory-session-manager.ts # In-memory session registry
|
|
611
|
-
│ ├── preferences-store.ts # User prefs: hidden sessions, pinned dirs
|
|
612
|
-
│ ├── meta-persistence.ts # Session metadata persistence
|
|
613
|
-
│ ├── session-order-manager.ts # Per-cwd session ordering
|
|
614
|
-
│ ├── session-discovery.ts # Session file scanning & loading
|
|
615
|
-
│ ├── process-manager.ts # tmux/headless session spawning
|
|
616
|
-
│ ├── headless-pid-registry.ts # Track headless process PIDs
|
|
617
|
-
│ ├── editor-registry.ts # Available editor detection
|
|
618
|
-
│ ├── editor-manager.ts # Editor launch & file opening
|
|
619
|
-
│ ├── provider-auth-storage.ts # Provider credential persistence
|
|
620
|
-
│ ├── provider-auth-handlers.ts # OAuth flow handlers
|
|
621
|
-
│ ├── npm-search-proxy.ts # npm registry search proxy
|
|
622
|
-
│ ├── package-manager-wrapper.ts # pi package install/remove
|
|
623
|
-
│ ├── pending-fork-registry.ts # Flow fork decision persistence
|
|
624
|
-
│ ├── tunnel.ts # Zrok tunnel with reserved shares
|
|
625
|
-
│ ├── terminal-manager.ts # Browser terminal sessions (xterm.js + node-pty)
|
|
626
|
-
│ ├── server-pid.ts # PID file for daemon management
|
|
627
|
-
│ ├── auth.ts # OAuth2 authentication
|
|
628
|
-
│ └── json-store.ts # Atomic JSON file helpers
|
|
629
|
-
├── client/ # React web client
|
|
630
|
-
│ └── src/
|
|
631
|
-
│ ├── App.tsx
|
|
632
|
-
│ ├── hooks/ # WebSocket hooks, mobile detection
|
|
633
|
-
│ ├── lib/ # Event reducer, command filter
|
|
634
|
-
│ └── components/ # UI components
|
|
635
|
-
│ ├── FlowDashboard.tsx # Live flow execution view
|
|
636
|
-
│ ├── FlowAgentCard.tsx # Per-agent status cards
|
|
637
|
-
│ ├── FlowGraph.tsx # DAG visualization
|
|
638
|
-
│ ├── FlowArchitect.tsx # Flow designer UI
|
|
639
|
-
│ ├── FlowSummary.tsx # Post-flow result summary
|
|
640
|
-
│ ├── DiffView.tsx # Side-by-side diff viewer
|
|
641
|
-
│ ├── TerminalView.tsx # Browser terminal emulator
|
|
642
|
-
│ ├── PackageBrowser.tsx # Package search & install
|
|
643
|
-
│ ├── ProviderAuthSection.tsx # Provider sign-in UI
|
|
644
|
-
│ ├── SettingsPanel.tsx # Config editor
|
|
645
|
-
│ └── ... # 80+ components
|
|
646
|
-
└── electron/ # Electron desktop app wrapper
|
|
647
|
-
├── src/main.ts
|
|
648
|
-
├── scripts/
|
|
649
|
-
└── resources/
|
|
650
|
-
```
|
|
651
|
-
|
|
652
|
-
## Monitoring
|
|
653
|
-
|
|
654
|
-
The health endpoint provides server and agent process metrics:
|
|
655
|
-
|
|
656
|
-
```bash
|
|
657
|
-
curl -s http://localhost:8000/api/health | jq
|
|
658
542
|
```
|
|
659
543
|
|
|
660
|
-
|
|
661
|
-
- `mode` — `"dev"` or `"production"`
|
|
662
|
-
- `server.rss`, `server.heapUsed`, `server.heapTotal` — server memory
|
|
663
|
-
- `server.activeSessions`, `server.totalSessions` — session counts
|
|
664
|
-
- `agents[]` — per-agent metrics (CPU%, RSS, heap, event loop max delay, system load)
|
|
665
|
-
|
|
666
|
-
Agent metrics are collected every 15s via heartbeats and include `eventLoopMaxMs` — useful for diagnosing connection drops during long-running operations.
|
|
667
|
-
|
|
668
|
-
### Troubleshooting: dashboard server doesn't start
|
|
669
|
-
|
|
670
|
-
If `pi` launches but the dashboard never becomes reachable (no `http://localhost:8000`, no `🌐 Dashboard started` notification), inspect the launch log:
|
|
671
|
-
|
|
672
|
-
```bash
|
|
673
|
-
cat ~/.pi/dashboard/server.log # Linux / macOS
|
|
674
|
-
type %USERPROFILE%\.pi\dashboard\server.log # Windows
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
The log is opened in append mode and prefixed with a timestamped header on every start attempt, so previous crashes are preserved. Common issues:
|
|
678
|
-
|
|
679
|
-
- **`ERR_UNSUPPORTED_ESM_URL_SCHEME` on Windows** — fixed in pi-agent-dashboard 0.2.10+; upgrade the package.
|
|
680
|
-
- **`Port 8000 is occupied by another service`** — another process is bound to the port. On Windows: `netstat -ano | findstr :8000` then `taskkill /F /PID <pid>`. On Unix: `lsof -t -i :8000 | xargs kill`. Or change `port` in `~/.pi/dashboard/config.json`.
|
|
681
|
-
- **`Cannot find pi's TypeScript loader`** — pi is not installed globally. Run `npm install -g @mariozechner/pi-coding-agent`.
|
|
682
|
-
|
|
683
|
-
The `POST /api/restart` endpoint and `pi-dashboard restart` command work identically on Windows, macOS, and Linux (no `sh`/`lsof`/`curl` dependency).
|
|
684
|
-
|
|
685
|
-
## Extension UI Events
|
|
544
|
+
### Extension UI events
|
|
686
545
|
|
|
687
546
|
Your own extensions can broadcast UI events to the dashboard:
|
|
688
547
|
|
|
@@ -696,40 +555,40 @@ pi.events.emit("dashboard:ui", {
|
|
|
696
555
|
|
|
697
556
|
Supported methods: `confirm`, `select`, `input`, `notify`.
|
|
698
557
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
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.
|
|
702
|
-
|
|
703
|
-
The Electron app supports two modes:
|
|
558
|
+
### Project structure
|
|
704
559
|
|
|
705
|
-
|
|
706
|
-
|------|-------------|
|
|
707
|
-
| **Standalone** | Bundles Node.js, auto-installs pi + dashboard into `~/.pi-dashboard/`. Zero prerequisites. |
|
|
708
|
-
| **Power User** | Detects and uses your existing system pi + dashboard install. |
|
|
560
|
+
Monorepo with npm workspaces — top-level layout only. See [AGENTS.md](AGENTS.md) for the full file-by-file index.
|
|
709
561
|
|
|
710
|
-
|
|
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
|
+
```
|
|
711
570
|
|
|
712
|
-
|
|
571
|
+
---
|
|
713
572
|
|
|
714
|
-
|
|
573
|
+
## Building the Electron app
|
|
715
574
|
|
|
716
|
-
|
|
575
|
+
> **Prerequisites:** Node.js 22.12+; platform-specific tools handled by Electron Forge automatically.
|
|
717
576
|
|
|
718
|
-
|
|
577
|
+
### Native build (current platform)
|
|
719
578
|
|
|
720
579
|
```bash
|
|
721
|
-
npm run electron:build
|
|
722
|
-
npm run electron:build -- --arch x64
|
|
723
|
-
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
|
|
724
583
|
```
|
|
725
584
|
|
|
726
585
|
Or step by step:
|
|
727
586
|
|
|
728
587
|
```bash
|
|
729
|
-
npm run build
|
|
588
|
+
npm run build # Build web client
|
|
730
589
|
cd packages/electron
|
|
731
|
-
bash scripts/download-node.sh
|
|
732
|
-
npm run make
|
|
590
|
+
bash scripts/download-node.sh # Download Node.js for bundling
|
|
591
|
+
npm run make # Build installer
|
|
733
592
|
```
|
|
734
593
|
|
|
735
594
|
Output by platform:
|
|
@@ -738,25 +597,22 @@ Output by platform:
|
|
|
738
597
|
|----------|--------|----------|
|
|
739
598
|
| macOS | `.dmg` | `packages/electron/out/make/` |
|
|
740
599
|
| Linux | `.deb` + `.AppImage` | `packages/electron/out/make/` |
|
|
741
|
-
| Windows | `.exe` (NSIS
|
|
600
|
+
| Windows | `.exe` (NSIS) + `.zip` + portable `.exe` | `packages/electron/out/make/` |
|
|
742
601
|
|
|
743
|
-
### Cross-
|
|
602
|
+
### Cross-platform builds (Docker)
|
|
744
603
|
|
|
745
|
-
From macOS or Linux,
|
|
604
|
+
From macOS or Linux, build installers for all platforms:
|
|
746
605
|
|
|
747
606
|
```bash
|
|
748
|
-
npm run electron:build -- --all
|
|
749
|
-
npm run electron:build -- --linux
|
|
750
|
-
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
|
|
751
610
|
npm run electron:build -- --linux --windows # Both, skip native
|
|
752
611
|
```
|
|
753
612
|
|
|
754
|
-
Docker builds use a Node 22 Debian container with NSIS installed for Windows cross-compilation.
|
|
755
|
-
All output goes to `packages/electron/out/make/`.
|
|
756
|
-
|
|
757
|
-
> **Note:** Native builds (no flags) build for the current platform only. Docker is required for `--linux`, `--windows`, and `--all`.
|
|
613
|
+
Docker builds use a Node 22 Debian container with NSIS installed for Windows cross-compilation. Output goes to `packages/electron/out/make/`.
|
|
758
614
|
|
|
759
|
-
###
|
|
615
|
+
### Electron dev mode
|
|
760
616
|
|
|
761
617
|
```bash
|
|
762
618
|
# Start the dashboard server and Vite dev server first
|
|
@@ -768,7 +624,7 @@ cd packages/electron
|
|
|
768
624
|
npm run start:dev
|
|
769
625
|
```
|
|
770
626
|
|
|
771
|
-
### Regenerating
|
|
627
|
+
### Regenerating icons
|
|
772
628
|
|
|
773
629
|
All platform icon variants are generated from the master icon at `packages/electron/resources/icon.png`:
|
|
774
630
|
|
|
@@ -777,9 +633,31 @@ cd packages/electron
|
|
|
777
633
|
npm run icons # Generates .icns (macOS), .ico (Windows), and resized PNGs
|
|
778
634
|
```
|
|
779
635
|
|
|
780
|
-
|
|
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
|
|
781
643
|
|
|
782
|
-
|
|
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
|
|
652
|
+
|
|
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:
|
|
783
661
|
|
|
784
662
|
| Runner | Platform | Outputs |
|
|
785
663
|
|--------|----------|---------|
|
|
@@ -789,37 +667,51 @@ The release workflow (`.github/workflows/publish.yml`) builds Electron installer
|
|
|
789
667
|
| `windows-latest` | Windows x64 | `.exe` (NSIS) + `.zip` + portable |
|
|
790
668
|
| `windows-latest` | Windows arm64 | `.zip` + portable (x64 Node.js via WoW64) |
|
|
791
669
|
|
|
792
|
-
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).
|
|
793
671
|
|
|
794
|
-
|
|
672
|
+
### Trusted Publisher (OIDC) setup
|
|
795
673
|
|
|
796
|
-
|
|
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.
|
|
797
675
|
|
|
798
|
-
|
|
676
|
+
**Requirements** (already configured in [`publish.yml`](.github/workflows/publish.yml)):
|
|
799
677
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
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
|
+
```
|
|
804
684
|
|
|
805
|
-
|
|
685
|
+
Trusted Publishing requires **npm CLI ≥ 11.5.1**. The workflow upgrades npm automatically (`npm install -g npm@latest`) before publishing.
|
|
806
686
|
|
|
807
|
-
|
|
687
|
+
**One-time npm-side setup** — repeat once per published package (five scoped workspaces; `@blackbelt-technology/pi-dashboard-electron` is private and skipped):
|
|
808
688
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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
|
|
813
706
|
|
|
814
|
-
|
|
707
|
+
**GitHub Environment (recommended)** — configures an optional human-approval gate on every release:
|
|
815
708
|
|
|
816
|
-
|
|
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)
|
|
817
711
|
|
|
818
|
-
|
|
712
|
+
No secrets to rotate, no tokens to leak.
|
|
819
713
|
|
|
820
|
-
|
|
821
|
-
2. Grant publish access to `@blackbelt-technology` packages
|
|
822
|
-
3. Add it as a repository secret: GitHub repo → Settings → Secrets and variables → Actions → New repository secret → Name: `NPM_TOKEN`
|
|
714
|
+
---
|
|
823
715
|
|
|
824
716
|
## License
|
|
825
717
|
|