@pellux/goodvibes-tui 1.16.1 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/CHANGELOG.md +138 -9
  2. package/README.md +1 -1
  3. package/docs/foundation-artifacts/operator-contract.json +5490 -1806
  4. package/package.json +7 -7
  5. package/src/cli/completions/generate.ts +5 -4
  6. package/src/cli/config-overrides.ts +51 -11
  7. package/src/cli/doctor.ts +4 -5
  8. package/src/cli/entrypoint.ts +13 -8
  9. package/src/cli/help.ts +7 -6
  10. package/src/cli/launch-auto-update.ts +214 -0
  11. package/src/cli/management-commands.ts +82 -15
  12. package/src/cli/management.ts +0 -2
  13. package/src/cli/parser.ts +5 -0
  14. package/src/cli/status.ts +13 -0
  15. package/src/cli/surface-command.ts +5 -5
  16. package/src/cli/tui-startup.ts +60 -97
  17. package/src/cli/types.ts +2 -0
  18. package/src/config/index.ts +1 -1
  19. package/src/config/tui-extension-settings.ts +33 -0
  20. package/src/core/composer-state.ts +1 -1
  21. package/src/core/consolidation-receipt.ts +41 -0
  22. package/src/core/conversation-line-cache.ts +3 -3
  23. package/src/core/conversation-rendering.ts +18 -9
  24. package/src/core/conversation.ts +2 -2
  25. package/src/core/long-task-notifier.ts +7 -7
  26. package/src/core/memory-provenance.ts +67 -0
  27. package/src/core/pairing-devices.ts +49 -0
  28. package/src/core/pairing-handoff.ts +101 -0
  29. package/src/core/pairing-offers.ts +83 -0
  30. package/src/core/pairing-origin.ts +78 -0
  31. package/src/core/pairing-tailscale-gateway.ts +56 -0
  32. package/src/core/power-chip-source.ts +91 -0
  33. package/src/core/power-status.ts +95 -0
  34. package/src/core/stable-host.ts +171 -0
  35. package/src/core/stream-event-wiring.ts +29 -6
  36. package/src/core/system-message-noise.ts +1 -1
  37. package/src/core/system-message-router.ts +6 -6
  38. package/src/core/turn-budget-outcome.ts +60 -0
  39. package/src/core/turn-cancellation.ts +40 -1
  40. package/src/core/turn-event-wiring.ts +14 -8
  41. package/src/daemon/cli.ts +64 -58
  42. package/src/daemon/lifecycle.ts +41 -0
  43. package/src/daemon/service-commands.ts +5 -5
  44. package/src/export/cost-utils.ts +128 -6
  45. package/src/input/autocomplete.ts +2 -2
  46. package/src/input/command-registry.ts +55 -9
  47. package/src/input/commands/acp-runtime.ts +72 -0
  48. package/src/input/commands/ci-runtime.ts +5 -1
  49. package/src/input/commands/codebase-runtime.ts +6 -6
  50. package/src/input/commands/cost-runtime.ts +1 -1
  51. package/src/input/commands/devices-runtime.ts +109 -0
  52. package/src/input/commands/git-runtime.ts +28 -4
  53. package/src/input/commands/graph-runtime.ts +45 -0
  54. package/src/input/commands/health-runtime.ts +2 -2
  55. package/src/input/commands/intelligence-runtime.ts +1 -1
  56. package/src/input/commands/local-auth-runtime.ts +1 -1
  57. package/src/input/commands/local-provider-runtime.ts +49 -10
  58. package/src/input/commands/local-runtime.ts +53 -5
  59. package/src/input/commands/memory.ts +2 -2
  60. package/src/input/commands/operator-panel-runtime.ts +5 -5
  61. package/src/input/commands/operator-rpc.ts +32 -11
  62. package/src/input/commands/permissions-provenance.ts +1 -1
  63. package/src/input/commands/permissions-runtime.ts +99 -8
  64. package/src/input/commands/planning-runtime.ts +3 -3
  65. package/src/input/commands/platform-sandbox-runtime.ts +1 -1
  66. package/src/input/commands/power-runtime.ts +56 -0
  67. package/src/input/commands/provider-accounts-runtime.ts +71 -6
  68. package/src/input/commands/provider.ts +7 -5
  69. package/src/input/commands/qrcode-runtime.ts +14 -19
  70. package/src/input/commands/queue-runtime.ts +70 -0
  71. package/src/input/commands/recall-files-git.ts +13 -51
  72. package/src/input/commands/recall-files.ts +8 -11
  73. package/src/input/commands/recall-review.ts +2 -2
  74. package/src/input/commands/relay-runtime.ts +1 -1
  75. package/src/input/commands/remote-runtime.ts +1 -1
  76. package/src/input/commands/runtime-services.ts +4 -4
  77. package/src/input/commands/schedule-runtime.ts +14 -7
  78. package/src/input/commands/services-runtime.ts +1 -1
  79. package/src/input/commands/session-workflow.ts +2 -2
  80. package/src/input/commands/settings-sync-runtime.ts +2 -2
  81. package/src/input/commands/share-runtime.ts +1 -1
  82. package/src/input/commands/shell-core.ts +46 -68
  83. package/src/input/commands/subscription-runtime.ts +1 -1
  84. package/src/input/commands/update-runtime.ts +153 -96
  85. package/src/input/commands/work-plan-runtime.ts +1 -1
  86. package/src/input/commands/workstream-attempts.ts +6 -1
  87. package/src/input/commands/workstream-runtime.ts +46 -27
  88. package/src/input/commands/worktree-runtime.ts +35 -8
  89. package/src/input/commands.ts +10 -2
  90. package/src/input/config-modal-types.ts +14 -3
  91. package/src/input/config-modal.ts +75 -13
  92. package/src/input/feature-unit-layout.ts +93 -82
  93. package/src/input/feed-context-factory.ts +2 -2
  94. package/src/input/handler-command-route.ts +2 -2
  95. package/src/input/handler-content-actions.ts +1 -1
  96. package/src/input/handler-feed-routes.ts +7 -7
  97. package/src/input/handler-feed.ts +4 -4
  98. package/src/input/handler-interactions.ts +3 -2
  99. package/src/input/handler-modal-routes.ts +12 -4
  100. package/src/input/handler-modal-token-routes.ts +1 -1
  101. package/src/input/handler-onboarding-daemon-adopt.ts +2 -2
  102. package/src/input/handler-onboarding.ts +3 -2
  103. package/src/input/handler-picker-routes.ts +26 -13
  104. package/src/input/handler-shortcuts.ts +29 -6
  105. package/src/input/handler.ts +2 -2
  106. package/src/input/keybindings.ts +21 -3
  107. package/src/input/onboarding/onboarding-feature-units.ts +34 -27
  108. package/src/input/onboarding/onboarding-provider-key-fields.ts +112 -0
  109. package/src/input/onboarding/onboarding-wizard-apply.ts +22 -21
  110. package/src/input/onboarding/onboarding-wizard-external-surfaces.ts +17 -0
  111. package/src/input/onboarding/onboarding-wizard-network-adopt.ts +2 -2
  112. package/src/input/onboarding/onboarding-wizard-steps.ts +30 -42
  113. package/src/input/panel-integration-actions.ts +2 -2
  114. package/src/input/panel-mouse-geometry.ts +1 -1
  115. package/src/input/panel-paste-flood-guard.ts +1 -1
  116. package/src/input/provider-key-intake.ts +167 -0
  117. package/src/input/sandbox-exec-config.ts +2 -2
  118. package/src/input/selection-modal.ts +1 -1
  119. package/src/input/settings-modal-activation.ts +5 -0
  120. package/src/input/settings-modal-adjustment.ts +4 -31
  121. package/src/input/settings-modal-data.ts +52 -57
  122. package/src/input/settings-modal-mutations.ts +12 -68
  123. package/src/input/settings-modal-types.ts +27 -17
  124. package/src/input/settings-modal.ts +74 -55
  125. package/src/main.ts +90 -90
  126. package/src/panels/agent-inspector-shared.ts +4 -4
  127. package/src/panels/base-panel.ts +2 -2
  128. package/src/panels/builtin/agent.ts +4 -4
  129. package/src/panels/builtin/development.ts +4 -4
  130. package/src/panels/builtin/knowledge.ts +1 -1
  131. package/src/panels/builtin/operations.ts +83 -11
  132. package/src/panels/builtin/session.ts +5 -5
  133. package/src/panels/builtin/shared.ts +16 -4
  134. package/src/panels/builtin-modals.ts +59 -42
  135. package/src/panels/builtin-panels.ts +1 -1
  136. package/src/panels/cost-tracker-panel.ts +124 -7
  137. package/src/panels/diff-panel.ts +39 -6
  138. package/src/panels/eval-registry.ts +2 -2
  139. package/src/panels/fleet-acts.ts +446 -0
  140. package/src/panels/fleet-deep-link.ts +1 -1
  141. package/src/panels/fleet-gateway.ts +117 -0
  142. package/src/panels/fleet-observed-render.ts +128 -0
  143. package/src/panels/fleet-panel-format.ts +163 -11
  144. package/src/panels/fleet-panel-worktree-detail.ts +14 -0
  145. package/src/panels/fleet-panel.ts +73 -57
  146. package/src/panels/fleet-read-model.ts +84 -14
  147. package/src/panels/fleet-spawn.ts +266 -0
  148. package/src/panels/fleet-steer.ts +2 -2
  149. package/src/panels/fleet-stop.ts +41 -5
  150. package/src/panels/fleet-tabs.ts +15 -16
  151. package/src/panels/fleet-transcript.ts +5 -5
  152. package/src/panels/git-panel.ts +2 -2
  153. package/src/panels/index.ts +4 -1
  154. package/src/panels/local-auth-panel.ts +1 -1
  155. package/src/panels/memory-consolidation-gateway.ts +94 -0
  156. package/src/panels/modals/devices-modal.ts +161 -0
  157. package/src/panels/modals/hooks-modal.ts +1 -1
  158. package/src/panels/modals/keybindings-modal.ts +2 -2
  159. package/src/panels/modals/knowledge-modal.ts +1 -1
  160. package/src/panels/modals/marketplace-modal.ts +4 -4
  161. package/src/panels/modals/memory-modal.ts +153 -9
  162. package/src/panels/modals/modal-surface-helpers.ts +1 -1
  163. package/src/panels/modals/modal-theme.ts +1 -1
  164. package/src/panels/modals/pairing-modal.ts +198 -68
  165. package/src/panels/modals/planning-modal.ts +2 -2
  166. package/src/panels/modals/plugins-modal.ts +1 -1
  167. package/src/panels/modals/policy-modal.ts +1 -1
  168. package/src/panels/modals/security-modal.ts +7 -1
  169. package/src/panels/modals/skills-modal.ts +1 -1
  170. package/src/panels/modals/work-plan-modal.ts +3 -3
  171. package/src/panels/notifications-feed.ts +127 -0
  172. package/src/panels/notifications-panel.ts +160 -0
  173. package/src/panels/panel-manager.ts +9 -9
  174. package/src/panels/plugins-panel.ts +4 -4
  175. package/src/panels/project-planning-answer-actions.ts +1 -1
  176. package/src/panels/provider-health-routes.ts +2 -2
  177. package/src/panels/skills-panel.ts +4 -5
  178. package/src/panels/token-budget-panel.ts +11 -3
  179. package/src/panels/types.ts +5 -5
  180. package/src/panels/workstream-graph-render.ts +123 -0
  181. package/src/permissions/broker-approval-card.ts +201 -0
  182. package/src/permissions/hunk-selection.ts +28 -4
  183. package/src/permissions/prompt.ts +244 -29
  184. package/src/renderer/autocomplete-overlay.ts +107 -54
  185. package/src/renderer/code-block.ts +2 -2
  186. package/src/renderer/compaction-history-modal.ts +1 -1
  187. package/src/renderer/compaction-preview.ts +1 -1
  188. package/src/renderer/compaction-quality.ts +1 -1
  189. package/src/renderer/composer-fragments.ts +69 -0
  190. package/src/renderer/compositor.ts +2 -2
  191. package/src/renderer/config-modal.ts +1 -1
  192. package/src/renderer/conversation-overlays.ts +1 -1
  193. package/src/renderer/footer-tips.ts +3 -3
  194. package/src/renderer/hint-grammar.ts +1 -1
  195. package/src/renderer/modal-factory.ts +1 -1
  196. package/src/renderer/model-picker-overlay.ts +1 -1
  197. package/src/renderer/model-workspace.ts +7 -2
  198. package/src/renderer/panel-composite.ts +2 -2
  199. package/src/renderer/panel-workspace-bar.ts +1 -1
  200. package/src/renderer/process-indicator.ts +1 -1
  201. package/src/renderer/selection-modal-overlay.ts +1 -1
  202. package/src/renderer/session-picker-modal.ts +2 -2
  203. package/src/renderer/settings-modal-helpers.ts +23 -5
  204. package/src/renderer/settings-modal.ts +129 -39
  205. package/src/renderer/shell-surface.ts +6 -0
  206. package/src/renderer/terminal-bg-probe.ts +1 -1
  207. package/src/renderer/theme.ts +3 -3
  208. package/src/renderer/tool-call.ts +13 -7
  209. package/src/renderer/tool-result-summary.ts +1 -1
  210. package/src/renderer/turn-injection.ts +7 -6
  211. package/src/renderer/ui-factory.ts +38 -1
  212. package/src/runtime/bootstrap-command-context.ts +7 -2
  213. package/src/runtime/bootstrap-command-parts.ts +9 -5
  214. package/src/runtime/bootstrap-core.ts +41 -41
  215. package/src/runtime/bootstrap-hook-bridge.ts +1 -1
  216. package/src/runtime/bootstrap-shell.ts +13 -5
  217. package/src/runtime/bootstrap.ts +34 -32
  218. package/src/runtime/channel-composition.ts +46 -0
  219. package/src/runtime/code-index-services.ts +3 -4
  220. package/src/runtime/daemon-attach-notices.ts +120 -0
  221. package/src/runtime/durability-services.ts +90 -0
  222. package/src/runtime/embedded-service-factories.ts +40 -0
  223. package/src/runtime/feature-settings.ts +147 -0
  224. package/src/runtime/fleet-services.ts +41 -0
  225. package/src/runtime/idle-power-services.ts +85 -0
  226. package/src/runtime/index.ts +6 -21
  227. package/src/runtime/interaction-seams.ts +109 -0
  228. package/src/runtime/legacy-daemon-migration.ts +29 -19
  229. package/src/runtime/memory-fold.ts +1 -1
  230. package/src/runtime/notification-dispatch.ts +110 -0
  231. package/src/runtime/onboarding/apply.ts +3 -29
  232. package/src/runtime/onboarding/fast-path.ts +39 -6
  233. package/src/runtime/onboarding/provider-key-capture.ts +126 -0
  234. package/src/runtime/onboarding/snapshot.ts +0 -1
  235. package/src/runtime/onboarding/types.ts +9 -3
  236. package/src/runtime/power-keepawake-remote.ts +75 -0
  237. package/src/runtime/process-lifecycle.ts +3 -1
  238. package/src/runtime/provider-fallback.ts +55 -0
  239. package/src/runtime/provider-optimizer-wiring.ts +55 -0
  240. package/src/runtime/release-artifacts.ts +19 -103
  241. package/src/runtime/resume-notice.ts +1 -1
  242. package/src/runtime/services.ts +113 -113
  243. package/src/runtime/session-continuity-hints.ts +38 -0
  244. package/src/runtime/surface-feature-flags.ts +40 -9
  245. package/src/runtime/terminal-output-guard.ts +2 -2
  246. package/src/runtime/trust/workspace-registration.ts +10 -2
  247. package/src/runtime/trust/workspace-trust.ts +58 -31
  248. package/src/runtime/ui-services.ts +6 -1
  249. package/src/runtime/update-check.ts +15 -69
  250. package/src/runtime/workstream-services.ts +2 -2
  251. package/src/shell/blocking-input.ts +108 -132
  252. package/src/shell/recovery-input-helpers.ts +53 -166
  253. package/src/shell/ui-openers.ts +38 -6
  254. package/src/utils/format-duration.ts +1 -1
  255. package/src/verification/verification-ledger.ts +21 -4
  256. package/src/version.ts +1 -1
  257. package/src/input/commands/flags-runtime.ts +0 -328
