@blackbelt-technology/pi-agent-dashboard 0.4.6 → 0.5.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.
Files changed (181) hide show
  1. package/AGENTS.md +339 -190
  2. package/README.md +50 -7
  3. package/docs/architecture.md +238 -23
  4. package/package.json +23 -13
  5. package/packages/extension/package.json +11 -3
  6. package/packages/extension/src/__tests__/ask-user-tool.test.ts +1 -1
  7. package/packages/extension/src/__tests__/build-provider-catalogue.test.ts +176 -0
  8. package/packages/extension/src/__tests__/command-handler.test.ts +68 -0
  9. package/packages/extension/src/__tests__/enrich-model-metadata.test.ts +1 -1
  10. package/packages/extension/src/__tests__/markdown-image-inliner.test.ts +355 -0
  11. package/packages/extension/src/__tests__/no-tui-multiselect-arm-regression.test.ts +1 -1
  12. package/packages/extension/src/__tests__/openspec-activity-detector.test.ts +68 -0
  13. package/packages/extension/src/__tests__/prompt-expander.test.ts +45 -0
  14. package/packages/extension/src/__tests__/provider-register-reload.test.ts +74 -0
  15. package/packages/extension/src/__tests__/retry-tracker.test.ts +147 -0
  16. package/packages/extension/src/__tests__/server-launcher.test.ts +24 -1
  17. package/packages/extension/src/__tests__/session-sync.test.ts +72 -0
  18. package/packages/extension/src/__tests__/usage-limit-orderer.test.ts +105 -0
  19. package/packages/extension/src/ask-user-tool.ts +1 -1
  20. package/packages/extension/src/bridge-context.ts +1 -1
  21. package/packages/extension/src/bridge.ts +169 -4
  22. package/packages/extension/src/command-handler.ts +65 -2
  23. package/packages/extension/src/flow-event-wiring.ts +1 -1
  24. package/packages/extension/src/markdown-image-inliner.ts +268 -0
  25. package/packages/extension/src/multiselect-list.ts +1 -1
  26. package/packages/extension/src/pi-env.d.ts +16 -9
  27. package/packages/extension/src/prompt-expander.ts +50 -2
  28. package/packages/extension/src/provider-register.ts +132 -8
  29. package/packages/extension/src/retry-tracker.ts +123 -0
  30. package/packages/extension/src/server-launcher.ts +18 -1
  31. package/packages/extension/src/session-sync.ts +15 -1
  32. package/packages/extension/src/usage-limit-orderer.ts +76 -0
  33. package/packages/server/package.json +6 -6
  34. package/packages/server/src/__tests__/auto-attach-slug-defense.test.ts +104 -0
  35. package/packages/server/src/__tests__/bootstrap-install-from-list.test.ts +263 -0
  36. package/packages/server/src/__tests__/browser-gateway-snapshot-on-connect.test.ts +143 -0
  37. package/packages/server/src/__tests__/build-auth-status.test.ts +190 -0
  38. package/packages/server/src/__tests__/changelog-fs.test.ts +171 -0
  39. package/packages/server/src/__tests__/changelog-parser.test.ts +220 -0
  40. package/packages/server/src/__tests__/changelog-remote.test.ts +193 -0
  41. package/packages/server/src/__tests__/cli-parse.test.ts +22 -4
  42. package/packages/server/src/__tests__/cold-boot-openspec-broadcast.test.ts +161 -0
  43. package/packages/server/src/__tests__/directory-service-refresh-force.test.ts +1 -1
  44. package/packages/server/src/__tests__/directory-service-specs-mtime.test.ts +1 -1
  45. package/packages/server/src/__tests__/directory-service-toctou.test.ts +1 -1
  46. package/packages/server/src/__tests__/directory-service.test.ts +1 -1
  47. package/packages/server/src/__tests__/doctor-route.test.ts +132 -0
  48. package/packages/server/src/__tests__/event-wiring-providers-list.test.ts +154 -0
  49. package/packages/server/src/__tests__/fixtures/pi-changelog-slice.md +180 -0
  50. package/packages/server/src/__tests__/fork-empty-session-preflight.test.ts +268 -0
  51. package/packages/server/src/__tests__/has-openspec-dir.test.ts +64 -0
  52. package/packages/server/src/__tests__/headless-pid-registry.test.ts +83 -0
  53. package/packages/server/src/__tests__/health-shape.test.ts +43 -0
  54. package/packages/server/src/__tests__/idle-timer-respects-terminals.test.ts +115 -0
  55. package/packages/server/src/__tests__/is-pi-process.test.ts +1 -1
  56. package/packages/server/src/__tests__/openspec-connect-snapshot.test.ts +92 -0
  57. package/packages/server/src/__tests__/package-manager-wrapper-resolve.test.ts +4 -4
  58. package/packages/server/src/__tests__/package-routes.test.ts +1 -1
  59. package/packages/server/src/__tests__/pending-fork-registry.test.ts +48 -24
  60. package/packages/server/src/__tests__/pi-changelog-integration.test.ts +165 -0
  61. package/packages/server/src/__tests__/pi-changelog-routes.test.ts +409 -0
  62. package/packages/server/src/__tests__/pi-core-checker.test.ts +155 -13
  63. package/packages/server/src/__tests__/pi-core-updater-managed-path.test.ts +236 -0
  64. package/packages/server/src/__tests__/pi-core-updater.test.ts +1 -1
  65. package/packages/server/src/__tests__/pi-dev-version-check.test.ts +184 -0
  66. package/packages/server/src/__tests__/pi-version-skew.test.ts +4 -4
  67. package/packages/server/src/__tests__/process-manager-codes.test.ts +80 -0
  68. package/packages/server/src/__tests__/process-manager-managed-path.test.ts +73 -0
  69. package/packages/server/src/__tests__/provider-auth-routes.test.ts +12 -4
  70. package/packages/server/src/__tests__/provider-auth-storage.test.ts +42 -11
  71. package/packages/server/src/__tests__/provider-catalogue-cache.test.ts +44 -0
  72. package/packages/server/src/__tests__/recommended-routes.test.ts +1 -1
  73. package/packages/server/src/__tests__/session-action-handler-spawn-error.test.ts +17 -2
  74. package/packages/server/src/__tests__/session-action-handler-spawn.test.ts +150 -0
  75. package/packages/server/src/__tests__/session-discovery-skill-firstmessage.test.ts +95 -0
  76. package/packages/server/src/__tests__/spawn-correlation-token-integration.test.ts +91 -0
  77. package/packages/server/src/__tests__/spawn-failure-log.test.ts +118 -0
  78. package/packages/server/src/__tests__/spawn-preflight.test.ts +91 -0
  79. package/packages/server/src/__tests__/spawn-register-watchdog.test.ts +250 -0
  80. package/packages/server/src/__tests__/spawn-token.test.ts +57 -0
  81. package/packages/server/src/__tests__/subscription-handler.test.ts +98 -6
  82. package/packages/server/src/__tests__/system-routes-reextract.test.ts +91 -0
  83. package/packages/server/src/__tests__/system-routes-spawn-failures.test.ts +84 -0
  84. package/packages/server/src/__tests__/terminal-manager.test.ts +45 -0
  85. package/packages/server/src/bootstrap-install-from-list.ts +232 -0
  86. package/packages/server/src/bootstrap-state.ts +18 -0
  87. package/packages/server/src/browser-gateway.ts +70 -24
  88. package/packages/server/src/browser-handlers/directory-handler.ts +4 -0
  89. package/packages/server/src/browser-handlers/handler-context.ts +9 -0
  90. package/packages/server/src/browser-handlers/session-action-handler.ts +159 -18
  91. package/packages/server/src/browser-handlers/subscription-handler.ts +50 -3
  92. package/packages/server/src/changelog-fs.ts +167 -0
  93. package/packages/server/src/changelog-parser.ts +321 -0
  94. package/packages/server/src/changelog-remote.ts +134 -0
  95. package/packages/server/src/cli.ts +23 -2
  96. package/packages/server/src/directory-service.ts +31 -0
  97. package/packages/server/src/event-wiring.ts +105 -5
  98. package/packages/server/src/headless-pid-registry.ts +54 -5
  99. package/packages/server/src/home-lock.d.ts +124 -0
  100. package/packages/server/src/home-lock.js +330 -0
  101. package/packages/server/src/home-lock.js.map +1 -0
  102. package/packages/server/src/idle-timer.ts +15 -1
  103. package/packages/server/src/pending-client-correlations.ts +73 -0
  104. package/packages/server/src/pending-fork-registry.ts +24 -12
  105. package/packages/server/src/pi-core-checker.ts +77 -17
  106. package/packages/server/src/pi-core-updater.ts +81 -15
  107. package/packages/server/src/pi-dev-version-check.ts +145 -0
  108. package/packages/server/src/pi-gateway.ts +10 -0
  109. package/packages/server/src/pi-version-skew.ts +12 -4
  110. package/packages/server/src/process-manager.ts +115 -21
  111. package/packages/server/src/provider-auth-handlers.ts +9 -0
  112. package/packages/server/src/provider-auth-storage.ts +83 -51
  113. package/packages/server/src/provider-catalogue-cache.ts +47 -0
  114. package/packages/server/src/routes/doctor-routes.ts +140 -0
  115. package/packages/server/src/routes/pi-changelog-routes.ts +194 -0
  116. package/packages/server/src/routes/pi-core-routes.ts +1 -1
  117. package/packages/server/src/routes/provider-auth-routes.ts +14 -1
  118. package/packages/server/src/routes/provider-routes.ts +4 -4
  119. package/packages/server/src/routes/system-routes.ts +38 -1
  120. package/packages/server/src/server.ts +85 -66
  121. package/packages/server/src/session-api.ts +54 -3
  122. package/packages/server/src/session-bootstrap.ts +27 -12
  123. package/packages/server/src/session-discovery.ts +11 -4
  124. package/packages/server/src/session-file-reader.ts +1 -1
  125. package/packages/server/src/session-scanner.ts +4 -2
  126. package/packages/server/src/spawn-failure-log.ts +130 -0
  127. package/packages/server/src/spawn-preflight.ts +82 -0
  128. package/packages/server/src/spawn-register-watchdog.ts +291 -0
  129. package/packages/server/src/spawn-token.ts +20 -0
  130. package/packages/server/src/terminal-manager.ts +12 -1
  131. package/packages/shared/package.json +1 -1
  132. package/packages/shared/src/__tests__/bootstrap/__snapshots__/cube.test.ts.snap +25 -17
  133. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/a-electron.test.ts.snap +5 -4
  134. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/b-npm-global.test.ts.snap +6 -5
  135. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/c-dev-monorepo.test.ts.snap +1 -0
  136. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/e-stale-partial.test.ts.snap +5 -4
  137. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/f-cwd-variants.test.ts.snap +2 -1
  138. package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/g-windows-specifics.test.ts.snap +6 -3
  139. package/packages/shared/src/__tests__/bootstrap/fixtures/dev-monorepo.ts +1 -1
  140. package/packages/shared/src/__tests__/bootstrap-install-resolve-npm.test.ts +72 -0
  141. package/packages/shared/src/__tests__/browser-protocol-types.test.ts +47 -1
  142. package/packages/shared/src/__tests__/changelog-types.test.ts +78 -0
  143. package/packages/shared/src/__tests__/config.test.ts +48 -0
  144. package/packages/shared/src/__tests__/dashboard-starter.test.ts +40 -0
  145. package/packages/shared/src/__tests__/detached-spawn.test.ts +24 -0
  146. package/packages/shared/src/__tests__/doctor-core.test.ts +134 -0
  147. package/packages/shared/src/__tests__/doctor-fault-tolerance.test.ts +218 -0
  148. package/packages/shared/src/__tests__/doctor-format.test.ts +121 -0
  149. package/packages/shared/src/__tests__/install-managed-node-bootstrap-order.test.ts +68 -0
  150. package/packages/shared/src/__tests__/install-managed-node.test.ts +192 -0
  151. package/packages/shared/src/__tests__/installable-list.test.ts +130 -0
  152. package/packages/shared/src/__tests__/managed-node-path.test.ts +122 -0
  153. package/packages/shared/src/__tests__/managed-runtime-strategy.test.ts +74 -0
  154. package/packages/shared/src/__tests__/no-installable-list-in-bridge.test.ts +52 -0
  155. package/packages/shared/src/__tests__/no-raw-openspec-status-in-skills.test.ts +6 -1
  156. package/packages/shared/src/__tests__/node-spawn-jiti-contract.test.ts +56 -20
  157. package/packages/shared/src/__tests__/resolve-jiti.test.ts +140 -9
  158. package/packages/shared/src/__tests__/skill-block-parser.test.ts +153 -0
  159. package/packages/shared/src/__tests__/tool-registry-definitions.test.ts +1 -1
  160. package/packages/shared/src/bootstrap-install.ts +197 -3
  161. package/packages/shared/src/browser-protocol.ts +155 -1
  162. package/packages/shared/src/changelog-types.ts +111 -0
  163. package/packages/shared/src/config.ts +15 -0
  164. package/packages/shared/src/dashboard-starter.ts +33 -0
  165. package/packages/shared/src/doctor-core.ts +821 -0
  166. package/packages/shared/src/index.ts +9 -0
  167. package/packages/shared/src/installable-list.ts +152 -0
  168. package/packages/shared/src/launch-source-flag.ts +14 -0
  169. package/packages/shared/src/launch-source-types.ts +18 -0
  170. package/packages/shared/src/openspec-activity-detector.ts +25 -7
  171. package/packages/shared/src/platform/detached-spawn.ts +13 -2
  172. package/packages/shared/src/platform/managed-node-path.ts +77 -0
  173. package/packages/shared/src/platform/node-spawn.ts +29 -21
  174. package/packages/shared/src/protocol.ts +54 -2
  175. package/packages/shared/src/resolve-jiti.ts +62 -9
  176. package/packages/shared/src/rest-api.ts +4 -0
  177. package/packages/shared/src/skill-block-parser.ts +115 -0
  178. package/packages/shared/src/tool-registry/__tests__/managed-runtime-strategy.test.ts +166 -0
  179. package/packages/shared/src/tool-registry/definitions.ts +33 -8
  180. package/packages/shared/src/tool-registry/strategies.ts +42 -0
  181. package/packages/shared/src/types.ts +64 -0
