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

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 (53) hide show
  1. package/AGENTS.md +38 -33
  2. package/README.md +1 -0
  3. package/docs/architecture.md +162 -4
  4. package/package.json +4 -4
  5. package/packages/extension/package.json +2 -2
  6. package/packages/extension/src/__tests__/connection-suppress-auto-start.test.ts +97 -0
  7. package/packages/extension/src/__tests__/session-sync.test.ts +81 -1
  8. package/packages/extension/src/bridge-context.ts +10 -0
  9. package/packages/extension/src/bridge.ts +22 -0
  10. package/packages/extension/src/connection.ts +29 -0
  11. package/packages/extension/src/server-auto-start.ts +16 -0
  12. package/packages/extension/src/session-sync.ts +14 -0
  13. package/packages/server/package.json +4 -4
  14. package/packages/server/src/__tests__/cli-restart.test.ts +78 -0
  15. package/packages/server/src/__tests__/config-api.test.ts +9 -0
  16. package/packages/server/src/__tests__/is-activity-event.test.ts +78 -0
  17. package/packages/server/src/__tests__/is-unread-trigger.test.ts +164 -0
  18. package/packages/server/src/__tests__/last-activity-broadcast.test.ts +190 -0
  19. package/packages/server/src/__tests__/reattach-placement.test.ts +231 -0
  20. package/packages/server/src/__tests__/restart-helper.test.ts +25 -0
  21. package/packages/server/src/__tests__/session-order-reboot.test.ts +117 -0
  22. package/packages/server/src/__tests__/session-scanner.test.ts +31 -0
  23. package/packages/server/src/__tests__/system-routes-restart.test.ts +128 -0
  24. package/packages/server/src/__tests__/unread-persistence.test.ts +55 -0
  25. package/packages/server/src/__tests__/unread-trigger-wiring.test.ts +210 -0
  26. package/packages/server/src/__tests__/viewed-session-tracker.test.ts +93 -0
  27. package/packages/server/src/browser-gateway.ts +36 -0
  28. package/packages/server/src/cli.ts +70 -2
  29. package/packages/server/src/event-status-extraction.ts +98 -1
  30. package/packages/server/src/event-wiring.ts +70 -1
  31. package/packages/server/src/memory-session-manager.ts +34 -3
  32. package/packages/server/src/pi-gateway.ts +4 -0
  33. package/packages/server/src/reattach-placement.ts +98 -0
  34. package/packages/server/src/restart-helper.ts +41 -2
  35. package/packages/server/src/routes/system-routes.ts +25 -1
  36. package/packages/server/src/server.ts +55 -3
  37. package/packages/server/src/session-scanner.ts +19 -0
  38. package/packages/server/src/viewed-session-tracker.ts +78 -0
  39. package/packages/shared/package.json +1 -1
  40. package/packages/shared/src/__tests__/config.test.ts +59 -0
  41. package/packages/shared/src/__tests__/mdns-discovery.test.ts +48 -1
  42. package/packages/shared/src/__tests__/no-bash-on-windows.test.ts +304 -0
  43. package/packages/shared/src/__tests__/no-hardcoded-node-modules-paths.test.ts +1 -1
  44. package/packages/shared/src/__tests__/node-spawn-jiti-contract.test.ts +107 -0
  45. package/packages/shared/src/__tests__/protocol.test.ts +11 -0
  46. package/packages/shared/src/__tests__/publish-workflow-contract.test.ts +92 -0
  47. package/packages/shared/src/browser-protocol.ts +25 -0
  48. package/packages/shared/src/config.ts +41 -0
  49. package/packages/shared/src/mdns-discovery.ts +32 -1
  50. package/packages/shared/src/platform/node-spawn.ts +30 -0
  51. package/packages/shared/src/protocol.ts +30 -1
  52. package/packages/shared/src/session-meta.ts +6 -0
  53. package/packages/shared/src/types.ts +19 -0