@@ -1,40 +1,45 @@
1
1
  import type { PanelManager } from '../panel-manager.ts';
2
2
  import { FleetPanel } from '../fleet-panel.ts';
3
3
  import { createFleetReadModel } from '../fleet-read-model.ts';
4
+ import { FleetActs, type FleetDiffSurface } from '../fleet-acts.ts';
5
+ import { createFleetGateway } from '../fleet-gateway.ts';
6
+ import { FleetSpawn, createAcpSpawnGateway } from '../fleet-spawn.ts';
7
+ import { DiffPanel } from '../diff-panel.ts';
4
8
  import { LocalAuthPanel } from '../local-auth-panel.ts';
9
+ import { NotificationsPanel } from '../notifications-panel.ts';
5
10
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
6
11
  import { requireUiServices } from './shared.ts';
7
12
 
8
- // WO-152: the former single 'monitoring' category (33 panels pre-merge) is
13
+ // the former single 'monitoring' category (33 panels pre-merge) is
9
14
  // split into five operator domains, applied per-registration below. Kept in
10
15
  // this file's original registration order (rather than physically regrouped
11
16
  // by category) because several registrations below close over shared local
12
17
  // state — `ui` — defined once near the top of this function.
13
18
  //
14
- // W6.1 (the purge): cockpit, approval, automation, routes, control-plane,
19
+ // (the purge): cockpit, approval, automation, routes, control-plane,
15
20
  // worktrees, tasks, orchestration, ops, ops-control, and communication were