@@ -22,6 +22,14 @@ import type { EditorInstanceStatus } from "./editor-types.js";
22
22
  export interface SessionAddedMessage {
23
23
  type: "session_added";
24
24
  session: DashboardSession;
25
+ /**
26
+ * Echoed `requestId` from the originating browser `spawn_session` /
27
+ * `resume_session` (when known). Lets the client auto-select / dismiss
28
+ * placeholder by exact correlation, replacing the cwd-FIFO heuristic.
29
+ * Absent for server-initiated spawns (auto-resume, headless reload).
30
+ * See change: spawn-correlation-token.
31
+ */
32
+ spawnRequestId?: string;
25
33
  }
26
34
 
27
35
  export interface SessionUpdatedMessage {
@@ -118,6 +126,24 @@ export interface ResumeResultBrowserMessage {
118
126
  sessionId: string;
119
127
  success: boolean;
120
128
  message: string;
129
+ /** Echoed from input `resume_session.requestId` when provided. */
130
+ requestId?: string;
131
+ /**
132
+ * For `mode: "fork"` only — populated once the new fork's bridge has
133
+ * registered and been correlated. Absent for `mode: "continue"` (the
134
+ * sessionId is unchanged across the respawn).
135
+ * See change: spawn-correlation-token.
136
+ */
137
+ newSessionId?: string;
138
+ /**
139
+ * Optional structured failure classifier. Known values:
140
+ * - `"FORK_EMPTY_SESSION"`: fork attempted on a session whose
141
+ * `sessionFile` does not exist on disk yet (e.g., freshly spawned,
142
+ * no messages persisted).
143
+ * Old clients that don't read this field still get the human-readable
144
+ * `message`. See change: fix-fork-empty-session-silent-timeout.
145
+ */
146
+ code?: string;
121
147
  }
122
148
 
123
149
  export interface SpawnResultBrowserMessage {
@@ -125,6 +151,37 @@ export interface SpawnResultBrowserMessage {
125
151
  cwd: string;
126
152
  success: boolean;
127
153
  message: string;
154
+ /** Echoed from input `spawn_session.requestId` when provided. */
155
+ requestId?: string;
156
+ /** Spawned process PID when known (headless strategies); informational. */
157
+ pid?: number;
158
+ }
159
+
160
+ /**
161
+ * Failure classification codes for spawn errors.
162
+ * Set on every `{ success: false }` path inside process-manager and the
163
+ * session-action-handler. Additive — clients that do not know a code fall
164
+ * back to the `message` string.
165
+ * See change: spawn-failure-diagnostics.
166
+ */
167
+ export type SpawnFailureCode =
168
+ | "DIR_MISSING"
169
+ | "PI_NOT_FOUND"
170
+ | "WIN_PI_CMD_ONLY"
171
+ | "WT_MISSING"
172
+ | "TMUX_MISSING"
173
+ | "PI_CRASHED"
174
+ | "SPAWN_ERRNO"
175
+ | "PREFLIGHT_FAILED"
176
+ | "REGISTER_TIMEOUT";
177
+
178
+ /**
179
+ * A single reason from the synchronous spawn preflight check.
180
+ * See change: spawn-failure-diagnostics.
181
+ */
182
+ export interface PreflightReason {
183
+ code: string;
184
+ message: string;
128
185
  }
129
186
 
130
187
  /**
@@ -140,6 +197,37 @@ export interface SpawnErrorMessage {
140
197
  message: string;
141
198
  /** Up to ~2 KB tail of stderr captured from the failed child, if any. */
142
199
  stderr?: string;
200
+ /** Structured failure classifier. Additive — old clients ignore this field. See change: spawn-failure-diagnostics. */
201
+ code?: SpawnFailureCode;
202
+ /** Preflight failure reasons. Only set when code === "PREFLIGHT_FAILED". See change: spawn-failure-diagnostics. */
203
+ reasons?: PreflightReason[];
204
+ }
205
+
206
+ /**
207
+ * Emitted when a spawned pi session never sends `session_register` within
208
+ * the configured `spawnRegisterTimeoutMs` window.
209
+ * See change: spawn-failure-diagnostics.
210
+ */
211
+ export interface SpawnRegisterTimeoutMessage {
212
+ type: "spawn_register_timeout";
213
+ cwd: string;
214
+ /** Present for headless spawns; absent for tmux/wt/wsl-tmux. */
215
+ pid?: number;
216
+ /** Last 4 KB of the per-session stderr log, if available. */
217
+ stderrTail?: string;
218
+ /** The effective watchdog timeout in ms — so the UI can render e.g. "30s". See change: spawn-failure-diagnostics (fix W2). */
219
+ timeoutMs?: number;
220
+ }
221
+
222
+ /**
223
+ * Emitted when pi finally registers AFTER the watchdog already fired.
224
+ * The UI uses it to auto-clear the timeout banner for the given cwd.
225
+ * See change: spawn-failure-diagnostics.
226
+ */
227
+ export interface SpawnRegisterRecoveredMessage {
228
+ type: "spawn_register_recovered";
229
+ cwd: string;
230
+ pid?: number;
143
231
  }
144
232
 
145
233
  export interface SessionsReorderedMessage {
@@ -148,6 +236,28 @@ export interface SessionsReorderedMessage {
148
236
  sessionIds: string[];
149
237
  }
150
238
 
239
+ /**
240
+ * Atomic on-connect snapshot of the server's full session registry and
241
+ * per-cwd ordering. Replaces the legacy per-session `session_added` loop
242
+ * + per-cwd `sessions_reordered` loop that the gateway used to emit on
243
+ * each browser WS connect. Client SHALL replace its `sessions` Map and
244
+ * `sessionOrderMap` with this payload (no merging) so stale ids from a
245
+ * previous server lifetime are dropped atomically.
246
+ *
247
+ * Live updates after the snapshot continue using the incremental
248
+ * `session_added` / `session_updated` / `session_removed` /
249
+ * `sessions_reordered` messages.
250
+ *
251
+ * See change: fix-stale-sessions-on-reconnect.
252
+ */
253
+ export interface SessionsSnapshotMessage {
254
+ type: "sessions_snapshot";
255
+ /** Every session known to the server at construction time, alive AND ended. */
256
+ sessions: DashboardSession[];
257
+ /** cwd → ordered session ids. Only non-empty arrays are included. */
258
+ orders: Record<string, string[]>;
259
+ }
260
+
151
261
  export interface PinnedDirsUpdatedMessage {
152
262
  type: "pinned_dirs_updated";
153
263
  paths: string[];
@@ -362,6 +472,23 @@ export interface BrowserExtUiDecoratorMessage {
362
472
  removed?: boolean;
363
473
  }
364
474
 
475
+ /**
476
+ * Server → browser: register a base64-encoded image asset under a content
477
+ * hash for the given session. Forwarded verbatim from the bridge's
478
+ * `asset_register` message and replayed to reconnecting browsers (in
479
+ * chronological position relative to its referencing `message_update` /
480
+ * `message_end`). The client populates a per-session `Map<hash,{data,mime}>`
481
+ * consumed by the `MarkdownContent` `pi-asset:` resolver.
482
+ * See change: chat-markdown-local-images-and-math.
483
+ */
484
+ export interface BrowserAssetRegisterMessage {
485
+ type: "asset_register";
486
+ sessionId: string;
487
+ hash: string;
488
+ mimeType: string;
489
+ data: string;
490
+ }
491
+
365
492
  /** Sent when a plugin's config changes; carries only that plugin's namespace. */
366
493
  export interface PluginConfigUpdateMessage {
367
494
  type: "plugin_config_update";
@@ -392,7 +519,10 @@ export type ServerToBrowserMessage =
392
519
  | ResumeResultBrowserMessage
393
520
  | SpawnResultBrowserMessage
394
521
  | SpawnErrorMessage
522
+ | SpawnRegisterTimeoutMessage
523
+ | SpawnRegisterRecoveredMessage
395
524
  | SessionsReorderedMessage
525
+ | SessionsSnapshotMessage
396
526
  | PinnedDirsUpdatedMessage
397
527
  | TerminalAddedMessage
398
528
  | TerminalRemovedMessage
@@ -416,7 +546,8 @@ export type ServerToBrowserMessage =
416
546
  | BootstrapTicketCompleteMessage
417
547
  | BrowserUiModulesListMessage
418
548
  | BrowserUiDataListMessage
419
- | BrowserExtUiDecoratorMessage;
549
+ | BrowserExtUiDecoratorMessage
550
+ | BrowserAssetRegisterMessage;
420
551
 
421
552
  // ── Browser → Server ────────────────────────────────────────────────
422
553
 
@@ -476,6 +607,15 @@ export interface RequestModelsBrowserMessage {
476
607
  sessionId: string;
477
608
  }
478
609
 
610
+ /**
611
+ * Browser asks the server to forward `request_providers` to the bridge.
612
+ * See change: replace-hardcoded-provider-lists.
613
+ */
614
+ export interface RequestProvidersBrowserMessage {
615
+ type: "request_providers";
616
+ sessionId: string;
617
+ }
618
+
479
619
  export interface SetThinkingLevelBrowserMessage {
480
620
  type: "set_thinking_level";
481
621
  sessionId: string;
@@ -555,6 +695,12 @@ export interface ResumeSessionBrowserMessage {
555
695
  mode: "continue" | "fork";
556
696
  /** When forking, optionally fork from a specific session entry instead of the latest */
557
697
  entryId?: string;
698
+ /**
699
+ * Client-minted UUIDv4 used to correlate `resume_result` and (for fork mode)
700
+ * the eventual `session_added` for the new session. Optional for back-compat.
701
+ * See change: spawn-correlation-token.
702
+ */
703
+ requestId?: string;
558
704
  /**
559
705
  * Placement intent for the resumed session in the cwd's sessionOrder:
560
706
  * - "front" (default): move to top of alive tier (Resume button, REST,
@@ -589,6 +735,13 @@ export interface SpawnSessionBrowserMessage {
589
735
  * add-folder-task-checker-and-spawn-attach.
590
736
  */
591
737
  attachProposal?: string;
738
+ /**
739
+ * Client-minted UUIDv4 used to correlate `spawn_result` and the eventual
740
+ * `session_added` (which echoes it as `spawnRequestId`). Optional for
741
+ * back-compat with older clients.
742
+ * See change: spawn-correlation-token.
743
+ */
744
+ requestId?: string;
592
745
  }
593
746
 
594
747
  export interface AttachProposalBrowserMessage {
@@ -769,6 +922,7 @@ export type BrowserToServerMessage =
769
922
  | OpenSpecRefreshBrowserMessage
770
923
  | RenameSessionBrowserMessage
771
924
  | RequestModelsBrowserMessage
925
+ | RequestProvidersBrowserMessage
772
926
  | SetThinkingLevelBrowserMessage
773
927
  | SetModelBrowserMessage
774
928
  | ShutdownBrowserMessage
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Shared types for the pi changelog display feature.
3
+ *
4
+ * Server parses `CHANGELOG.md` files installed alongside core packages
5
+ * and the client renders the result via `WhatsNewDialog`. These types
6
+ * are the wire contract between the two halves.
7
+ *
8
+ * See change: pi-update-whats-new-panel.
9
+ */
10
+
11
+ /**
12
+ * One bullet point under a release section. Preserves the original
13
+ * markdown prose verbatim so issue/PR links and inline code formatting
14
+ * survive intact for the client renderer.
15
+ */
16
+ export interface ChangelogBullet {
17
+ /**
18
+ * Original markdown text of the bullet, with the leading `- `
19
+ * removed and any continuation lines joined with `\n`. Inline
20
+ * markdown (links, code spans, emphasis) is preserved exactly as
21
+ * written so the client can hand it to a markdown renderer.
22
+ */
23
+ text: string;
24
+ /**
25
+ * Issue / PR references mined from the prose via the canonical
26
+ * `([#NNN](URL))` pattern pi uses at end-of-bullet. May be empty
27
+ * when no such pattern is found. Order matches occurrence order.
28
+ * The `text` field still contains the link in its original form.
29
+ */
30
+ issues: { num: number; url: string }[];
31
+ }
32
+
33
+ /**
34
+ * One release entry parsed from a Keep-a-Changelog-style markdown
35
+ * document. Typed sub-section arrays are populated only when the
36
+ * corresponding H3 heading is present in the source.
37
+ */
38
+ export interface ChangelogRelease {
39
+ /**
40
+ * Version string lifted from the `## [<version>] - <date>` H2
41
+ * heading. The bracket contents are taken verbatim so versions
42
+ * like `0.4.3-rc.1` survive.
43
+ */
44
+ version: string;
45
+ /**
46
+ * Date string lifted from the H2 heading. Set to `null` when the
47
+ * date token is missing or fails to parse as a YYYY-MM-DD-ish form.
48
+ * Parser tolerance is intentional — pi has shipped rare entries
49
+ * with date ranges or missing dates.
50
+ */
51
+ date: string | null;
52
+ /** Bullets under `### Breaking Changes`, in source order. */
53
+ breaking: ChangelogBullet[];
54
+ /**
55
+ * Union of bullets under `### New Features` and `### Added`. Pi
56
+ * uses both labels at different times for the same concept, so
57
+ * we merge them. Source order is preserved within each sub-section
58
+ * and the two sub-sections are concatenated in source order.
59
+ */
60
+ features: ChangelogBullet[];
61
+ /** Bullets under `### Changed`. */
62
+ changed: ChangelogBullet[];
63
+ /** Bullets under `### Fixed`. */
64
+ fixed: ChangelogBullet[];
65
+ /**
66
+ * Full markdown text from the release's H2 line up to (but not
67
+ * including) the next H2 line. Retained as a fallback render path
68
+ * when the typed arrays don't capture the content (e.g. an
69
+ * unrecognized H3 heading).
70
+ */
71
+ raw: string;
72
+ }
73
+
74
+ /**
75
+ * Response shape for `GET /api/pi-core/changelog`. Always wraps the
76
+ * filtered release list in this envelope so the client gets the
77
+ * derived `hasBreaking` flag and the GitHub link in one round-trip.
78
+ */
79
+ export interface ChangelogResponse {
80
+ /** Package the changelog was parsed for. */
81
+ pkg: string;
82
+ /**
83
+ * Lower bound of the version range, EXCLUSIVE. Echoes the request
84
+ * query param. Releases at or below this version are filtered out.
85
+ */
86
+ from: string;
87
+ /**
88
+ * Upper bound of the version range, INCLUSIVE. Echoes the request
89
+ * query param. Releases above this version are filtered out.
90
+ */
91
+ to: string;
92
+ /**
93
+ * Filtered release list, ordered with the latest version FIRST.
94
+ * Empty when no releases exist in `(from, to]` or when the
95
+ * CHANGELOG could not be located.
96
+ */
97
+ releases: ChangelogRelease[];
98
+ /**
99
+ * Convenience flag derived from `releases.some(r => r.breaking.length > 0)`.
100
+ * Lets the client render the warning icon without re-walking the array.
101
+ */
102
+ hasBreaking: boolean;
103
+ /**
104
+ * Public URL to the full CHANGELOG on GitHub, derived from the
105
+ * package's `repository` field. `null` when the repository is not
106
+ * GitHub-hosted or is unparseable.
107
+ */
108
+ changelogUrl: string | null;
109
+ /** ISO timestamp at which the parser produced this response. */
110
+ parsedAt: string;
111
+ }
@@ -159,6 +159,12 @@ export interface DashboardConfig {
159
159
  reattachPlacement: ReattachPlacement;
160
160
  /** Persisted list of known remote servers */
161
161
  knownServers: KnownServer[];
162
+ /**
163
+ * How long (ms) to wait for a spawned pi session to send `session_register`
164
+ * before emitting a timeout warning. Default 30000 (30s). Clamped [5000, 120000].
165
+ * See change: spawn-failure-diagnostics.
166
+ */
167
+ spawnRegisterTimeoutMs: number;
162
168
  /**
163
169
  * Per-plugin config namespaces. Reserved top-level key.
164
170
  * Each plugin's config lives at plugins.<id>.*
@@ -178,6 +184,13 @@ const VALID_SPAWN_STRATEGIES: SpawnStrategy[] = ["tmux", "headless"];
178
184
  /** Default ask_user prompt timeout: 300 seconds (5 minutes). */
179
185
  export const DEFAULT_ASK_USER_PROMPT_TIMEOUT_SECONDS = 300;
180
186
 
187
+ /** Default + clamp for spawnRegisterTimeoutMs. See change: spawn-failure-diagnostics. */
188
+ export const DEFAULT_SPAWN_REGISTER_TIMEOUT_MS = 30000;
189
+ export function clampSpawnRegisterTimeoutMs(v: unknown): number {
190
+ if (typeof v !== "number" || isNaN(v)) return DEFAULT_SPAWN_REGISTER_TIMEOUT_MS;
191
+ return Math.max(5000, Math.min(120000, v));
192
+ }
193
+
181
194
  const DEFAULTS: DashboardConfig = {
182
195
  plugins: {},
183
196
  port: 8000,
@@ -199,6 +212,7 @@ const DEFAULTS: DashboardConfig = {
199
212
  knownServers: [],
200
213
  askUserPromptTimeoutSeconds: DEFAULT_ASK_USER_PROMPT_TIMEOUT_SECONDS,
201
214
  reattachPlacement: DEFAULT_REATTACH_PLACEMENT,
215
+ spawnRegisterTimeoutMs: 30000,
202
216
  };
203
217
 
204
218
  /**
@@ -399,6 +413,7 @@ export function loadConfig(): DashboardConfig {
399
413
  askUserPromptTimeoutSeconds: typeof parsed.askUserPromptTimeoutSeconds === "number"
400
414
  ? parsed.askUserPromptTimeoutSeconds
401
415
  : defaults.askUserPromptTimeoutSeconds,
416
+ spawnRegisterTimeoutMs: clampSpawnRegisterTimeoutMs(parsed.spawnRegisterTimeoutMs),
402
417
  };
403
418
 
404
419
  // Compute resolvedTrustedNetworks: merge trustedNetworks + auth.bypassHosts
@@ -0,0 +1,33 @@
1
+ /**
2
+ * DashboardStarter — identifies who launched the dashboard server process.
3
+ *
4
+ * "Bridge" — spawned by the pi bridge extension (server-launcher.ts).
5
+ * "Standalone" — invoked directly via CLI (`pi-dashboard` or `pi-dashboard start`).
6
+ * "Electron" — spawned by the Electron main process.
7
+ *
8
+ * The value is injected via the DASHBOARD_STARTER env var at spawn time.
9
+ * When unset or empty the default is "Standalone" (direct CLI invocation).
10
+ */
11
+
12
+ export type DashboardStarter = "Bridge" | "Standalone" | "Electron";
13
+
14
+ const VALID: ReadonlySet<string> = new Set<DashboardStarter>(["Bridge", "Standalone", "Electron"]);
15
+
16
+ /**
17
+ * Parse `env.DASHBOARD_STARTER` into a `DashboardStarter`.
18
+ *
19
+ * - Unset or empty → `"Standalone"` (direct CLI invocation default).
20
+ * - Valid value → that value.
21
+ * - Invalid value → logs `console.warn`, returns `"Standalone"`.
22
+ */
23
+ export function parseDashboardStarter(
24
+ env: Record<string, string | undefined>,
25
+ ): DashboardStarter {
26
+ const raw = env["DASHBOARD_STARTER"];
27
+ if (!raw) return "Standalone";
28
+ if (VALID.has(raw)) return raw as DashboardStarter;
29
+ console.warn(
30
+ `[dashboard-starter] Unknown DASHBOARD_STARTER value "${raw}"; defaulting to "Standalone".`,
31
+ );
32
+ return "Standalone";
33
+ }