@blackbelt-technology/pi-agent-dashboard 0.5.3 → 0.5.4
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 +19 -30
- package/README.md +69 -1
- package/docs/architecture.md +89 -165
- package/package.json +10 -7
- package/packages/extension/package.json +2 -2
- package/packages/extension/src/__tests__/bridge-default-model-gate.test.ts +47 -0
- package/packages/extension/src/__tests__/bridge-followup-chat-order.test.ts +215 -0
- package/packages/extension/src/__tests__/bridge-followup-multi-entry.test.ts +202 -0
- package/packages/extension/src/__tests__/bridge-queue-update-forward.test.ts +77 -0
- package/packages/extension/src/__tests__/bridge-retry-ordering.test.ts +148 -0
- package/packages/extension/src/__tests__/bridge-shadow-queue-drain.test.ts +221 -0
- package/packages/extension/src/__tests__/bridge-shadow-queue-gate.test.ts +299 -0
- package/packages/extension/src/__tests__/bridge-shutdown-reset.test.ts +238 -0
- package/packages/extension/src/__tests__/bridge-slash-command-routing.test.ts +127 -31
- package/packages/extension/src/__tests__/command-handler.test.ts +105 -3
- package/packages/extension/src/__tests__/fixtures/usage-limit-error-strings.ts +127 -0
- package/packages/extension/src/__tests__/source-detector.test.ts +15 -0
- package/packages/extension/src/__tests__/usage-limit-orderer.test.ts +12 -0
- package/packages/extension/src/bridge-default-model-gate.ts +32 -0
- package/packages/extension/src/bridge.ts +299 -20
- package/packages/extension/src/command-handler.ts +53 -7
- package/packages/extension/src/dashboard-default-adapter.ts +5 -0
- package/packages/extension/src/prompt-bus.ts +15 -0
- package/packages/extension/src/slash-dispatch.ts +30 -15
- package/packages/extension/src/source-detector.ts +13 -5
- package/packages/extension/src/usage-limit-orderer.ts +18 -1
- package/packages/server/bin/pi-dashboard.mjs +62 -14
- package/packages/server/package.json +9 -5
- package/packages/server/src/__tests__/browser-gateway-register-handler.test.ts +69 -0
- package/packages/server/src/__tests__/cli-env-no-clobber.test.ts +46 -0
- package/packages/server/src/__tests__/cli-no-bootstrap-references.test.ts +69 -0
- package/packages/server/src/__tests__/cli-parse.test.ts +9 -10
- package/packages/server/src/__tests__/cli-version.test.ts +151 -0
- package/packages/server/src/__tests__/directory-service-openspec-enabled.test.ts +9 -0
- package/packages/server/src/__tests__/directory-service-refresh-force.test.ts +9 -0
- package/packages/server/src/__tests__/directory-service-specs-mtime.test.ts +9 -0
- package/packages/server/src/__tests__/directory-service-toctou.test.ts +9 -0
- package/packages/server/src/__tests__/directory-service.test.ts +9 -0
- package/packages/server/src/__tests__/doctor-route.test.ts +53 -0
- package/packages/server/src/__tests__/event-wiring-queue-state.test.ts +156 -0
- package/packages/server/src/__tests__/event-wiring-resume-clear.test.ts +105 -0
- package/packages/server/src/__tests__/health-shape.test.ts +35 -12
- package/packages/server/src/__tests__/installed-package-enricher.test.ts +12 -12
- package/packages/server/src/__tests__/is-activity-event.test.ts +4 -7
- package/packages/server/src/__tests__/package-routes.test.ts +6 -2
- package/packages/server/src/__tests__/pi-changelog-routes.test.ts +10 -13
- package/packages/server/src/__tests__/pi-core-checker.test.ts +2 -2
- package/packages/server/src/__tests__/pi-version-skew.test.ts +3 -2
- package/packages/server/src/__tests__/plugin-activation-routes.test.ts +267 -0
- package/packages/server/src/__tests__/plugin-intent-cache.test.ts +75 -0
- package/packages/server/src/__tests__/preferences-store.test.ts +196 -0
- package/packages/server/src/__tests__/reattach-placement.test.ts +9 -0
- package/packages/server/src/__tests__/recommended-routes.test.ts +2 -2
- package/packages/server/src/__tests__/recovery-server.test.ts +203 -0
- package/packages/server/src/__tests__/session-action-handler-clear-queue.test.ts +153 -0
- package/packages/server/src/__tests__/session-action-handler-headless-reload.test.ts +43 -0
- package/packages/server/src/__tests__/session-order-manager.test.ts +9 -0
- package/packages/server/src/__tests__/session-order-reboot.test.ts +9 -0
- package/packages/server/src/__tests__/session-ordering-integration.test.ts +9 -0
- package/packages/server/src/browser-gateway.ts +83 -5
- package/packages/server/src/browser-handlers/directory-handler.ts +69 -0
- package/packages/server/src/browser-handlers/session-action-handler.ts +89 -0
- package/packages/server/src/browser-handlers/subscription-handler.ts +23 -0
- package/packages/server/src/changelog-parser.ts +1 -1
- package/packages/server/src/cli.ts +68 -250
- package/packages/server/src/event-status-extraction.ts +14 -62
- package/packages/server/src/event-wiring.ts +23 -10
- package/packages/server/src/memory-session-manager.ts +4 -0
- package/packages/server/src/pi-core-checker.ts +1 -1
- package/packages/server/src/pi-dev-version-check.ts +1 -1
- package/packages/server/src/pi-version-skew.ts +24 -46
- package/packages/server/src/plugin-intent-cache.ts +67 -0
- package/packages/server/src/preferences-store.ts +199 -13
- package/packages/server/src/recovery-server.ts +366 -0
- package/packages/server/src/routes/__tests__/manifest-route.test.ts +138 -0
- package/packages/server/src/routes/doctor-routes.ts +26 -21
- package/packages/server/src/routes/manifest-route.ts +162 -0
- package/packages/server/src/routes/openspec-routes.ts +4 -25
- package/packages/server/src/routes/pi-changelog-routes.ts +5 -24
- package/packages/server/src/routes/pi-core-routes.ts +3 -23
- package/packages/server/src/routes/plugin-activation-routes.ts +193 -0
- package/packages/server/src/routes/recommended-routes.ts +21 -0
- package/packages/server/src/routes/system-routes.ts +73 -11
- package/packages/server/src/server.ts +105 -307
- package/packages/server/src/session-api.ts +5 -63
- package/packages/shared/package.json +1 -1
- package/packages/shared/src/__tests__/binary-lookup-resolveJiti.test.ts +28 -0
- package/packages/shared/src/__tests__/binary-lookup-spawn-env.test.ts +61 -0
- package/packages/shared/src/__tests__/binary-lookup.test.ts +16 -0
- package/packages/shared/src/__tests__/bridge-register.test.ts +67 -0
- package/packages/shared/src/__tests__/ci-electron-no-side-effects.test.ts +129 -0
- package/packages/shared/src/__tests__/config.test.ts +40 -0
- package/packages/shared/src/__tests__/dashboard-paths.test.ts +81 -0
- package/packages/shared/src/__tests__/ensure-windows-path.test.ts +112 -0
- package/packages/shared/src/__tests__/intent-types.test.ts +120 -0
- package/packages/shared/src/__tests__/jiti-packages-parity.test.ts +85 -0
- package/packages/shared/src/__tests__/legacy-managed-dir.test.ts +59 -0
- package/packages/shared/src/__tests__/no-direct-child-process.test.ts +12 -0
- package/packages/shared/src/__tests__/no-electron-execpath-spawn.test.ts +149 -0
- package/packages/shared/src/__tests__/no-flow-command-route-claims.test.ts +71 -0
- package/packages/shared/src/__tests__/no-flow-references-in-shell.test.ts +221 -0
- package/packages/shared/src/__tests__/no-managed-dir-reference.test.ts +134 -0
- package/packages/shared/src/__tests__/no-pi-dashboard-version-jiti-gate.test.ts +41 -0
- package/packages/shared/src/__tests__/no-primitive-direct-import.test.ts +235 -0
- package/packages/shared/src/__tests__/no-server-imports-in-resolver.test.ts +53 -0
- package/packages/shared/src/__tests__/node-spawn-jiti-contract.test.ts +54 -101
- package/packages/shared/src/__tests__/node-spawn.test.ts +29 -13
- package/packages/shared/src/__tests__/pi-package-resolver.test.ts +300 -0
- package/packages/shared/src/__tests__/plugin-activation-contracts.test.ts +74 -0
- package/packages/shared/src/__tests__/plugin-bridge-classify-source.test.ts +73 -0
- package/packages/shared/src/__tests__/plugin-bridge-register-extended.test.ts +17 -5
- package/packages/shared/src/__tests__/plugin-bridge-register-packages.test.ts +233 -0
- package/packages/shared/src/__tests__/plugin-bridge-register.test.ts +19 -9
- package/packages/shared/src/__tests__/publish-workflow-contract.test.ts +154 -15
- package/packages/shared/src/__tests__/recommended-extensions.test.ts +28 -10
- package/packages/shared/src/__tests__/resolver-parity-with-scanner.test.ts +76 -0
- package/packages/shared/src/__tests__/server-identity.test.ts +127 -0
- package/packages/shared/src/__tests__/server-launcher.test.ts +35 -0
- package/packages/shared/src/__tests__/source-matching.test.ts +5 -5
- package/packages/shared/src/__tests__/sync-versions-spec.test.ts +76 -0
- package/packages/shared/src/__tests__/tool-registry-definitions.test.ts +50 -2
- package/packages/shared/src/bridge-register.ts +35 -2
- package/packages/shared/src/browser-protocol.ts +176 -2
- package/packages/shared/src/config.ts +12 -0
- package/packages/shared/src/dashboard-paths.ts +69 -0
- package/packages/shared/src/dashboard-plugin/index.ts +2 -0
- package/packages/shared/src/dashboard-plugin/intent-types.ts +93 -0
- package/packages/shared/src/dashboard-plugin/manifest-types.ts +55 -1
- package/packages/shared/src/dashboard-plugin/plugin-status.ts +82 -0
- package/packages/shared/src/dashboard-plugin/slot-props.ts +11 -0
- package/packages/shared/src/dashboard-plugin/slot-types.ts +16 -2
- package/packages/shared/src/dashboard-plugin/ui-primitives.ts +287 -0
- package/packages/shared/src/dashboard-starter.ts +22 -0
- package/packages/shared/src/doctor-core.ts +49 -27
- package/packages/shared/src/launch-source-types.ts +9 -9
- package/packages/shared/src/legacy-managed-dir.ts +97 -0
- package/packages/shared/src/mdns-discovery.ts +4 -1
- package/packages/shared/src/pi-package-resolver.ts +388 -0
- package/packages/shared/src/platform/binary-lookup.ts +27 -3
- package/packages/shared/src/platform/ensure-windows-path.ts +95 -0
- package/packages/shared/src/platform/exec.ts +22 -0
- package/packages/shared/src/platform/node-spawn.ts +42 -41
- package/packages/shared/src/plugin-bridge-register.ts +275 -18
- package/packages/shared/src/protocol.ts +94 -2
- package/packages/shared/src/recommended-extensions.ts +34 -10
- package/packages/shared/src/server-identity.ts +74 -5
- package/packages/shared/src/server-launcher.ts +20 -0
- package/packages/shared/src/source-matching.ts +1 -1
- package/packages/shared/src/tool-registry/__tests__/node-script-toargv-fallback.test.ts +84 -0
- package/packages/shared/src/tool-registry/definitions.ts +91 -7
- package/packages/shared/src/types.ts +12 -8
- package/scripts/maybe-patch-package.cjs +44 -0
- package/packages/server/src/__tests__/bootstrap-install-from-list.test.ts +0 -263
- package/packages/server/src/__tests__/bootstrap-queue.test.ts +0 -120
- package/packages/server/src/__tests__/bootstrap-routes.test.ts +0 -125
- package/packages/server/src/__tests__/bootstrap-state.test.ts +0 -119
- package/packages/server/src/__tests__/cli-bootstrap.test.ts +0 -36
- package/packages/server/src/__tests__/event-status-extraction-flow.test.ts +0 -55
- package/packages/server/src/__tests__/legacy-pi-cleanup.test.ts +0 -149
- package/packages/server/src/__tests__/post-install-openspec-refresh.test.ts +0 -180
- package/packages/server/src/__tests__/post-install-rescan.test.ts +0 -134
- package/packages/server/src/__tests__/system-routes-reextract.test.ts +0 -91
- package/packages/server/src/bootstrap-install-from-list.ts +0 -232
- package/packages/server/src/bootstrap-queue.ts +0 -130
- package/packages/server/src/bootstrap-state.ts +0 -159
- package/packages/server/src/legacy-pi-cleanup.ts +0 -151
- package/packages/server/src/routes/bootstrap-routes.ts +0 -125
- package/packages/shared/src/__tests__/bootstrap/README.md +0 -133
- package/packages/shared/src/__tests__/bootstrap/__snapshots__/cube.test.ts.snap +0 -378
- package/packages/shared/src/__tests__/bootstrap/assertions.ts +0 -136
- package/packages/shared/src/__tests__/bootstrap/cube.test.ts +0 -47
- package/packages/shared/src/__tests__/bootstrap/cube.ts +0 -66
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/a-electron.test.ts.snap +0 -84
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/b-npm-global.test.ts.snap +0 -90
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/c-dev-monorepo.test.ts.snap +0 -34
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/d-overrides.test.ts.snap +0 -20
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/e-stale-partial.test.ts.snap +0 -62
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/f-cwd-variants.test.ts.snap +0 -34
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/g-windows-specifics.test.ts.snap +0 -49
- package/packages/shared/src/__tests__/bootstrap/families/__snapshots__/j-path-gui-minimal.test.ts.snap +0 -12
- package/packages/shared/src/__tests__/bootstrap/families/a-electron.test.ts +0 -156
- package/packages/shared/src/__tests__/bootstrap/families/b-npm-global.test.ts +0 -157
- package/packages/shared/src/__tests__/bootstrap/families/c-dev-monorepo.test.ts +0 -102
- package/packages/shared/src/__tests__/bootstrap/families/d-overrides.test.ts +0 -76
- package/packages/shared/src/__tests__/bootstrap/families/e-stale-partial.test.ts +0 -94
- package/packages/shared/src/__tests__/bootstrap/families/f-cwd-variants.test.ts +0 -87
- package/packages/shared/src/__tests__/bootstrap/families/g-windows-specifics.test.ts +0 -143
- package/packages/shared/src/__tests__/bootstrap/families/h-home-drift.test.ts +0 -64
- package/packages/shared/src/__tests__/bootstrap/families/i-malformed-settings.test.ts +0 -77
- package/packages/shared/src/__tests__/bootstrap/families/index.ts +0 -19
- package/packages/shared/src/__tests__/bootstrap/families/j-path-gui-minimal.test.ts +0 -61
- package/packages/shared/src/__tests__/bootstrap/families/k-dashboard-absent.test.ts +0 -50
- package/packages/shared/src/__tests__/bootstrap/families/l-instance-coordination.test.ts +0 -272
- package/packages/shared/src/__tests__/bootstrap/fixtures/dev-monorepo.ts +0 -58
- package/packages/shared/src/__tests__/bootstrap/fixtures/electron-layout.ts +0 -84
- package/packages/shared/src/__tests__/bootstrap/fixtures/index.ts +0 -9
- package/packages/shared/src/__tests__/bootstrap/fixtures/managed-install.ts +0 -85
- package/packages/shared/src/__tests__/bootstrap/fixtures/npm-global-layout.ts +0 -122
- package/packages/shared/src/__tests__/bootstrap/fixtures/pi-versions.ts +0 -36
- package/packages/shared/src/__tests__/bootstrap/fixtures/settings-json.ts +0 -39
- package/packages/shared/src/__tests__/bootstrap/harness.smoke.test.ts +0 -220
- package/packages/shared/src/__tests__/bootstrap/harness.ts +0 -413
- package/packages/shared/src/__tests__/bootstrap/scenarios-skipped.ts +0 -125
- package/packages/shared/src/__tests__/bootstrap/scenarios.ts +0 -132
- package/packages/shared/src/__tests__/bootstrap-install-resolve-npm.test.ts +0 -72
- package/packages/shared/src/__tests__/install-managed-node-bootstrap-order.test.ts +0 -68
- package/packages/shared/src/__tests__/install-managed-node.test.ts +0 -192
- package/packages/shared/src/__tests__/installable-list.test.ts +0 -130
- package/packages/shared/src/__tests__/no-installable-list-in-bridge.test.ts +0 -52
- package/packages/shared/src/bootstrap-install.ts +0 -406
- package/packages/shared/src/installable-list.ts +0 -152
- package/packages/shared/src/launch-source-flag.ts +0 -14
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Server ↔ Browser WebSocket protocol messages.
|
|
3
3
|
*/
|
|
4
|
+
import type {
|
|
5
|
+
PluginIntentsMessage,
|
|
6
|
+
PluginActionMessage,
|
|
7
|
+
} from "./dashboard-plugin/intent-types.js";
|
|
4
8
|
import type {
|
|
5
9
|
DashboardSession,
|
|
6
10
|
DashboardEvent,
|
|
@@ -277,6 +281,28 @@ export interface PinnedDirsUpdatedMessage {
|
|
|
277
281
|
paths: string[];
|
|
278
282
|
}
|
|
279
283
|
|
|
284
|
+
// ── Workspaces (folder-workspaces) ───────────────────────────────────
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Named, server-persisted, collapsible container grouping one or more
|
|
288
|
+
* folders. Membership is authoritative and orthogonal to pinning — a
|
|
289
|
+
* folder may be in `folders[]` and `pinnedDirectories` independently.
|
|
290
|
+
* Single-membership: a folder belongs to ≤1 workspace.
|
|
291
|
+
* See change: folder-workspaces.
|
|
292
|
+
*/
|
|
293
|
+
export interface Workspace {
|
|
294
|
+
id: string;
|
|
295
|
+
name: string;
|
|
296
|
+
collapsed: boolean;
|
|
297
|
+
folders: string[];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Server → browser: full workspace list snapshot (sent on subscribe + every mutation). */
|
|
301
|
+
export interface WorkspacesUpdatedMessage {
|
|
302
|
+
type: "workspaces_updated";
|
|
303
|
+
workspaces: Workspace[];
|
|
304
|
+
}
|
|
305
|
+
|
|
280
306
|
export interface TerminalAddedMessage {
|
|
281
307
|
type: "terminal_added";
|
|
282
308
|
terminal: TerminalSession;
|
|
@@ -551,6 +577,7 @@ export type ServerToBrowserMessage =
|
|
|
551
577
|
| SessionsReorderedMessage
|
|
552
578
|
| SessionsSnapshotMessage
|
|
553
579
|
| PinnedDirsUpdatedMessage
|
|
580
|
+
| WorkspacesUpdatedMessage
|
|
554
581
|
| TerminalAddedMessage
|
|
555
582
|
| TerminalRemovedMessage
|
|
556
583
|
| TerminalUpdatedMessage
|
|
@@ -574,7 +601,9 @@ export type ServerToBrowserMessage =
|
|
|
574
601
|
| BrowserUiModulesListMessage
|
|
575
602
|
| BrowserUiDataListMessage
|
|
576
603
|
| BrowserExtUiDecoratorMessage
|
|
577
|
-
| BrowserAssetRegisterMessage
|
|
604
|
+
| BrowserAssetRegisterMessage
|
|
605
|
+
| PluginIntentsMessage
|
|
606
|
+
| QueueUpdateToBrowserMessage;
|
|
578
607
|
|
|
579
608
|
// ── Browser → Server ────────────────────────────────────────────────
|
|
580
609
|
|
|
@@ -594,6 +623,8 @@ export interface SendPromptToBrowserMessage {
|
|
|
594
623
|
sessionId: string;
|
|
595
624
|
text: string;
|
|
596
625
|
images?: ImageContent[];
|
|
626
|
+
/** Delivery mode: "steer" (after current turn) or "followUp" (after agent finishes). Defaults to "followUp" when absent. See change: add-steering-message. */
|
|
627
|
+
delivery?: "steer" | "followUp";
|
|
597
628
|
}
|
|
598
629
|
|
|
599
630
|
export interface AbortToBrowserMessage {
|
|
@@ -601,6 +632,86 @@ export interface AbortToBrowserMessage {
|
|
|
601
632
|
sessionId: string;
|
|
602
633
|
}
|
|
603
634
|
|
|
635
|
+
/**
|
|
636
|
+
* Browser -> server: clear pi's steering queue for the given session.
|
|
637
|
+
* Server forwards as `clear_steering_queue`; bridge calls `pi.clearSteeringQueue()`.
|
|
638
|
+
* Pi emits a fresh `queue_update` reflecting the empty array, which the server
|
|
639
|
+
* caches + broadcasts. Idempotent on empty queue.
|
|
640
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
641
|
+
*/
|
|
642
|
+
export interface ClearSteeringQueueFromBrowserMessage {
|
|
643
|
+
type: "clear_steering_queue";
|
|
644
|
+
sessionId: string;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Browser -> server: clear pi's follow-up slot for the given session.
|
|
649
|
+
* Server forwards as `clear_followup_slot`; bridge calls `pi.clearFollowUpQueue()`.
|
|
650
|
+
* Idempotent on empty slot.
|
|
651
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
652
|
+
*/
|
|
653
|
+
export interface ClearFollowupSlotFromBrowserMessage {
|
|
654
|
+
type: "clear_followup_slot";
|
|
655
|
+
sessionId: string;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Browser -> server (v1, deprecated): replace pi's follow-up slot atomically.
|
|
660
|
+
* v2 prefers `edit_followup_entry { index: 0 }`. Bridge still accepts both
|
|
661
|
+
* for backward compatibility.
|
|
662
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
663
|
+
*/
|
|
664
|
+
export interface EditFollowupSlotFromBrowserMessage {
|
|
665
|
+
type: "edit_followup_slot";
|
|
666
|
+
sessionId: string;
|
|
667
|
+
text: string;
|
|
668
|
+
images?: ImageContent[];
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Browser -> server (v2): move follow-up entry at `index` to position 0.
|
|
673
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
674
|
+
*/
|
|
675
|
+
export interface PromoteFollowupEntryFromBrowserMessage {
|
|
676
|
+
type: "promote_followup_entry";
|
|
677
|
+
sessionId: string;
|
|
678
|
+
index: number;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Browser -> server (v2): remove follow-up entry at `index`.
|
|
683
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
684
|
+
*/
|
|
685
|
+
export interface RemoveFollowupEntryFromBrowserMessage {
|
|
686
|
+
type: "remove_followup_entry";
|
|
687
|
+
sessionId: string;
|
|
688
|
+
index: number;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* Browser -> server (v2): replace follow-up entry at `index`.
|
|
693
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
694
|
+
*/
|
|
695
|
+
export interface EditFollowupEntryFromBrowserMessage {
|
|
696
|
+
type: "edit_followup_entry";
|
|
697
|
+
sessionId: string;
|
|
698
|
+
index: number;
|
|
699
|
+
text: string;
|
|
700
|
+
images?: ImageContent[];
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Server -> browser: broadcast pi's queue mirror after a `queue_update`
|
|
705
|
+
* arrives from the bridge. Drives `Session.pendingQueues`.
|
|
706
|
+
* See change: add-followup-edit-and-steer-cancel.
|
|
707
|
+
*/
|
|
708
|
+
export interface QueueUpdateToBrowserMessage {
|
|
709
|
+
type: "queue_update";
|
|
710
|
+
sessionId: string;
|
|
711
|
+
steering: string[];
|
|
712
|
+
followUp: string[];
|
|
713
|
+
}
|
|
714
|
+
|
|
604
715
|
export interface RequestCommandsToBrowserMessage {
|
|
605
716
|
type: "request_commands";
|
|
606
717
|
sessionId: string;
|
|
@@ -803,6 +914,54 @@ export interface ReorderPinnedDirsMessage {
|
|
|
803
914
|
paths: string[];
|
|
804
915
|
}
|
|
805
916
|
|
|
917
|
+
// ── Workspace mutation messages (browser → server) ───────────────────
|
|
918
|
+
// See change: folder-workspaces. Verb-first to match pin_directory family.
|
|
919
|
+
|
|
920
|
+
export interface CreateWorkspaceMessage {
|
|
921
|
+
type: "create_workspace";
|
|
922
|
+
name: string;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
export interface RenameWorkspaceMessage {
|
|
926
|
+
type: "rename_workspace";
|
|
927
|
+
id: string;
|
|
928
|
+
name: string;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
export interface DeleteWorkspaceMessage {
|
|
932
|
+
type: "delete_workspace";
|
|
933
|
+
id: string;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
export interface SetWorkspaceCollapsedMessage {
|
|
937
|
+
type: "set_workspace_collapsed";
|
|
938
|
+
id: string;
|
|
939
|
+
collapsed: boolean;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
export interface AddFolderToWorkspaceMessage {
|
|
943
|
+
type: "add_folder_to_workspace";
|
|
944
|
+
id: string;
|
|
945
|
+
path: string;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
export interface RemoveFolderFromWorkspaceMessage {
|
|
949
|
+
type: "remove_folder_from_workspace";
|
|
950
|
+
id: string;
|
|
951
|
+
path: string;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
export interface ReorderWorkspaceFoldersMessage {
|
|
955
|
+
type: "reorder_workspace_folders";
|
|
956
|
+
id: string;
|
|
957
|
+
paths: string[];
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
export interface ReorderWorkspacesMessage {
|
|
961
|
+
type: "reorder_workspaces";
|
|
962
|
+
ids: string[];
|
|
963
|
+
}
|
|
964
|
+
|
|
806
965
|
export interface OpenSpecBulkArchiveBrowserMessage {
|
|
807
966
|
type: "openspec_bulk_archive";
|
|
808
967
|
cwd: string;
|
|
@@ -964,6 +1123,14 @@ export type BrowserToServerMessage =
|
|
|
964
1123
|
| PinDirectoryMessage
|
|
965
1124
|
| UnpinDirectoryMessage
|
|
966
1125
|
| ReorderPinnedDirsMessage
|
|
1126
|
+
| CreateWorkspaceMessage
|
|
1127
|
+
| RenameWorkspaceMessage
|
|
1128
|
+
| DeleteWorkspaceMessage
|
|
1129
|
+
| SetWorkspaceCollapsedMessage
|
|
1130
|
+
| AddFolderToWorkspaceMessage
|
|
1131
|
+
| RemoveFolderFromWorkspaceMessage
|
|
1132
|
+
| ReorderWorkspaceFoldersMessage
|
|
1133
|
+
| ReorderWorkspacesMessage
|
|
967
1134
|
| OpenSpecBulkArchiveBrowserMessage
|
|
968
1135
|
| CreateTerminalBrowserMessage
|
|
969
1136
|
| KillTerminalBrowserMessage
|
|
@@ -981,4 +1148,11 @@ export type BrowserToServerMessage =
|
|
|
981
1148
|
| UiManagementBrowserMessage
|
|
982
1149
|
| SessionViewBrowserMessage
|
|
983
1150
|
| SessionUnviewBrowserMessage
|
|
984
|
-
| KillProcessBrowserMessage
|
|
1151
|
+
| KillProcessBrowserMessage
|
|
1152
|
+
| ClearSteeringQueueFromBrowserMessage
|
|
1153
|
+
| ClearFollowupSlotFromBrowserMessage
|
|
1154
|
+
| EditFollowupSlotFromBrowserMessage
|
|
1155
|
+
| PromoteFollowupEntryFromBrowserMessage
|
|
1156
|
+
| RemoveFollowupEntryFromBrowserMessage
|
|
1157
|
+
| EditFollowupEntryFromBrowserMessage
|
|
1158
|
+
| PluginActionMessage;
|
|
@@ -212,6 +212,15 @@ export interface DashboardConfig {
|
|
|
212
212
|
cors: CorsConfig;
|
|
213
213
|
/** Last-used server address (host:port) for reconnection */
|
|
214
214
|
lastServer?: string;
|
|
215
|
+
/**
|
|
216
|
+
* Display name shown as the PWA app label when installed on a home screen
|
|
217
|
+
* or app drawer. Used as the `<source>` segment of the dynamic
|
|
218
|
+
* `/manifest.json` `name` field: `"Pi-Dash · <source>"`. Trimmed; blank /
|
|
219
|
+
* whitespace-only values are treated as unset and the server falls back to
|
|
220
|
+
* the request `Host` header (port stripped) → `os.hostname()` → literal
|
|
221
|
+
* `"Pi-Dash"`. See change: add-dynamic-pwa-manifest-naming.
|
|
222
|
+
*/
|
|
223
|
+
dashboardName?: string;
|
|
215
224
|
/** Whether the server was launched by the Electron app */
|
|
216
225
|
electronMode: boolean;
|
|
217
226
|
/**
|
|
@@ -574,6 +583,9 @@ export function loadConfig(): DashboardConfig {
|
|
|
574
583
|
: defaults.cors.allowedOrigins,
|
|
575
584
|
},
|
|
576
585
|
...(typeof parsed.lastServer === "string" ? { lastServer: parsed.lastServer } : {}),
|
|
586
|
+
...(typeof parsed.dashboardName === "string" && parsed.dashboardName.trim()
|
|
587
|
+
? { dashboardName: parsed.dashboardName }
|
|
588
|
+
: {}),
|
|
577
589
|
electronMode: parsed.electronMode === true,
|
|
578
590
|
knownServers: parseKnownServers(parsed.knownServers),
|
|
579
591
|
reattachPlacement: parseReattachPlacement(parsed.reattachPlacement),
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for filesystem paths the dashboard touches at runtime.
|
|
3
|
+
*
|
|
4
|
+
* Why this file exists
|
|
5
|
+
* --------------------
|
|
6
|
+
* Two distinct directories were historically conflated by `~/`-anchored
|
|
7
|
+
* `path.join` calls scattered across packages:
|
|
8
|
+
*
|
|
9
|
+
* ~/.pi/dashboard/ — config + the *server* log (`server.log`)
|
|
10
|
+
* ~/.pi-dashboard/ — the *managed* install dir (npm packages, etc.)
|
|
11
|
+
* Older bootstrap code also wrote an *installer*
|
|
12
|
+
* log to `~/.pi-dashboard/server.log` (note: same
|
|
13
|
+
* filename, different dir). That file is now
|
|
14
|
+
* legacy/dead in the V2 launch path.
|
|
15
|
+
*
|
|
16
|
+
* Loading-page recovery surfaced this on 2026-05-17: the IPC handler
|
|
17
|
+
* read `~/.pi-dashboard/server.log` (stale installer log from May 8)
|
|
18
|
+
* while the live server wrote to `~/.pi/dashboard/server.log`.
|
|
19
|
+
*
|
|
20
|
+
* All path math lives here. Every $HOME override goes through `env.homedir`
|
|
21
|
+
* so tests can re-root without mutating `os.homedir()`.
|
|
22
|
+
*
|
|
23
|
+
* See change: harvest-bootstrap-survivor-fixes (cherry-pick 1).
|
|
24
|
+
*/
|
|
25
|
+
import path from "node:path";
|
|
26
|
+
import os from "node:os";
|
|
27
|
+
import { getManagedDir as getManagedDirInternal, type ManagedPathsEnv } from "./managed-paths.js";
|
|
28
|
+
|
|
29
|
+
/** Shared env override surface — `homedir` only, mirrors `ManagedPathsEnv`. */
|
|
30
|
+
export type DashboardPathsEnv = ManagedPathsEnv;
|
|
31
|
+
|
|
32
|
+
/** `~/.pi/dashboard/` — config dir for `config.json`, `server.log`, etc. */
|
|
33
|
+
export function getDashboardConfigDir(env?: DashboardPathsEnv): string {
|
|
34
|
+
return path.join(env?.homedir ?? os.homedir(), ".pi", "dashboard");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** `~/.pi/dashboard/server.log` — the live dashboard server's stdout/stderr log. */
|
|
38
|
+
export function getDashboardServerLogPath(env?: DashboardPathsEnv): string {
|
|
39
|
+
return path.join(getDashboardConfigDir(env), "server.log");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* `~/.pi/dashboard/first-run-done` — sentinel file written by the Electron
|
|
44
|
+
* wizard on completion. Presence means the one-step welcome was shown and
|
|
45
|
+
* acknowledged; subsequent launches skip the wizard.
|
|
46
|
+
*
|
|
47
|
+
* Lives under `~/.pi/dashboard/` (not the legacy `~/.pi-dashboard/`) so it
|
|
48
|
+
* survives Electron whole-app updates and remains the same path across
|
|
49
|
+
* all install layouts.
|
|
50
|
+
*
|
|
51
|
+
* See change: eliminate-electron-runtime-install (Q2 ratification).
|
|
52
|
+
*/
|
|
53
|
+
export function getFirstRunMarkerPath(env?: DashboardPathsEnv): string {
|
|
54
|
+
return path.join(getDashboardConfigDir(env), "first-run-done");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** `~/.pi-dashboard/` — managed-install root (npm packages, etc.). Re-export. */
|
|
58
|
+
export function getManagedDir(env?: DashboardPathsEnv): string {
|
|
59
|
+
return getManagedDirInternal(env);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* `~/.pi-dashboard/server.log` — the legacy *installer* log. Distinct from
|
|
64
|
+
* the server log; left here so callers can be explicit about which file
|
|
65
|
+
* they want and the grep tooling has a single canonical reference.
|
|
66
|
+
*/
|
|
67
|
+
export function getInstallerLogPath(env?: DashboardPathsEnv): string {
|
|
68
|
+
return path.join(getManagedDir(env), "server.log");
|
|
69
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin intent protocol — wire-format types.
|
|
3
|
+
*
|
|
4
|
+
* Plugins describe per-session UI contributions as `IntentNode` JSON trees
|
|
5
|
+
* and broadcast them via `ServerPluginContext.broadcastToSubscribers`. The
|
|
6
|
+
* shell on every connected client receives the broadcast, looks up the
|
|
7
|
+
* referenced primitive name in its local UI primitive registry, and renders
|
|
8
|
+
* the resulting React component with the JSON-serializable props.
|
|
9
|
+
*
|
|
10
|
+
* Function references SHALL NOT cross the wire. Action handlers (onClick,
|
|
11
|
+
* onSubmit, etc.) are declared as `ActionDescriptor` objects; the client's
|
|
12
|
+
* IntentRenderer wires them to send `PluginActionMessage` back over the
|
|
13
|
+
* WebSocket when triggered.
|
|
14
|
+
*
|
|
15
|
+
* See change: adopt-server-driven-intent-rendering.
|
|
16
|
+
*/
|
|
17
|
+
import type { SlotId } from "./slot-types.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A node in an intent tree.
|
|
21
|
+
*
|
|
22
|
+
* The plugin describes WHAT to render by primitive name. The client's
|
|
23
|
+
* IntentRenderer resolves the name to a `ComponentType` from its local
|
|
24
|
+
* primitive registry.
|
|
25
|
+
*/
|
|
26
|
+
export interface IntentNode {
|
|
27
|
+
/** Stable primitive name. Resolved by useUiPrimitive on the client. */
|
|
28
|
+
primitive: string;
|
|
29
|
+
/**
|
|
30
|
+
* Props passed to the resolved component. Values may be primitives,
|
|
31
|
+
* serializable structures, OR nested IntentNodes (rendered recursively
|
|
32
|
+
* as React elements by IntentRenderer).
|
|
33
|
+
*/
|
|
34
|
+
props?: Record<string, unknown>;
|
|
35
|
+
/** Optional stable React key for reconciliation. Required for items in lists. */
|
|
36
|
+
key?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Optional action descriptors. The IntentRenderer wires these to send
|
|
39
|
+
* `PluginActionMessage` to the server when the user triggers them.
|
|
40
|
+
*/
|
|
41
|
+
actions?: Record<string, ActionDescriptor>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* What to send back to the server when the user triggers an action.
|
|
46
|
+
*
|
|
47
|
+
* Function references SHALL NOT cross the wire. This is what does instead.
|
|
48
|
+
*/
|
|
49
|
+
export interface ActionDescriptor {
|
|
50
|
+
/** The plugin to dispatch the action to (matches manifest id). */
|
|
51
|
+
pluginId: string;
|
|
52
|
+
/** Plugin-defined action name. */
|
|
53
|
+
action: string;
|
|
54
|
+
/** Optional payload. Must be JSON-serializable. */
|
|
55
|
+
payload?: Record<string, unknown>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Server → Browser envelope. One message per (slot, session) change from
|
|
60
|
+
* a plugin. The shell on every connected client receives it via the bridge
|
|
61
|
+
* fanout.
|
|
62
|
+
*/
|
|
63
|
+
export interface PluginIntentsMessage {
|
|
64
|
+
type: "plugin_intents";
|
|
65
|
+
/** The plugin emitting this intent. */
|
|
66
|
+
pluginId: string;
|
|
67
|
+
/**
|
|
68
|
+
* The session this intent applies to. `null` for global slots like
|
|
69
|
+
* `settings-section` that aren't bound to a single session.
|
|
70
|
+
*/
|
|
71
|
+
sessionId: string | null;
|
|
72
|
+
/** The slot this intent occupies. */
|
|
73
|
+
slot: SlotId;
|
|
74
|
+
/** The intent tree. `null` means "clear my contribution to this slot". */
|
|
75
|
+
intent: IntentNode | null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Browser → Server envelope. Emitted by the IntentRenderer when the user
|
|
80
|
+
* triggers an `ActionDescriptor` (e.g. a button click) inside a rendered
|
|
81
|
+
* intent tree.
|
|
82
|
+
*/
|
|
83
|
+
export interface PluginActionMessage {
|
|
84
|
+
type: "plugin_action";
|
|
85
|
+
/** Matches `ActionDescriptor.pluginId` on the originating intent. */
|
|
86
|
+
pluginId: string;
|
|
87
|
+
/** The session context this action originated in (may be `null`). */
|
|
88
|
+
sessionId: string | null;
|
|
89
|
+
/** Plugin-defined action name. */
|
|
90
|
+
action: string;
|
|
91
|
+
/** Optional payload. */
|
|
92
|
+
payload?: Record<string, unknown>;
|
|
93
|
+
}
|
|
@@ -19,7 +19,24 @@ export interface PluginClaim {
|
|
|
19
19
|
* Defaults to "general" if omitted.
|
|
20
20
|
*/
|
|
21
21
|
tab?: SettingsTab;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* URL path pattern (wouter syntax, must start with "/") for the
|
|
24
|
+
* `shell-overlay-route` slot. First-class field so the slot consumer
|
|
25
|
+
* has a typed contract instead of digging through `config`.
|
|
26
|
+
* Example: "/session/:sid/flow/:flowId/agent/:agentId".
|
|
27
|
+
*
|
|
28
|
+
* See change: fix-flows-plugin-polish (path-as-first-class-claim-field).
|
|
29
|
+
*/
|
|
30
|
+
path?: string;
|
|
31
|
+
/**
|
|
32
|
+
* For `shell-overlay-route` claims: which URL parameter holds the session
|
|
33
|
+
* id. The slot consumer uses this to resolve the parent session metadata
|
|
34
|
+
* via `useShellSession`. Defaults to "sid" when omitted.
|
|
35
|
+
*
|
|
36
|
+
* See change: fix-flows-plugin-polish (path-as-first-class-claim-field).
|
|
37
|
+
*/
|
|
38
|
+
sessionParam?: string;
|
|
39
|
+
/** Slot-specific extra config (escape hatch — prefer first-class fields). */
|
|
23
40
|
config?: Record<string, unknown>;
|
|
24
41
|
/**
|
|
25
42
|
* Optional exported predicate function name for filtering contributions.
|
|
@@ -40,6 +57,27 @@ export interface PluginClaim {
|
|
|
40
57
|
shouldRender?: string;
|
|
41
58
|
}
|
|
42
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Declarative requirements a plugin has on its environment.
|
|
62
|
+
* Probed by the dashboard-plugin-runtime; surfaced in PluginStatus.requirements.
|
|
63
|
+
*
|
|
64
|
+
* Names are matched against pi extensions (via /api/packages/installed),
|
|
65
|
+
* binaries (via the shared ToolRegistry), and named service probes from a
|
|
66
|
+
* closed built-in registry. Plugins SHALL NOT register additional service
|
|
67
|
+
* names in V1.
|
|
68
|
+
*
|
|
69
|
+
* See change: add-plugin-activation-ui (Layer 1.5).
|
|
70
|
+
*/
|
|
71
|
+
export interface PluginRequirements {
|
|
72
|
+
/** pi extension package identifiers (matched via the same logic
|
|
73
|
+
RECOMMENDED_EXTENSIONS uses: name / id / source / displayName). */
|
|
74
|
+
piExtensions?: string[];
|
|
75
|
+
/** Binaries that must resolve on PATH via the tool-registry. */
|
|
76
|
+
binaries?: string[];
|
|
77
|
+
/** Named service probes (closed built-in registry; "pi-model-proxy" only in V1). */
|
|
78
|
+
services?: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
43
81
|
/**
|
|
44
82
|
* The pi-dashboard-plugin manifest.
|
|
45
83
|
* Declared as the `pi-dashboard-plugin` field in a package.json,
|
|
@@ -65,6 +103,22 @@ export interface PluginManifest {
|
|
|
65
103
|
configSchema?: string;
|
|
66
104
|
/** Slot claims. */
|
|
67
105
|
claims: PluginClaim[];
|
|
106
|
+
/**
|
|
107
|
+
* Optional declarative requirements probed by the runtime and surfaced as
|
|
108
|
+
* `PluginStatus.requirements` / `missingRequirements`.
|
|
109
|
+
* See change: add-plugin-activation-ui (Layer 1.5).
|
|
110
|
+
*/
|
|
111
|
+
requires?: PluginRequirements;
|
|
112
|
+
/**
|
|
113
|
+
* Other plugin ids this plugin requires (hard, transitive). When a
|
|
114
|
+
* dependency is missing from discovery or disabled in config, the loader
|
|
115
|
+
* SHALL skip this plugin's server entry and surface the gap via
|
|
116
|
+
* `PluginStatus.missingDeps`. Cycles soft-fail at discovery (loaded: false
|
|
117
|
+
* for every plugin in the cycle).
|
|
118
|
+
*
|
|
119
|
+
* See change: add-plugin-activation-ui (Layer 2 — dependency graph).
|
|
120
|
+
*/
|
|
121
|
+
dependsOn?: string[];
|
|
68
122
|
/**
|
|
69
123
|
* When true, the plugin is a test fixture and SHALL be excluded from
|
|
70
124
|
* production bundles (NODE_ENV=production).
|
|
@@ -2,15 +2,97 @@
|
|
|
2
2
|
* Plugin status types used in /api/health.plugins[] and WebSocket broadcasts.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Where pi-coding-agent's loader will (or won't) find this plugin's bridge.
|
|
7
|
+
*
|
|
8
|
+
* - `"packages[]"` — bridge path present in `settings.json#packages[]`
|
|
9
|
+
* (pi reads this; bridge will load on session start)
|
|
10
|
+
* - `"dashboardPluginBridges"` — only present in the legacy key pi ignores
|
|
11
|
+
* (loaded: false expected)
|
|
12
|
+
* - `"none"` — plugin has no bridge entry or registration failed
|
|
13
|
+
*
|
|
14
|
+
* See change: fix-pi-flows-end-to-end (Group 2).
|
|
15
|
+
*/
|
|
16
|
+
export type BridgeLoadSource = "packages[]" | "dashboardPluginBridges" | "none";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Structured probe report for a plugin's declarative `requires`.
|
|
20
|
+
* See change: add-plugin-activation-ui (Layer 1.5).
|
|
21
|
+
*/
|
|
22
|
+
export interface PluginRequirementReport {
|
|
23
|
+
piExtensions: { name: string; satisfied: boolean }[];
|
|
24
|
+
binaries: { name: string; satisfied: boolean; resolvedPath?: string }[];
|
|
25
|
+
services: { name: string; satisfied: boolean; error?: string }[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Latest bridge-status probe forwarded from the pi-side extension (for
|
|
30
|
+
* status-emitting bridges like flows-anthropic-bridge). Omitted when the
|
|
31
|
+
* plugin has no bridge or hasn't reported yet.
|
|
32
|
+
*/
|
|
33
|
+
export interface BridgeProbeSnapshot {
|
|
34
|
+
status: "probing" | "waiting_peers" | "active" | "degraded";
|
|
35
|
+
/** Per-peer probe results keyed by the peer spec (e.g. "@pi/anthropic-messages"). */
|
|
36
|
+
peers: Record<string, { ok: boolean; reason?: string }>;
|
|
37
|
+
/** Unix-ms timestamp when the bridge emitted this snapshot. */
|
|
38
|
+
at: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
5
41
|
/** Status of a single discovered plugin, reported by /api/health. */
|
|
6
42
|
export interface PluginStatus {
|
|
7
43
|
id: string;
|
|
44
|
+
/**
|
|
45
|
+
* Human-readable name from the manifest. Used by the Plugins activation
|
|
46
|
+
* UI. Falls back to `id` at the consumer if absent on legacy payloads.
|
|
47
|
+
* See change: add-plugin-activation-ui.
|
|
48
|
+
*/
|
|
49
|
+
displayName: string;
|
|
8
50
|
enabled: boolean;
|
|
9
51
|
loaded: boolean;
|
|
10
52
|
/** Error message if the plugin failed to load or has a conflict. */
|
|
11
53
|
error?: string;
|
|
12
54
|
/** Number of slot claims declared in the plugin's manifest. */
|
|
13
55
|
claims: number;
|
|
56
|
+
/**
|
|
57
|
+
* Where the bridge entry is registered, classified at health-check time.
|
|
58
|
+
* See change: fix-pi-flows-end-to-end Group 2.
|
|
59
|
+
*/
|
|
60
|
+
bridgeLoadedFrom?: BridgeLoadSource;
|
|
61
|
+
/** Latest bridge-status probe (only present for status-emitting bridges). */
|
|
62
|
+
lastProbe?: BridgeProbeSnapshot;
|
|
63
|
+
/**
|
|
64
|
+
* Structured probe report against the plugin's declarative `requires`.
|
|
65
|
+
* Populated by the loader after `loadServerEntries` and refreshed on every
|
|
66
|
+
* successful `package_operation_complete` and at most every 30 seconds.
|
|
67
|
+
* Absent when the plugin declares no `requires`.
|
|
68
|
+
* See change: add-plugin-activation-ui.
|
|
69
|
+
*/
|
|
70
|
+
requirements?: PluginRequirementReport;
|
|
71
|
+
/**
|
|
72
|
+
* Flat list of unsatisfied requirement names across all three categories.
|
|
73
|
+
* Always `[]` when every requirement is satisfied or the plugin declares
|
|
74
|
+
* no `requires`. Never `undefined`.
|
|
75
|
+
* See change: add-plugin-activation-ui.
|
|
76
|
+
*/
|
|
77
|
+
missingRequirements?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* `dependsOn` array verbatim from the manifest. Empty when the plugin
|
|
80
|
+
* has no inter-plugin dependencies.
|
|
81
|
+
* See change: add-plugin-activation-ui (Layer 2 — dependency graph).
|
|
82
|
+
*/
|
|
83
|
+
dependsOn?: string[];
|
|
84
|
+
/**
|
|
85
|
+
* Plugin ids that declare THIS plugin in their `dependsOn`. Computed
|
|
86
|
+
* by the loader by inverting the graph. Empty when nothing depends on
|
|
87
|
+
* this plugin.
|
|
88
|
+
*/
|
|
89
|
+
dependents?: string[];
|
|
90
|
+
/**
|
|
91
|
+
* Plugin ids from `dependsOn` that are either missing from discovery or
|
|
92
|
+
* disabled in config. Non-empty implies the loader skipped this plugin's
|
|
93
|
+
* server entry (`loaded: false`).
|
|
94
|
+
*/
|
|
95
|
+
missingDeps?: string[];
|
|
14
96
|
}
|
|
15
97
|
|
|
16
98
|
/** WebSocket broadcast sent to all browsers when a plugin's config changes. */
|
|
@@ -42,6 +42,10 @@ export interface SlotPropsMap {
|
|
|
42
42
|
session: DashboardSession;
|
|
43
43
|
pluginContext: AnyPluginContext;
|
|
44
44
|
};
|
|
45
|
+
"session-card-flows": {
|
|
46
|
+
session: DashboardSession;
|
|
47
|
+
pluginContext: AnyPluginContext;
|
|
48
|
+
};
|
|
45
49
|
"workspace-action-bar": {
|
|
46
50
|
session: DashboardSession;
|
|
47
51
|
pluginContext: AnyPluginContext;
|
|
@@ -71,6 +75,13 @@ export interface SlotPropsMap {
|
|
|
71
75
|
onClose: () => void;
|
|
72
76
|
pluginContext: AnyPluginContext;
|
|
73
77
|
};
|
|
78
|
+
"shell-overlay-route": {
|
|
79
|
+
params: Record<string, string>;
|
|
80
|
+
/** DashboardSession metadata resolved from the URL’s session param (`config.sessionParam`, default `"sid"`). Undefined when the URL has no session id or no matching session. */
|
|
81
|
+
session?: DashboardSession;
|
|
82
|
+
onBack: () => void;
|
|
83
|
+
pluginContext: AnyPluginContext;
|
|
84
|
+
};
|
|
74
85
|
"settings-section": {
|
|
75
86
|
pluginContext: AnyPluginContext;
|
|
76
87
|
};
|
|
@@ -15,13 +15,15 @@ export type SlotId =
|
|
|
15
15
|
| "sidebar-folder-section"
|
|
16
16
|
| "session-card-action-bar"
|
|
17
17
|
| "workspace-action-bar"
|
|
18
|
-
|
|
18
|
+
| "shell-overlay-route"
|
|
19
|
+
// (session-card-memory and session-card-flows are also react-only; declared below for ordering)
|
|
19
20
|
| "content-inline-footer"
|
|
20
21
|
| "anchored-popover"
|
|
21
22
|
| "command-route"
|
|
22
23
|
| "tool-renderer"
|
|
23
24
|
// React-or-descriptor slots
|
|
24
25
|
| "session-card-memory"
|
|
26
|
+
| "session-card-flows"
|
|
25
27
|
| "session-card-badge"
|
|
26
28
|
| "content-view"
|
|
27
29
|
| "content-header-sticky"
|
|
@@ -54,6 +56,11 @@ export const SLOT_DEFINITIONS: Record<SlotId, SlotDefinition> = {
|
|
|
54
56
|
payloadTier: "react-only",
|
|
55
57
|
description: "Collapsible block above session list per workspace folder",
|
|
56
58
|
},
|
|
59
|
+
"shell-overlay-route": {
|
|
60
|
+
multiplicity: "many",
|
|
61
|
+
payloadTier: "react-only",
|
|
62
|
+
description: "Plugin-owned full-screen route mounted at top of the shell (desktop + mobile). Each claim ships a wouter path pattern via `config.path` and a React component receiving { params, onBack, session? }.",
|
|
63
|
+
},
|
|
57
64
|
"session-card-badge": {
|
|
58
65
|
multiplicity: "many",
|
|
59
66
|
payloadTier: "react-or-descriptor",
|
|
@@ -69,6 +76,11 @@ export const SLOT_DEFINITIONS: Record<SlotId, SlotDefinition> = {
|
|
|
69
76
|
payloadTier: "react-only",
|
|
70
77
|
description: "Memory/Honcho contributions inside the MEMORY subcard of a session card",
|
|
71
78
|
},
|
|
79
|
+
"session-card-flows": {
|
|
80
|
+
multiplicity: "many",
|
|
81
|
+
payloadTier: "react-only",
|
|
82
|
+
description: "Flow contributions inside the FLOWS subcard of a session card",
|
|
83
|
+
},
|
|
72
84
|
"workspace-action-bar": {
|
|
73
85
|
multiplicity: "many",
|
|
74
86
|
payloadTier: "react-only",
|
|
@@ -179,11 +191,13 @@ type SessionScopedSlot =
|
|
|
179
191
|
| "session-card-badge"
|
|
180
192
|
| "session-card-action-bar"
|
|
181
193
|
| "session-card-memory"
|
|
194
|
+
| "session-card-flows"
|
|
182
195
|
| "workspace-action-bar"
|
|
183
196
|
| "content-view"
|
|
184
197
|
| "content-header-sticky"
|
|
185
198
|
| "content-inline-footer"
|
|
186
|
-
| "command-route"
|
|
199
|
+
| "command-route"
|
|
200
|
+
| "shell-overlay-route";
|
|
187
201
|
|
|
188
202
|
/** Slot ids whose predicates receive a folder descriptor. */
|
|
189
203
|
type FolderScopedSlot = "sidebar-folder-section";
|