16
21
  // RETIRE-INTO-FLEET (their live views are subsumed by the Fleet panel below
17
22
  // — each id now redirects there via registerAlias); debug and eval were
18
23
  // DELETE-disposition (no surviving human surface). See
19
- // .goodvibes/audit/2026-07-04-wave6-briefs.json (W6.1) for the full
24
+ // .goodvibes/audit/2026-07-04-wave6-briefs.json for the full
20
25
  // disposition map. The rosterReadModel/agent-lifecycle wiring that used to
21
26
  // feed CockpitPanel exclusively was removed along with it — Fleet reads the
22
27
  // process registry directly via fleetReadModel below, not via the roster
23
28
  // read-model.
24
29
  //
25
- // W6.1 MIGRATE-TO-MODAL: the Providers & Connectivity group (services,
30
+ // MIGRATE-TO-MODAL: the Providers & Connectivity group (services,
26
31
  // subscription, remote, provider-health) and Security group (settings-sync,
27
32
  // sandbox) migrated to config-modal surfaces registered in builtin-modals.ts
28
- // (WO-A); the Ecosystem & Governance group (plugins, skills, hooks, security,
33
+ //; the Ecosystem & Governance group (plugins, skills, hooks, security,
29
34
  // marketplace, policy, knowledge, memory, docs, qr-code, work-plan,