@@ -116,6 +116,36 @@ export function toFileUrl(pathOrUrl: string): string {
116
116
  *
117
117
  * Keeps a `platform` parameter for testability so unit tests on a POSIX
118
118
  * host can exercise the Windows branch without mutating `process.platform`.
119
+ *
120
+ * !! JITI VERSION CONTRACT !!
121
+ * The Windows-non-tsx arm assumes the jiti loader is from
122
+ * `@mariozechner/pi-coding-agent@0.70.x` (jiti 2.x with the `file:///`
123
+ * triple-slash URL handling fix). jiti 2.x correctly handles `file:///`
124
+ * URL entries on Windows — it was the version we carved this contract
125
+ * around in change `fix-windows-entry-script-url`.
126
+ *
127
+ * Newer jiti versions (e.g. jiti 2.6.5 in `pi-coding-agent@0.71.x`)
128
+ * MISBEHAVE on `file:///` entries: they normalize triple-slash to
129
+ * single-slash and prepend cwd as if the entry were a relative
130
+ * specifier, producing `<cwd>/file:/...` ENOENT errors.
131
+ *
132
+ * The Electron Windows codepath defends against this version drift by
133
+ * resolving jiti from the managed dir's `pi-coding-agent@0.70.0` (the
134
+ * version pinned in `packages/electron/offline-packages.json` and
135
+ * extracted into `~/.pi-dashboard/` by `installStandalone()` on first
136
+ * launch — see Defect 1 of change
137
+ * `fix-electron-windows-installer-and-server-bootstrap`). Since the
138
+ * managed-dir tree is pinned, the contract holds regardless of what
139
+ * jiti is on the user's PATH.
140
+ *
141
+ * If a future change bumps the offline-cacache `pi-coding-agent` pin to
142
+ * a version with a different jiti, RE-VERIFY this contract on Windows
143
+ * manually (run a packaged Electron app on Win10 + Win11) and either:
144
+ * 1. Update the contract (fix the file:// URL handling expectation), OR
145
+ * 2. Add a per-jiti-version branch here, OR
146
+ * 3. Switch the bundled loader to tsx (which has its own contract).
147
+ *
148
+ * Locked by `node-spawn-jiti-contract.test.ts`.
119
149
  */
120
150
  export function shouldUrlWrapEntry(
121
151
  loader: string | null | undefined,
@@ -22,6 +22,18 @@ export interface SessionRegisterMessage {
22
22
  eventCount?: number;
23
23
  /** OS process ID of the pi agent — used for force-kill escalation */
24
24
  pid?: number;
25
+ /**
26
+ * Why the bridge is registering this session. The bridge sets this to
27
+ * `"spawn"` for the very first `session_register` after process boot
28
+ * and for every register emitted by the new/fork/resume path
29
+ * (`handleSessionChange`), and `"reattach"` for any subsequent
30
+ * `sendStateSync` triggered by a WebSocket reconnect to the dashboard
31
+ * server (i.e. the dashboard restarted while the bridge stayed alive).
32
+ * When omitted (legacy bridges), the server treats the message as if
33
+ * `"spawn"` was specified.
34
+ * See change: reattach-move-to-front.
35
+ */
36
+ registerReason?: "spawn" | "reattach";
25
37
  }
26
38
 
27
39
  export interface SessionUnregisterMessage {
@@ -463,6 +475,22 @@ export interface PromptResponseServerMessage {
463
475
  source: string;
464
476
  }
465
477
 
478
+ /**
479
+ * Server → extension: the dashboard server is about to exit as part of a
480
+ * deliberate restart or shutdown. Bridges that receive this MUST suppress
481
+ * the spawn step in `server-auto-start.ts` for `quiesceMs` ms; mDNS
482
+ * discovery + health-check probes still run, so reconnection to the
483
+ * orchestrator-spawned replacement is unaffected.
484
+ *
485
+ * See change: fix-restart-bridge-auto-start-race.
486
+ */
487
+ export interface ServerRestartingExtensionMessage {
488
+ type: "server_restarting";
489
+ reason: "restart" | "shutdown";
490
+ /** Suppression window in ms. Default 5000 for restart, 60000 for shutdown. */
491
+ quiesceMs: number;
492
+ }
493
+
466
494
  export type ServerToExtensionMessage =
467
495
  | SendPromptToExtensionMessage
468
496
  | AbortToExtensionMessage
@@ -489,4 +517,5 @@ export type ServerToExtensionMessage =
489
517
  | RolePresetDeleteExtensionMessage
490
518
  | RequestRolesMessage
491
519
  | UiManagementMessage
492
- | KillProcessMessage;
520
+ | KillProcessMessage
521
+ | ServerRestartingExtensionMessage;
@@ -18,6 +18,12 @@ export interface SessionMeta {
18
18
  // Cached identity & state (from .jsonl header / bridge)
19
19
  cwd?: string;
20
20
  status?: string;
21
+ /**
22
+ * Per-session unread bit; mirrors `DashboardSession.unread`. Persists across
23
+ * server restarts so an unread session stays unread until viewed.
24
+ * See change: session-card-unread-stripes.
25
+ */
26
+ unread?: boolean;
21
27
  startedAt?: number;
22
28
  endedAt?: number;
23
29
  firstMessage?: string;
@@ -15,6 +15,25 @@ export interface DashboardSession {
15
15
  thinkingLevel?: string;
16
16
  startedAt: number;
17
17
  endedAt?: number;
18
+ /**
19
+ * Epoch ms timestamp of the most recent activity event observed for this
20
+ * session. Server-managed: stamped in `event-wiring.ts` whenever an
21
+ * `event_forward` arrives whose `eventType` is on the activity-event
22
+ * allowlist (`isActivityEvent`). NOT persisted to `.meta.json`; cold-start
23
+ * seeded from `events.jsonl` mtime in `session-scanner.ts`. Drives the
24
+ * session-card relative-time badge via `selectBadgeTimestamp`.
25
+ * See change: session-card-last-activity-badge.
26
+ */
27
+ lastActivityAt?: number;
28
+ /**
29
+ * Server-managed per-session unread bit. `true` when an attention-worthy
30
+ * event (turn finished, ask_user appeared, agent_end with error) fired
31
+ * while no browser was viewing the session. Cleared when any browser
32
+ * sends `session_view`. Persisted to `.meta.json` so it survives reload.
33
+ * Bridges SHALL NOT send this field.
34
+ * See change: session-card-unread-stripes.
35
+ */
36
+ unread?: boolean;
18
37
  tokensIn?: number;
19
38
  tokensOut?: number;
20
39
  cacheRead?: number;