30
- // project-planning) migrated to config-modal surfaces (WO-P). All surfaces AND
35
+ // project-planning) migrated to config-modal surfaces. All surfaces AND
31
36
  // their panel-id redirects are registered centrally in registerBuiltinModals
32
37
  // (builtin-modals.ts) now — the interim ecosystem redirect bridge was deleted
33
38
  // with the group-B port. local-auth is a DELIBERATE EXCEPTION — see below.
34
39
  export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
35
40
  const ui = requireUiServices(deps);
36
41
 
37
- // W2.2: Fleet — the live unified process tree, read from the single
42
+ // Fleet — the live unified process tree, read from the single
38
43
  // process registry constructed once in runtime/services.ts (shared with
39
44
  // every other consumer rather than duplicated here; the registry owns its
40
45
  // own coalesced tick, so no manual lifecycle-event wiring is needed).
@@ -42,10 +47,59 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
42
47
  // to the honest COMMUNICATION_CONSUMED steer-ack signal (fleet-read-model.ts).
43
48
  const fleetReadModel = createFleetReadModel(ui.runtime.processRegistry, ui.runtime.runtimeBus);
44
49
 
50
+ // The Fleet panel's waiting-on-human acts (pick / conflict / discard) drive
51
+ // gateway verbs over the same operator invoke path the command layer uses, and
52
+ // reuse the shared DiffPanel (candidate diffs + the pick confirm overlay) and
53
+ // the CI fix-session jump affordance. Built here so the panel stays thin.
54
+ const fleetNotify = deps.fleetActsNotify ?? (() => {});
55
+ const armFixSessionAttach = deps.armFixSessionAttach ?? (() => {});
56
+ const diffSurface: FleetDiffSurface = {
57
+ show: (_title, unifiedDiff) => {
58
+ let panel = manager.getAllOpen().find((p) => p.id === 'diff');
59
+ if (!panel) { try { panel = manager.open('diff'); } catch { return; } }
60
+ manager.activateById('diff');
61
+ if (!manager.isVisible()) manager.show();
62
+ manager.focusPanels();
63
+ (panel as DiffPanel).loadRawDiff(unifiedDiff);
64
+ },
65
+ armConfirm: (opts) => {
66
+ let panel = manager.getAllOpen().find((p) => p.id === 'diff');
67
+ if (!panel) { try { panel = manager.open('diff'); } catch { return; } }
68
+ manager.activateById('diff');
69
+ if (!manager.isVisible()) manager.show();
70
+ manager.focusPanels();
71
+ (panel as DiffPanel).confirmOverlay.arm(opts);
72
+ },
73
+ close: () => { manager.close('diff'); },
74
+ };
75
+ const fleetActs = new FleetActs({
76
+ resolveGateway: () => createFleetGateway({
77
+ configManager: deps.configManager,
78
+ homeDirectory: ui.environment.shellPaths.homeDirectory,
79
+ armFixSessionAttach,
80
+ }),
81
+ diffSurface,
82
+ notify: fleetNotify,
83
+ markDirty: deps.requestRender ?? (() => {}),
84
+ findNode: (nodeId: string) => fleetReadModel.getSnapshot().rows.find((r) => r.node.id === nodeId)?.node ?? null,
85
+ });
86
+
87
+ // The ACP spawn affordance ('n'): host a discovered third-party agent as an
88
+ // acp-agent row over the same operator invoke path the acts use.
89
+ const fleetSpawn = new FleetSpawn({
90
+ resolveGateway: () => createAcpSpawnGateway({
91
+ configManager: deps.configManager,
92
+ homeDirectory: ui.environment.shellPaths.homeDirectory,
93
+ }),
94
+ currentDirectory: () => ui.environment.shellPaths.workingDirectory,
95
+ notify: fleetNotify,
96
+ markDirty: deps.requestRender ?? (() => {}),
97
+ });
98
+
45
99
  manager.registerType({
46
100
  id: 'fleet',
47
101
  name: 'Fleet',
48
- // W2.2: '⊟' verified free against the full icon registry at wiring time.
102
+ // '⊟' verified free against the full icon registry at wiring time.
49
103
  icon: '⊟',
50
104
  category: 'runtime-ops',
51
105
  description: 'Live unified process tree: agents, WRFC chains, workflows, watchers, and background processes, with interrupt/kill/steer controls',
@@ -62,7 +116,7 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
62
116
  resolveSessionLogPath: (agentId: string) => ui.environment.shellPaths.resolveProjectPath('tui', 'sessions', `${agentId}.jsonl`),
63
117
  // Queue a message for a live in-process agent/wrfc-subtask member.
64
118
  steer: (id: string, text: string) => fleetReadModel.steer(id, text),
65
- }, deps.configManager),
119
+ }, deps.configManager, fleetActs, fleetSpawn),
66
120
  });
67
121
 
68
122
  // Compat: '/panel open <id>' (and any saved layout/muscle memory) for
@@ -82,11 +136,29 @@ export function registerOperationsPanels(manager: PanelManager, deps: ResolvedBu
82
136
  manager.registerAlias('communication', 'fleet');
83
137
  manager.registerAlias('incident', 'fleet');
84
138
  // Re-pointed: forensics used to resolve to the (now-retired) incident
85
- // workspace (WO-114); both ids now land on fleet directly — alias
139
+ // workspace; both ids now land on fleet directly — alias
86
140
  // resolution is a single hop, so this cannot chain through 'incident'.
87
141
  manager.registerAlias('forensics', 'fleet');
88
142
 
89
- // local-auth is a DELIBERATE EXCEPTION to the W6.1 purge: it stays a
143
+ // Notifications — the visible home for the panel_only notification
144
+ // target: anything a NotificationRouter (SDK) routes there (including
145
+ // burst/batch-collapsed groups, shown with their real running count)
146
+ // renders here instead of having nowhere to go. See notifications-feed.ts
147
+ // for why this exists. Not preloaded (only 'tokens' preloads, per the
148
+ // panel-consolidation cleanup below) — the shared feed singleton
149
+ // accumulates independently of whether this view has been opened yet, so
150
+ // nothing is lost by instantiating it lazily on first open like every
151
+ // other panel here.
152
+ manager.registerType({
153
+ id: 'notifications',
154
+ name: 'Notifications',
155
+ icon: 'N',
156
+ category: 'runtime-ops',
157
+ description: 'Notifications routed to the panel-only target (quiet/balanced-mode operational chatter, burst- and batch-collapsed groups) with their real collapsed counts',
158
+ factory: () => new NotificationsPanel(),
159
+ });
160
+
161
+ // local-auth is a DELIBERATE EXCEPTION to the purge: it stays a
90
162
  // registered panel because it is the host for the masked password-entry
91
163
  // sub-mode (LocalAuthPanel.openMaskedEntry, driven by
92
164
  // ctx.openLocalAuthMaskedEntry — the only path that keeps a plaintext
@@ -3,7 +3,7 @@ import { TokenBudgetPanel } from '../token-budget-panel.ts';
3
3
  import type { ResolvedBuiltinPanelDeps } from './shared.ts';
4
4
  import { requireUiServices } from './shared.ts';
5
5
 
6
- // W6.1 (the purge): panel-list and system-messages were registered here
6
+ // (the purge): panel-list and system-messages were registered here
7
7
  // before the purge — both DELETE-disposition. panel-list was a picker over a
8
8
  // handful of panels (dead weight now that the registry is much smaller —
9
9
  // the picker itself is replaced by a live-registry selection modal on
@@ -14,7 +14,7 @@ import { requireUiServices } from './shared.ts';
14
14
  // conversation.addTypedSystemMessage for every kind/target combination — see
15
15
  // bootstrap-shell.ts and core/system-message-router.ts.
16
16
  //
17
- // W6.1 (the purge) — group B (WO-P): 'qr-code', 'sessions', and 'docs' also
17
+ // (the purge) — group B: 'qr-code', 'sessions', and 'docs' also
18
18
  // migrated. 'qr-code' → the 'pairing-modal' surface; 'docs' → the
19
19
  // 'keybindings-modal' surface (merged with the shortcuts-overlay content);
20
20
  // 'sessions' folds into the existing session-picker modal ('sessions' redirects
@@ -25,7 +25,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
25
25
  manager.registerType({
26
26
  id: 'tokens',
27
27
  name: 'Tokens',
28
- // WO-152: registry previously said 'K' while the live panel's own
28
+ // registry previously said 'K' while the live panel's own
29
29
  // super() call used 'T' — a pre-existing registry/instance mismatch as
30
30
  // well as a collision ('K' with knowledge/skills, 'T' with thinking).
31
31
  // Unified to a single unique glyph in both places.
@@ -35,7 +35,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
35
35
  // Preloaded (absorbed from the retired ContextVisualizerPanel) so turn
36
36
  // history and pressure accumulate in the background even before the user
37
37
  // opens the tab. The only builtin panel that still preloads post-purge
38
- // (W6.1) — see registerBuiltinPanels callers for the others' preload
38
+ // — see registerBuiltinPanels callers for the others' preload
39
39
  // removal.
40
40
  preload: true,
41
41
  retainOnClose: true,
@@ -58,7 +58,7 @@ export function registerSessionPanels(manager: PanelManager, deps: ResolvedBuilt
58
58
  },
59
59
  });
60
60
 
61
- // WO-113 compat: the retired 'context' panel id still resolves — redirected
61
+ // compat: the retired 'context' panel id still resolves — redirected
62
62
  // to the merged tokens console ('/panel open context', saved layouts).
63
63
  manager.registerAlias('context', 'tokens');
64
64
  }
@@ -55,7 +55,7 @@ export interface BuiltinPanelDeps {
55
55
  subscriptionManager?: SubscriptionManager;
56
56
  /** Shared service registry for services-backed panels. */
57
57
  serviceRegistry?: ServiceRegistry;
58
- /** Context window size in tokens. Unused since WO-113 folded ContextVisualizerPanel into TokenBudgetPanel (which reads getCtxWindow instead); kept for source compatibility. */
58
+ /** Context window size in tokens. Unused since folded ContextVisualizerPanel into TokenBudgetPanel (which reads getCtxWindow instead); kept for source compatibility. */
59
59
  contextWindow?: number;
60
60
  /** Main Orchestrator instance for TokenBudgetPanel.wire(). */
61
61
  orchestrator?: Orchestrator;
@@ -72,7 +72,7 @@ export interface BuiltinPanelDeps {
72
72
  /** ForensicsRegistry for the Forensics panel. */
73
73
  forensicsRegistry?: import('@/runtime/index.ts').ForensicsRegistry;
74
74
  /**
75
- * EvalRegistry for the `/eval` command surface. W6.1: 'eval' the panel was
75
+ * EvalRegistry for the `/eval` command surface.: 'eval' the panel was
76
76
  * deleted (DELETE-disposition), but this field is left in place — no
77
77
  * builtin panel factory reads it anymore, and it was never wired at
78
78
  * bootstrap in production either way (the eval CLI command reads its own
@@ -123,7 +123,7 @@ export interface BuiltinPanelDeps {
123
123
  workPlanStore?: import('../../work-plans/work-plan-store.ts').WorkPlanStore;
124
124
  /** Explicit UI-facing runtime services for agent/process/WRFC/remote panels and modals. */
125
125
  uiServices?: UiRuntimeServices;
126
- /** Shared plugin manager for plugin and security panels (widened past the read-only observer surface — WO-134 — so PluginsPanel can drive enable/disable/verify/lift-quarantine). */
126
+ /** Shared plugin manager for plugin and security panels (widened past the read-only observer surface — — so PluginsPanel can drive enable/disable/verify/lift-quarantine). */
127
127
  pluginManager?: PluginManagerControls;
128
128
  /** Shared hook dispatcher for the hooks control-room panel. */
129
129
  hookDispatcher?: Pick<HookDispatcher, 'listHooks' | 'getChains'>;
@@ -150,6 +150,18 @@ export interface BuiltinPanelDeps {
150
150
  * cross-panel navigation instead of printing a "/panel open …" signpost.
151
151
  */
152
152
  openPanel?: (panelId: string) => void;
153
+ /**
154
+ * Surface a Fleet act result/receipt/error to the operator (late-bound to the
155
+ * command context's print, which the Fleet pick/conflict/discard acts use for
156
+ * their receipts — the same conversation sink the command flow prints to).
157
+ */
158
+ fleetActsNotify?: (message: string) => void;
159
+ /**
160
+ * Hand a spawned session id to the shared one-key jump/attach affordance (the
161
+ * CI fix-session machinery). Late-bound: main.ts patches it onto the command
162
+ * context after bootstrap; the Fleet conflict-resolve act reuses it verbatim.
163
+ */
164
+ armFixSessionAttach?: (sessionId: string) => void;
153
165
  }
154
166
 
155
167
  export type ResolvedBuiltinPanelDeps = Omit<
@@ -287,7 +299,7 @@ export function requireKnowledgeApi(deps: BuiltinPanelDeps): KnowledgeApi {
287
299
  }
288
300
 
289
301
  // ---------------------------------------------------------------------------
290
- // WO-152: always-register conditional panels with a "dependency not
302
+ // always-register conditional panels with a "dependency not
291
303
  // configured" empty state instead of skipping registration entirely.
292
304
  // ---------------------------------------------------------------------------
293
305
 
@@ -1,13 +1,13 @@
1
- import { networkInterfaces } from 'node:os';
2
- import { readFileSync } from 'node:fs';
3
1
  import type { PanelManager } from './panel-manager.ts';
4
2
  import { requireUiServices, type ResolvedBuiltinPanelDeps } from './builtin/shared.ts';
5
3
  import type { ConfigModalSurface, ConfigModalView } from '../input/config-modal-types.ts';
6
4
  import { createProviderRuntimeInspectionQuery } from '../runtime/ui-service-queries.ts';
7
5
  import { createRuntimeProviderApi } from '@/runtime/index.ts';
8
6
  import { copyToClipboard } from '../utils/clipboard.ts';
9
- import { getOrCreateCompanionToken, buildCompanionConnectionInfo } from '@pellux/goodvibes-sdk/platform/pairing';
10
- // ── Group A: Providers & Connectivity + Security subset (WO-A) ───────────────
7
+ import { ensurePublicBaseUrl } from '../core/pairing-origin.ts';
8
+ import { availablePairingOffers, mintPairingHandoff, defaultPairingTokenName } from '../core/pairing-handoff.ts';
9
+ import { probePairingTailscale, runPairingTailscaleServe } from '../core/pairing-tailscale-gateway.ts';
10
+ // ── Providers & Connectivity + Security subset ────────────────────────────────
11
11
  import { createServicesModalSurface } from './modals/services-modal.ts';
12
12
  import { createSubscriptionModalSurface } from './modals/subscription-modal.ts';
13
13
  import { createRemoteModalSurface } from './modals/remote-modal.ts';
@@ -15,7 +15,7 @@ import { createSettingsSyncModalSurface } from './modals/settings-sync-modal.ts'
15
15
  import { createProviderHealthModalSurface } from './modals/provider-health-modal.ts';
16
16
  import { createLocalAuthModalSurface } from './modals/local-auth-modal.ts';
17
17
  import { createSandboxModalSurface } from './modals/sandbox-modal.ts';
18
- // ── Group B: Ecosystem & Governance (WO-P, this work order) ──────────────────
18
+ // ── Ecosystem & Governance ─────────────────────────────────────────────────
19
19
  import { createMarketplaceModalSurface } from './modals/marketplace-modal.ts';
20
20
  import { createPluginsModalSurface } from './modals/plugins-modal.ts';
21
21
  import { createSkillsModalSurface } from './modals/skills-modal.ts';
@@ -24,28 +24,30 @@ import { createSecurityModalSurface } from './modals/security-modal.ts';
24
24
  import { createPolicyModalSurface } from './modals/policy-modal.ts';
25
25
  import { createKnowledgeModalSurface } from './modals/knowledge-modal.ts';
26
26
  import { createMemoryModalSurface, type MemoryModalDeps } from './modals/memory-modal.ts';
27
+ import { createMemoryConsolidationGateway } from './memory-consolidation-gateway.ts';
27
28
  import { createWorkPlanModalSurface } from './modals/work-plan-modal.ts';
28
29
  import { createKeybindingsModalSurface } from './modals/keybindings-modal.ts';
29
30
  import { createPairingModalSurface, type PairingModalConnectionInfo } from './modals/pairing-modal.ts';
31
+ import { createDevicesModalSurface } from './modals/devices-modal.ts';
30
32
  import { createPlanningModalSurface } from './modals/planning-modal.ts';
31
33
 
32
34
  /**
33
- * Register the config-modal surfaces + their panel-id redirects (W6.1, the
34
- * purge). Called once at startup from registerBuiltinPanels, AFTER the panels'
35
+ * Register the config-modal surfaces + their panel-id redirects, from a prior
36
+ * panel-consolidation cleanup. Called once at startup from registerBuiltinPanels, AFTER the panels'
35
37
  * deps are resolved (the surfaces close over the same read-models the retired
36
- * panels used). For each MIGRATE-TO-MODAL surface this does two things:
38
+ * panels used). For each surface migrated from a standalone panel this does two things:
37
39
  * 1. registerModalSurface — the data + actions the config-modal host renders.
38
40
  * 2. registerModalRedirect — so `/panel open <old-id>`, saved layouts, and any
39
41
  * alias still resolve to the modal.
40
42
  *
41
- * Group A (WO-A) is the Providers & Connectivity + Security subset. Group B
42
- * (WO-P) is the Ecosystem & Governance set — the 12 ported config-modal
43
+ * The Providers & Connectivity + Security subset is registered first, followed by the
44
+ * Ecosystem & Governance set — the 12 ported config-modal
43
45
  * surfaces plus the `sessions` fold into the existing session-picker modal.
44
46
  */
45
47
  export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuiltinPanelDeps): void {
46
48
  const ui = requireUiServices(deps);
47
49
 
48
- // ── Providers & Connectivity (WO-A) ─────────────────────────────────────────
50
+ // ── Providers & Connectivity ─────────────────────────────────────────────────
49
51
  manager.registerModalSurface(createServicesModalSurface(deps.serviceRegistry, deps.subscriptionManager));
50
52
  manager.registerModalRedirect('services', 'services-modal');
51
53
 
@@ -65,7 +67,7 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
65
67
  manager.registerModalRedirect('providers', 'providers-modal');
66
68
  manager.registerModalRedirect('accounts', 'providers-modal');
67
69
 
68
- // ── Security & Governance (WO-A subset) ─────────────────────────────────────
70
+ // ── Security & Governance ────────────────────────────────────────────────────
69
71
  manager.registerModalSurface(createSettingsSyncModalSurface(deps.configManager));
70
72
  manager.registerModalRedirect('settings-sync', 'settings-sync-modal');
71
73
 
@@ -77,7 +79,7 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
77
79
  manager.registerModalSurface(createSandboxModalSurface(deps.configManager, deps.sandboxSessionRegistry, deps.requestRender));
78
80
  manager.registerModalRedirect('sandbox', 'sandbox-modal');
79
81
 
80
- // ── Ecosystem & Governance (WO-P — group B) ─────────────────────────────────
82
+ // ── Ecosystem & Governance ───────────────────────────────────────────────────
81
83
  manager.registerModalSurface(createMarketplaceModalSurface({
82
84
  readModel: ui.readModels.marketplace,
83
85
  ecosystemPaths: {
@@ -131,6 +133,13 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
131
133
 
132
134
  manager.registerModalSurface(createMemoryModalSurface({
133
135
  memoryRegistry: deps.memoryRegistry as MemoryModalDeps['memoryRegistry'],
136
+ // Lazily resolved — a fresh factory call per Proposals-tab fetch, exactly
137
+ // like the Fleet gateway (fleet-gateway.ts) — so a daemon that comes up
138
+ // AFTER this session started is still reachable on the next refresh.
139
+ resolveConsolidationGateway: () => createMemoryConsolidationGateway({
140
+ configManager: deps.configManager,
141
+ homeDirectory: ui.environment.shellPaths.homeDirectory,
142
+ }),
134
143
  }));
135
144
  manager.registerModalRedirect('memory', 'memory-modal');
136
145
 
@@ -144,13 +153,24 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
144
153
  }));
145
154
  manager.registerModalRedirect('docs', 'keybindings-modal');
146
155
 
156
+ const tailscaleGatewayDeps = { configManager: deps.configManager, homeDirectory: ui.environment.shellPaths.homeDirectory };
147
157
  manager.registerModalSurface(createPairingModalSurface({
148
158
  getConnectionInfo: () => buildPairingConnectionInfo(deps),
149
159
  controlPlaneReadModel: ui.readModels.controlPlane,
150
160
  copyToClipboard,
161
+ probeTailscale: () => probePairingTailscale(tailscaleGatewayDeps),
162
+ runTailscaleServe: () => runPairingTailscaleServe(tailscaleGatewayDeps),
151
163
  }));
152
164
  manager.registerModalRedirect('qr-code', 'pairing-modal');
153
165
 
166
+ // Paired-device management (settings security domain): list/rename/revoke/
167
+ // migrate-shared over the same per-device token store the pairing QR mints into.
168
+ manager.registerModalSurface(createDevicesModalSurface({
169
+ pairingTokens: ui.platform.pairingTokens,
170
+ copyToClipboard,
171
+ }));
172
+ manager.registerModalRedirect('devices', 'devices-modal');
173
+
154
174
  manager.registerModalSurface(createPlanningModalSurface({
155
175
  service: deps.projectPlanningService,
156
176
  projectId: deps.projectPlanningProjectId,
@@ -171,15 +191,33 @@ export function registerBuiltinModals(manager: PanelManager, deps: ResolvedBuilt
171
191
  * Mirrors the retired QrPanel factory's construction.
172
192
  */
173
193
  function buildPairingConnectionInfo(deps: ResolvedBuiltinPanelDeps): PairingModalConnectionInfo | null {
174
- if (!deps.daemonHomeDir) return null;
175
194
  try {
176
- const daemonHomeDir = deps.daemonHomeDir;
177
- const tokenRecord = getOrCreateCompanionToken('tui', { daemonHomeDir });
178
- const daemonPort = deps.configManager.get('controlPlane.port');
179
- const daemonHost = String(process.env['GOODVIBES_DAEMON_HOST'] ?? getLocalNetworkIp());
180
- const daemonUrl = `http://${daemonHost}:${daemonPort}`;
181
- const bootstrapPassword = readBootstrapPassword(deps.localUserAuthManager.getBootstrapCredentialPath());
182
- return buildCompanionConnectionInfo({ daemonUrl, token: tokenRecord.token, password: bootstrapPassword, surface: 'tui' }) as PairingModalConnectionInfo;
195
+ const ui = requireUiServices(deps);
196
+ const configManager = deps.configManager;
197
+ // Freeze a stable web origin once (never clobbering a user-set value).
198
+ const webOrigin = ensurePublicBaseUrl(configManager);
199
+ const offers = availablePairingOffers({
200
+ relayEnabled: configManager.get('relay.enabled') === true,
201
+ // The TUI composition always wires a step-up service ⇒ the passkey offer is
202
+ // presentable; the web app declines it if the device has no authenticator.
203
+ stepUpAvailable: true,
204
+ });
205
+ // Mint a fresh per-device token and encode the canonical `#pair=` deep link —
206
+ // the same mint the pairing.handoff.create verb performs, no raw JSON blob.
207
+ const handoff = mintPairingHandoff({
208
+ pairingTokens: ui.platform.pairingTokens,
209
+ name: defaultPairingTokenName(),
210
+ offers,
211
+ webOrigin: webOrigin.origin,
212
+ });
213
+ return {
214
+ url: webOrigin.origin,
215
+ token: handoff.token.token,
216
+ tokenName: handoff.token.name,
217
+ deepLink: handoff.deepLink ?? handoff.fragment,
218
+ offers: handoff.offers,
219
+ posture: handoff.posture,
220
+ };
183
221
  } catch {
184
222
  return null;
185
223
  }
@@ -195,24 +233,3 @@ function unwiredSurface(name: string, title: string, reason: string): ConfigModa
195
233
  };
196
234
  }
197
235
 
198
- function getLocalNetworkIp(): string {
199
- const nets = networkInterfaces();
200
- for (const name of Object.keys(nets)) {
201
- for (const net of nets[name] ?? []) {
202
- if (net.family === 'IPv4' && !net.internal) return net.address;
203
- }
204
- }
205
- return 'localhost';
206
- }
207
-
208
- function readBootstrapPassword(credentialPath: string): string | undefined {
209
- try {
210
- const content = readFileSync(credentialPath, 'utf-8');
211
- for (const line of content.split('\n')) {
212
- if (line.startsWith('password=')) return line.slice('password='.length).trim();
213
- }
214
- } catch {
215
- // credential file may not exist yet
216
- }
217
- return undefined;
218
- }
@@ -19,7 +19,7 @@ export function registerBuiltinPanels(manager: PanelManager, deps: BuiltinPanelD
19
19
  registerAgentPanels(manager, resolved);
20
20
  registerSessionPanels(manager, resolved);
21
21
  registerKnowledgePanels(manager, resolved);
22
- // W6.1 (the purge): register MIGRATE-TO-MODAL surfaces + their panel-id
22
+ // (the purge): register MIGRATE-TO-MODAL surfaces + their panel-id
23
23
  // redirects. Must run after the panel registrations so a redirected id wins
24
24
  // over any lingering panel registration in open().
25
25
  registerBuiltinModals(manager, resolved);