@pellux/goodvibes-agent 0.1.116 → 1.0.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 (285) hide show
  1. package/CHANGELOG.md +48 -661
  2. package/README.md +64 -57
  3. package/bin/goodvibes-agent.ts +16 -2
  4. package/dist/package/main.js +199180 -192185
  5. package/docs/README.md +15 -8
  6. package/docs/channels-remote-and-api.md +50 -0
  7. package/docs/connected-host.md +59 -0
  8. package/docs/getting-started.md +61 -50
  9. package/docs/knowledge-artifacts-and-multimodal.md +91 -0
  10. package/docs/project-planning.md +79 -0
  11. package/docs/providers-and-routing.md +46 -0
  12. package/docs/release-and-publishing.md +48 -11
  13. package/docs/tools-and-commands.md +123 -0
  14. package/docs/voice-and-live-tts.md +51 -0
  15. package/package.json +3 -6
  16. package/src/agent/behavior-discovery-summary.ts +1 -3
  17. package/src/agent/channel-delivery.ts +201 -0
  18. package/src/agent/media-generation.ts +159 -0
  19. package/src/agent/memory-prompt.ts +0 -1
  20. package/src/agent/note-registry.ts +329 -0
  21. package/src/agent/operator-actions.ts +343 -0
  22. package/src/agent/persona-discovery.ts +1 -3
  23. package/src/agent/persona-registry.ts +19 -16
  24. package/src/agent/record-labels.ts +107 -0
  25. package/src/agent/reminder-schedule-format.ts +33 -24
  26. package/src/agent/reminder-schedule.ts +27 -26
  27. package/src/agent/routine-registry.ts +54 -14
  28. package/src/agent/routine-schedule-args.ts +2 -1
  29. package/src/agent/routine-schedule-format.ts +77 -53
  30. package/src/agent/routine-schedule-promotion.ts +35 -33
  31. package/src/agent/routine-schedule-receipts.ts +29 -27
  32. package/src/agent/runtime-profile-starters.ts +5 -5
  33. package/src/agent/runtime-profile.ts +91 -12
  34. package/src/agent/skill-registry.ts +210 -32
  35. package/src/cli/agent-knowledge-args.ts +5 -1
  36. package/src/cli/agent-knowledge-command.ts +40 -34
  37. package/src/cli/agent-knowledge-format.ts +80 -67
  38. package/src/cli/agent-knowledge-methods.ts +1 -1
  39. package/src/cli/agent-knowledge-runtime.ts +32 -26
  40. package/src/cli/bundle-command.ts +14 -9
  41. package/src/cli/config-overrides.ts +37 -36
  42. package/src/cli/entrypoint.ts +16 -7
  43. package/src/cli/external-runtime.ts +10 -4
  44. package/src/cli/help.ts +54 -29
  45. package/src/cli/local-library-command.ts +203 -83
  46. package/src/cli/management-commands.ts +105 -68
  47. package/src/cli/management.ts +55 -74
  48. package/src/cli/memory-command.ts +66 -32
  49. package/src/cli/parser.ts +37 -3
  50. package/src/cli/profiles-command.ts +166 -31
  51. package/src/cli/provider-auth-routes.ts +2 -1
  52. package/src/cli/routines-command.ts +176 -40
  53. package/src/cli/service-posture.ts +16 -16
  54. package/src/cli/status.ts +56 -135
  55. package/src/core/conversation-message-snapshot.ts +131 -0
  56. package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
  57. package/src/input/agent-workspace-access-command-editors.ts +170 -0
  58. package/src/input/agent-workspace-activation.ts +35 -8
  59. package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
  60. package/src/input/agent-workspace-basic-command-editors.ts +502 -9
  61. package/src/input/agent-workspace-categories.ts +423 -51
  62. package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
  63. package/src/input/agent-workspace-channel-command-editors.ts +65 -0
  64. package/src/input/agent-workspace-channels.ts +35 -2
  65. package/src/input/agent-workspace-command-editor.ts +41 -3
  66. package/src/input/agent-workspace-config-reader.ts +16 -0
  67. package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
  68. package/src/input/agent-workspace-editors.ts +166 -1
  69. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
  70. package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
  71. package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
  72. package/src/input/agent-workspace-learned-behavior.ts +67 -0
  73. package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
  74. package/src/input/agent-workspace-library-command-editors.ts +35 -0
  75. package/src/input/agent-workspace-local-operations.ts +218 -0
  76. package/src/input/agent-workspace-local-selection.ts +75 -0
  77. package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
  78. package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
  79. package/src/input/agent-workspace-media-command-editors.ts +27 -0
  80. package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
  81. package/src/input/agent-workspace-memory-command-editors.ts +180 -0
  82. package/src/input/agent-workspace-memory-editor.ts +2 -2
  83. package/src/input/agent-workspace-navigation.ts +81 -0
  84. package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
  85. package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
  86. package/src/input/agent-workspace-operations-command-editors.ts +196 -0
  87. package/src/input/agent-workspace-panel-route.ts +43 -0
  88. package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
  89. package/src/input/agent-workspace-provider-command-editors.ts +93 -0
  90. package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
  91. package/src/input/agent-workspace-requirements.ts +11 -0
  92. package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
  93. package/src/input/agent-workspace-search.ts +169 -0
  94. package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
  95. package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
  96. package/src/input/agent-workspace-session-command-editors.ts +249 -0
  97. package/src/input/agent-workspace-setup.ts +37 -16
  98. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
  99. package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
  100. package/src/input/agent-workspace-snapshot.ts +162 -21
  101. package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
  102. package/src/input/agent-workspace-task-command-editors.ts +47 -0
  103. package/src/input/agent-workspace-token.ts +18 -2
  104. package/src/input/agent-workspace-types.ts +212 -4
  105. package/src/input/agent-workspace-voice-media.ts +4 -7
  106. package/src/input/agent-workspace-web-research-editor.ts +104 -0
  107. package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
  108. package/src/input/agent-workspace.ts +178 -240
  109. package/src/input/command-registry.ts +5 -2
  110. package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
  111. package/src/input/commands/agent-skills-runtime.ts +149 -72
  112. package/src/input/commands/agent-workspace-runtime.ts +23 -6
  113. package/src/input/commands/brief-runtime.ts +55 -25
  114. package/src/input/commands/channels-runtime.ts +147 -33
  115. package/src/input/commands/compat-runtime.ts +32 -0
  116. package/src/input/commands/delegation-runtime.ts +29 -23
  117. package/src/input/commands/experience-runtime.ts +6 -4
  118. package/src/input/commands/guidance-runtime.ts +4 -4
  119. package/src/input/commands/health-runtime.ts +149 -126
  120. package/src/input/commands/knowledge.ts +82 -60
  121. package/src/input/commands/local-provider-runtime.ts +43 -21
  122. package/src/input/commands/local-runtime.ts +138 -16
  123. package/src/input/commands/local-setup-review.ts +10 -20
  124. package/src/input/commands/mcp-runtime.ts +63 -46
  125. package/src/input/commands/notify-runtime.ts +38 -9
  126. package/src/input/commands/operator-actions-runtime.ts +138 -0
  127. package/src/input/commands/operator-runtime.ts +6 -76
  128. package/src/input/commands/personas-runtime.ts +46 -31
  129. package/src/input/commands/planning-runtime.ts +1 -1
  130. package/src/input/commands/platform-access-runtime.ts +35 -98
  131. package/src/input/commands/product-runtime.ts +2 -2
  132. package/src/input/commands/provider-accounts-runtime.ts +60 -39
  133. package/src/input/commands/qrcode-runtime.ts +50 -9
  134. package/src/input/commands/recall-bundle.ts +11 -11
  135. package/src/input/commands/recall-capture.ts +13 -11
  136. package/src/input/commands/recall-query.ts +29 -21
  137. package/src/input/commands/recall-review.ts +2 -1
  138. package/src/input/commands/routines-runtime.ts +99 -45
  139. package/src/input/commands/runtime-services.ts +1 -14
  140. package/src/input/commands/schedule-runtime.ts +33 -20
  141. package/src/input/commands/security-runtime.ts +6 -11
  142. package/src/input/commands/session-content.ts +80 -78
  143. package/src/input/commands/session-workflow.ts +134 -104
  144. package/src/input/commands/session.ts +3 -174
  145. package/src/input/commands/shell-core.ts +38 -17
  146. package/src/input/commands/subscription-runtime.ts +54 -185
  147. package/src/input/commands/support-bundle-runtime.ts +53 -0
  148. package/src/input/commands/tasks-runtime.ts +21 -21
  149. package/src/input/commands/work-plan-runtime.ts +33 -8
  150. package/src/input/commands.ts +6 -2
  151. package/src/input/feed-context-factory.ts +2 -2
  152. package/src/input/file-picker.ts +3 -2
  153. package/src/input/handler-command-route.ts +4 -7
  154. package/src/input/handler-content-actions.ts +89 -26
  155. package/src/input/handler-feed-routes.ts +19 -12
  156. package/src/input/handler-feed.ts +6 -5
  157. package/src/input/handler-interactions.ts +9 -36
  158. package/src/input/handler-modal-stack.ts +3 -3
  159. package/src/input/handler-onboarding.ts +52 -91
  160. package/src/input/handler-shortcuts.ts +16 -7
  161. package/src/input/handler.ts +50 -23
  162. package/src/input/input-history.ts +5 -6
  163. package/src/input/keybindings.ts +27 -16
  164. package/src/input/mcp-workspace.ts +90 -26
  165. package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
  166. package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
  167. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
  168. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  169. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
  170. package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
  171. package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
  172. package/src/input/onboarding/onboarding-wizard.ts +87 -2
  173. package/src/input/profile-picker-modal.ts +31 -12
  174. package/src/input/session-picker-modal.ts +21 -4
  175. package/src/input/settings-modal-agent-policy.ts +6 -6
  176. package/src/input/settings-modal-behavior.ts +0 -3
  177. package/src/input/settings-modal-subscriptions.ts +3 -3
  178. package/src/input/settings-modal-types.ts +2 -13
  179. package/src/input/settings-modal.ts +20 -66
  180. package/src/input/submission-intent.ts +0 -1
  181. package/src/input/submission-router.ts +3 -3
  182. package/src/main.ts +18 -10
  183. package/src/panels/approval-panel.ts +8 -8
  184. package/src/panels/automation-control-panel.ts +4 -4
  185. package/src/panels/base-panel.ts +1 -1
  186. package/src/panels/builtin/agent.ts +1 -1
  187. package/src/panels/builtin/operations.ts +3 -12
  188. package/src/panels/builtin/session.ts +32 -24
  189. package/src/panels/builtin/shared.ts +7 -7
  190. package/src/panels/cost-tracker-panel.ts +1 -1
  191. package/src/panels/docs-panel.ts +5 -3
  192. package/src/panels/index.ts +0 -1
  193. package/src/panels/knowledge-panel.ts +6 -5
  194. package/src/panels/memory-panel.ts +7 -6
  195. package/src/panels/panel-list-panel.ts +36 -80
  196. package/src/panels/project-planning-panel.ts +19 -12
  197. package/src/panels/provider-account-snapshot.ts +51 -25
  198. package/src/panels/provider-accounts-panel.ts +33 -18
  199. package/src/panels/provider-health-domains.ts +48 -7
  200. package/src/panels/provider-health-panel.ts +5 -4
  201. package/src/panels/qr-panel.ts +44 -20
  202. package/src/panels/schedule-panel.ts +9 -17
  203. package/src/panels/security-panel.ts +8 -8
  204. package/src/panels/session-browser-panel.ts +10 -10
  205. package/src/panels/subscription-panel.ts +6 -6
  206. package/src/panels/system-messages-panel.ts +3 -3
  207. package/src/panels/tasks-panel.ts +21 -14
  208. package/src/panels/tool-inspector-panel.ts +19 -12
  209. package/src/panels/work-plan-panel.ts +5 -5
  210. package/src/planning/project-planning-coordinator.ts +3 -3
  211. package/src/provider-auth-route-display.ts +9 -0
  212. package/src/renderer/agent-workspace-style.ts +34 -0
  213. package/src/renderer/agent-workspace.ts +254 -57
  214. package/src/renderer/autocomplete-overlay.ts +25 -6
  215. package/src/renderer/block-actions.ts +1 -3
  216. package/src/renderer/bookmark-modal.ts +19 -4
  217. package/src/renderer/buffer.ts +4 -2
  218. package/src/renderer/context-inspector.ts +50 -13
  219. package/src/renderer/diff.ts +1 -1
  220. package/src/renderer/file-picker-overlay.ts +19 -6
  221. package/src/renderer/help-overlay.ts +112 -34
  222. package/src/renderer/history-search-overlay.ts +19 -4
  223. package/src/renderer/live-tail-modal.ts +27 -5
  224. package/src/renderer/mcp-workspace.ts +176 -43
  225. package/src/renderer/model-picker-overlay.ts +58 -3
  226. package/src/renderer/model-workspace.ts +104 -22
  227. package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
  228. package/src/renderer/process-modal.ts +27 -6
  229. package/src/renderer/profile-picker-modal.ts +21 -5
  230. package/src/renderer/search-overlay.ts +25 -5
  231. package/src/renderer/selection-modal-overlay.ts +46 -14
  232. package/src/renderer/session-picker-modal.ts +18 -1
  233. package/src/renderer/settings-modal-helpers.ts +2 -40
  234. package/src/renderer/settings-modal.ts +88 -55
  235. package/src/renderer/system-message.ts +1 -1
  236. package/src/renderer/tool-call.ts +20 -11
  237. package/src/runtime/agent-runtime-events.ts +129 -0
  238. package/src/runtime/bootstrap-command-context.ts +7 -1
  239. package/src/runtime/bootstrap-command-parts.ts +11 -8
  240. package/src/runtime/bootstrap-core.ts +23 -65
  241. package/src/runtime/bootstrap-hook-bridge.ts +7 -18
  242. package/src/runtime/bootstrap-shell.ts +46 -8
  243. package/src/runtime/bootstrap.ts +36 -46
  244. package/src/runtime/connected-host-auth.ts +47 -0
  245. package/src/runtime/diagnostics/panels/index.ts +2 -2
  246. package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
  247. package/src/runtime/diagnostics/panels/policy.ts +7 -7
  248. package/src/runtime/index.ts +2 -5
  249. package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
  250. package/src/runtime/onboarding/apply.ts +288 -74
  251. package/src/runtime/onboarding/derivation.ts +10 -13
  252. package/src/runtime/onboarding/snapshot.ts +2 -17
  253. package/src/runtime/onboarding/types.ts +34 -20
  254. package/src/runtime/onboarding/verify.ts +105 -4
  255. package/src/runtime/operator-token-cleanup.ts +3 -3
  256. package/src/runtime/services.ts +95 -11
  257. package/src/runtime/store/selectors/index.ts +3 -3
  258. package/src/runtime/store/state.ts +1 -4
  259. package/src/runtime/surface-feature-flags.ts +41 -6
  260. package/src/runtime/ui-read-models.ts +3 -4
  261. package/src/runtime/ui-services.ts +6 -6
  262. package/src/shell/blocking-input.ts +2 -1
  263. package/src/shell/service-settings-sync.ts +7 -7
  264. package/src/shell/ui-openers.ts +17 -38
  265. package/src/tools/agent-analysis-registry-policy.ts +0 -1
  266. package/src/tools/agent-channel-send-tool.ts +133 -0
  267. package/src/tools/agent-context-policy.ts +1 -1
  268. package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
  269. package/src/tools/agent-knowledge-tool.ts +170 -0
  270. package/src/tools/agent-local-registry-tool.ts +279 -73
  271. package/src/tools/agent-media-generate-tool.ts +133 -0
  272. package/src/tools/agent-notify-tool.ts +143 -0
  273. package/src/tools/agent-operator-action-tool.ts +137 -0
  274. package/src/tools/agent-operator-briefing-tool.ts +217 -0
  275. package/src/tools/agent-reminder-schedule-tool.ts +237 -0
  276. package/src/tools/agent-tool-policy-guard.ts +13 -15
  277. package/src/tools/agent-work-plan-tool.ts +256 -0
  278. package/src/version.ts +1 -1
  279. package/docs/connected-services.md +0 -51
  280. package/src/cli/package-verification.ts +0 -274
  281. package/src/input/commands/policy-dispatch.ts +0 -339
  282. package/src/input/commands/policy.ts +0 -17
  283. package/src/panels/panel-picker.ts +0 -105
  284. package/src/panels/policy-panel.ts +0 -308
  285. package/src/renderer/panel-picker-overlay.ts +0 -202
@@ -26,12 +26,21 @@ import {
26
26
  } from '@/runtime/index.ts';
27
27
  import { loadBootstrapSystemPrompt, syncConfiguredServices } from '@/runtime/index.ts';
28
28
  import { registerBootstrapHookBridge } from '@/runtime/index.ts';
29
- import { registerBootstrapRuntimeEvents } from '@/runtime/index.ts';
30
29
  import { createRuntimeServices, type RuntimeServices } from './services.ts';
31
30
  import { createUiRuntimeServices, type UiRuntimeServices } from './ui-services.ts';
32
31
  import { installAgentToolPolicyGuard } from '../tools/agent-tool-policy-guard.ts';
32
+ import { registerAgentChannelSendTool } from '../tools/agent-channel-send-tool.ts';
33
+ import { registerAgentKnowledgeIngestTool } from '../tools/agent-knowledge-ingest-tool.ts';
34
+ import { registerAgentKnowledgeTool } from '../tools/agent-knowledge-tool.ts';
33
35
  import { registerAgentLocalRegistryTool } from '../tools/agent-local-registry-tool.ts';
36
+ import { registerAgentMediaGenerateTool } from '../tools/agent-media-generate-tool.ts';
37
+ import { registerAgentNotifyTool } from '../tools/agent-notify-tool.ts';
38
+ import { registerAgentOperatorActionTool } from '../tools/agent-operator-action-tool.ts';
39
+ import { registerAgentOperatorBriefingTool } from '../tools/agent-operator-briefing-tool.ts';
40
+ import { registerAgentReminderScheduleTool } from '../tools/agent-reminder-schedule-tool.ts';
41
+ import { registerAgentWorkPlanTool } from '../tools/agent-work-plan-tool.ts';
34
42
  import { GOODVIBES_AGENT_SURFACE_ROOT } from '../config/surface.ts';
43
+ import { registerAgentRuntimeEvents } from './agent-runtime-events.ts';
35
44
 
36
45
  export interface BootstrapCoreState {
37
46
  readonly userSessionId: string;
@@ -139,7 +148,7 @@ export async function initializeBootstrapCore(
139
148
  metadata: {
140
149
  product: 'goodvibes-agent',
141
150
  surfaceRoot: GOODVIBES_AGENT_SURFACE_ROOT,
142
- clientKindNote: 'SDK has no dedicated agent client kind yet; using service for the Agent operator surface.',
151
+ clientKindNote: 'SDK compatibility client kind; GoodVibes Agent remains an interactive operator TUI.',
143
152
  },
144
153
  }, 'bootstrap.control-plane');
145
154
 
@@ -211,7 +220,6 @@ export async function initializeBootstrapCore(
211
220
  agentManager: services.agentManager,
212
221
  agentMessageBus: services.agentMessageBus,
213
222
  archetypeLoader: services.archetypeLoader,
214
- wrfcController: services.wrfcController,
215
223
  webSearchService: services.webSearchService,
216
224
  channelRegistry: services.channelPlugins,
217
225
  remoteRunnerRegistry: services.remoteRunnerRegistry,
@@ -228,7 +236,16 @@ export async function initializeBootstrapCore(
228
236
  overflowHandler: services.overflowHandler,
229
237
  changeTracker: services.sessionChangeTracker,
230
238
  });
239
+ registerAgentKnowledgeIngestTool(toolRegistry, services.shellPaths, configManager);
240
+ registerAgentChannelSendTool(toolRegistry, services.channelDeliveryRouter);
241
+ registerAgentKnowledgeTool(toolRegistry, services.shellPaths, configManager);
231
242
  registerAgentLocalRegistryTool(toolRegistry, services.shellPaths, services.memoryRegistry);
243
+ registerAgentMediaGenerateTool(toolRegistry, services.mediaProviders, services.artifactStore);
244
+ registerAgentNotifyTool(toolRegistry, configManager, services.webhookNotifier);
245
+ registerAgentOperatorActionTool(toolRegistry, services.shellPaths, configManager);
246
+ registerAgentOperatorBriefingTool(toolRegistry, services.shellPaths, configManager);
247
+ registerAgentReminderScheduleTool(toolRegistry, services.shellPaths, configManager);
248
+ registerAgentWorkPlanTool(toolRegistry, services.workPlanStore);
232
249
  installAgentToolPolicyGuard(toolRegistry, {
233
250
  getLastUserMessage: () => conversation.getLastUserMessage(),
234
251
  });
@@ -314,7 +331,7 @@ export async function initializeBootstrapCore(
314
331
  const runtimeSessionIdRef = { value: userSessionId };
315
332
  const systemMessageRouterRef: { value: SystemMessageRouter | null } = { value: null };
316
333
  const conversationFollowUpRef: { value: ((item: ConversationFollowUpItem) => void) | null } = { value: null };
317
- const { unsubs: runtimeUnsubs, agentStatusIntervalRef } = registerBootstrapRuntimeEvents({
334
+ const { unsubs: runtimeUnsubs, agentStatusIntervalRef } = registerAgentRuntimeEvents({
318
335
  runtimeBus,
319
336
  domainDispatch,
320
337
  getSystemMessageRouter: () => systemMessageRouterRef.value,
@@ -322,69 +339,10 @@ export async function initializeBootstrapCore(
322
339
  requestRender,
323
340
  configManager,
324
341
  agentManager: services.agentManager,
325
- wrfcController: services.wrfcController,
326
342
  });
327
343
 
328
- // ── TUI-specific WRFC constraint-propagation event subscriptions (SDK 0.23.0) ──
329
- // These supplement the SDK's registerBootstrapRuntimeEvents which handles the
330
- // core WORKFLOW_REVIEW_COMPLETED / WORKFLOW_CHAIN_CREATED messages.
331
- // The SDK does not surface constraint-specific system messages; the TUI layer
332
- // adds them here so operators can observe constraint enumeration and violations
333
- // in the SystemMessagesPanel and main conversation.
334
- runtimeUnsubs.push(
335
- runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_CONSTRAINTS_ENUMERATED' }>>(
336
- 'WORKFLOW_CONSTRAINTS_ENUMERATED',
337
- ({ payload }) => {
338
- const router = systemMessageRouterRef.value;
339
- if (!router) return;
340
- const count = payload.constraints.length;
341
- if (count > 0) {
342
- router.wrfc(
343
- `[WRFC] Engineer enumerated ${count} constraint${count !== 1 ? 's' : ''} for chain ${payload.chainId.slice(0, 12)}`,
344
- 'low',
345
- );
346
- }
347
- requestRender();
348
- },
349
- ),
350
- );
351
- runtimeUnsubs.push(
352
- runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_FIX_ATTEMPTED' }>>(
353
- 'WORKFLOW_FIX_ATTEMPTED',
354
- ({ payload }) => {
355
- const router = systemMessageRouterRef.value;
356
- if (!router) return;
357
- const targetIds = payload.targetConstraintIds;
358
- if (targetIds && targetIds.length > 0) {
359
- router.wrfc(
360
- `[WRFC] Fix #${payload.attempt} targeting ${targetIds.length} constraint${targetIds.length !== 1 ? 's' : ''} on chain ${payload.chainId.slice(0, 12)}`,
361
- 'low',
362
- );
363
- requestRender();
364
- }
365
- },
366
- ),
367
- );
368
- runtimeUnsubs.push(
369
- runtimeBus.on<Extract<import('@/runtime/index.ts').WorkflowEvent, { type: 'WORKFLOW_REVIEW_COMPLETED' }>>(
370
- 'WORKFLOW_REVIEW_COMPLETED',
371
- ({ payload }) => {
372
- const router = systemMessageRouterRef.value;
373
- if (!router) return;
374
- const unsatisfied = payload.unsatisfiedConstraintIds;
375
- if (!payload.passed && unsatisfied && unsatisfied.length > 0) {
376
- router.wrfc(
377
- `[WRFC] ✗ Chain ${payload.chainId.slice(0, 12)}: ${unsatisfied.length} constraint violation${unsatisfied.length !== 1 ? 's' : ''} forced failure`,
378
- 'high',
379
- );
380
- requestRender();
381
- }
382
- },
383
- ),
384
- );
385
-
386
- // Subscribe to companion main-chat messages received from the daemon's HTTP layer.
387
- // The daemon emits COMPANION_MESSAGE_RECEIVED on the runtime bus when a companion
344
+ // Subscribe to companion main-chat messages received from the connected host's HTTP layer.
345
+ // The connected host emits COMPANION_MESSAGE_RECEIVED on the runtime bus when a companion
388
346
  // POST /api/sessions/:id/messages with kind='message' arrives.
389
347
  //
390
348
  // bootstrap.ts patches orchestratorHandleUserInputRef.value after the Orchestrator
@@ -10,9 +10,9 @@ import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config';
10
10
  import { formatReturnContextForDisplay, getReturnContextMode, maybeAssistReturnContextSummary } from '@/runtime/index.ts';
11
11
  import type { SharedSessionBroker } from '@pellux/goodvibes-sdk/platform/control-plane';
12
12
  import type { SessionManager } from '@pellux/goodvibes-sdk/platform/sessions';
13
- import type { PanelManager } from '../panels/panel-manager.ts';
14
13
  import type { ProviderRegistry } from '@pellux/goodvibes-sdk/platform/providers';
15
14
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
15
+ import { readConversationMessageSnapshots } from '../core/conversation-message-snapshot.ts';
16
16
 
17
17
  export interface ResumeSessionOptions {
18
18
  readonly runtimeBus: RuntimeEventBus;
@@ -24,7 +24,6 @@ export interface ResumeSessionOptions {
24
24
  readonly writeLastSessionPointer: (sessionId: string) => void;
25
25
  readonly hookDispatcher: HookDispatcher;
26
26
  readonly sessionManager: SessionManager;
27
- readonly panelManager: PanelManager;
28
27
  readonly configManager: Pick<ConfigManager, 'get' | 'getCategory'>;
29
28
  readonly providerRegistry: Pick<ProviderRegistry, 'get' | 'getCurrentModel' | 'getForModel' | 'require'>;
30
29
  }
@@ -42,7 +41,7 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
42
41
  turnCount: messages.length,
43
42
  });
44
43
  options.conversation.fromJSON({
45
- messages: messages as Parameters<typeof options.conversation.fromJSON>[0]['messages'],
44
+ messages: readConversationMessageSnapshots(messages),
46
45
  title: meta.title,
47
46
  titleSource: meta.titleSource,
48
47
  });
@@ -53,28 +52,18 @@ export function createResumeSessionHandler(options: ResumeSessionOptions): (sess
53
52
  options.writeLastSessionPointer(sessionId);
54
53
  void options.sharedSessionBroker.reopenSession(sessionId).catch((err) => { logger.debug('session broker reopen session failed', { err }); });
55
54
  options.conversation.log(`Resumed session: ${sessionId}`, { fg: '135' });
56
- const reopenedPanels: string[] = [];
57
- if (meta.returnContext?.openPanels?.length) {
58
- for (const panelId of meta.returnContext.openPanels.slice(0, 4)) {
59
- try {
60
- options.panelManager.open(panelId);
61
- reopenedPanels.push(panelId);
62
- } catch {
63
- // Ignore unavailable panels during restore.
64
- }
65
- }
66
- if (reopenedPanels.length > 0) options.panelManager.show();
67
- }
55
+ const ignoredPanels = meta.returnContext?.openPanels?.slice(0, 4) ?? [];
68
56
  const returnContextMode = getReturnContextMode(options.configManager);
69
57
  if (returnContextMode !== 'off' && meta.returnContext) {
70
58
  for (const line of formatReturnContextForDisplay(meta.returnContext)) {
59
+ if (line.startsWith('Open panels:')) continue;
71
60
  options.conversation.log(`Resume: ${line}`, { fg: '244' });
72
61
  }
73
- if (reopenedPanels.length > 0) {
74
- options.conversation.log(`Resume: Reopened panels: ${reopenedPanels.join(', ')}`, { fg: '244' });
62
+ if (ignoredPanels.length > 0) {
63
+ options.conversation.log(`Resume: Saved panel state ignored: ${ignoredPanels.join(', ')}. Open the Agent workspace for current operator controls.`, { fg: '244' });
75
64
  }
76
65
  if ((meta.returnContext.remoteRunners?.length ?? 0) > 0) {
77
- options.conversation.log('Resume: Remote runner recovery belongs outside Agent; delegate explicit build/fix/review recovery from Agent.', { fg: '244' });
66
+ options.conversation.log('Resume: Remote build-host recovery belongs outside Agent; delegate explicit build/fix/review recovery from Agent.', { fg: '244' });
78
67
  }
79
68
  if (returnContextMode === 'assisted') {
80
69
  const helperModel = new HelperModel({
@@ -62,6 +62,43 @@ export interface BootstrapShellOptions {
62
62
  readonly completeModelSelectionSideEffect?: () => void;
63
63
  }
64
64
 
65
+ type PlanningAnswerSubmit = (answer: string) => void;
66
+
67
+ export interface PlanningAnswerSubmitBridgeOptions {
68
+ readonly getSubmitInput: () => PlanningAnswerSubmit | undefined;
69
+ readonly addSystemMessage: (message: string) => void;
70
+ readonly requestRender: () => void;
71
+ readonly defer?: (callback: () => void) => void;
72
+ }
73
+
74
+ export function submitPlanningAnswerWithShellFallback(
75
+ answer: string,
76
+ options: PlanningAnswerSubmitBridgeOptions,
77
+ ): void {
78
+ const submit = options.getSubmitInput();
79
+ if (submit) {
80
+ submit(answer);
81
+ return;
82
+ }
83
+
84
+ const defer = options.defer ?? ((callback) => {
85
+ setTimeout(callback, 0);
86
+ });
87
+ defer(() => {
88
+ const deferredSubmit = options.getSubmitInput();
89
+ if (deferredSubmit) {
90
+ deferredSubmit(answer);
91
+ return;
92
+ }
93
+
94
+ options.addSystemMessage([
95
+ '[Planning] Could not submit the selected answer because the prompt bridge is not ready.',
96
+ `Paste this answer into the prompt to continue planning: ${answer}`,
97
+ ].join('\n'));
98
+ options.requestRender();
99
+ });
100
+ }
101
+
65
102
  export function createBootstrapShell(options: BootstrapShellOptions): BootstrapShellState {
66
103
  const {
67
104
  configManager,
@@ -96,7 +133,6 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
96
133
  writeLastSessionPointer,
97
134
  hookDispatcher: services.hookDispatcher,
98
135
  sessionManager: services.sessionManager,
99
- panelManager: services.panelManager,
100
136
  configManager,
101
137
  providerRegistry: services.providerRegistry,
102
138
  });
@@ -113,10 +149,11 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
113
149
  resumeSession,
114
150
  requestRender,
115
151
  submitPlanningAnswer: (answer) => {
116
- if (!commandContextRef?.submitInput) {
117
- throw new Error('Planning answer submission is not wired yet.');
118
- }
119
- commandContextRef.submitInput(answer);
152
+ submitPlanningAnswerWithShellFallback(answer, {
153
+ getSubmitInput: () => commandContextRef?.submitInput,
154
+ addSystemMessage: (message) => conversation.addSystemMessage(message),
155
+ requestRender,
156
+ });
120
157
  },
121
158
  dismissPlanning: () => {
122
159
  services.panelManager.close('project-planning');
@@ -142,7 +179,7 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
142
179
  hookActivityTracker: services.hookActivityTracker,
143
180
  hookWorkbench: services.hookWorkbench,
144
181
  mcpRegistry: services.mcpRegistry,
145
- daemonHomeDir: join(services.homeDirectory, '.goodvibes', 'daemon'),
182
+ connectedHostTokenDir: join(services.homeDirectory, '.goodvibes', 'daemon'),
146
183
  });
147
184
  services.panelManager.prewarmRegistered();
148
185
 
@@ -160,9 +197,8 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
160
197
 
161
198
  const commandRegistry = new CommandRegistry();
162
199
  registerBuiltinCommands(commandRegistry);
163
- type RuntimeFoundationInput = Parameters<typeof createRuntimeFoundationClients>[0];
164
200
  const foundationClients = createRuntimeFoundationClients({
165
- runtimeServices: services as unknown as RuntimeFoundationInput['runtimeServices'],
201
+ runtimeServices: services,
166
202
  tasksReadModel: uiServices.readModels.tasks,
167
203
  taskManager,
168
204
  opsControlPlane,
@@ -198,6 +234,8 @@ export function createBootstrapShell(options: BootstrapShellOptions): BootstrapS
198
234
  voiceProviderRegistry: services.voiceProviders,
199
235
  voiceService: services.voiceService,
200
236
  mediaProviderRegistry: services.mediaProviders,
237
+ artifactStore: services.artifactStore,
238
+ channelDeliveryRouter: services.channelDeliveryRouter,
201
239
  forensicsRegistry,
202
240
  policyRuntimeState,
203
241
  readModels: uiServices.readModels,
@@ -10,7 +10,6 @@
10
10
  * - lifecycle.ts: save/shutdown helpers
11
11
  */
12
12
  import { Orchestrator, type OrchestratorUserInputOptions } from '../core/orchestrator.ts';
13
- import { AcpManager } from '@pellux/goodvibes-sdk/platform/acp';
14
13
  import { getTierPromptSupplement, getTierForContextWindow } from '@pellux/goodvibes-sdk/platform/providers';
15
14
  import { logger } from '@pellux/goodvibes-sdk/platform/utils';
16
15
  import type { PermissionRequestHandler } from '@pellux/goodvibes-sdk/platform/permissions';
@@ -23,7 +22,6 @@ import type { RuntimeContext, BootstrapOptions } from './context.ts';
23
22
  import { shutdownRuntime, fireSessionStart, saveSession } from '@/runtime/index.ts';
24
23
  import { createTaskManager } from '@/runtime/index.ts';
25
24
  import { OpsControlPlane } from '@/runtime/index.ts';
26
- import { AcpTaskAdapter } from '@/runtime/index.ts';
27
25
  import type { SystemMessageRouter } from '../core/system-message-router.ts';
28
26
  import { emitSessionReady, emitSessionStarted } from '@/runtime/index.ts';
29
27
  import {
@@ -47,14 +45,23 @@ import { buildReviewedMemoryPrompt } from '../agent/memory-prompt.ts';
47
45
 
48
46
  const GOODVIBES_AGENT_OPERATOR_POLICY = [
49
47
  '## GoodVibes Agent Operator Policy',
50
- '- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure local Agent state, use read-only connected-service/operator routes, and take safe non-destructive actions without spawning local agents or WRFC.',
51
- '- GoodVibes Agent connects to GoodVibes services owned outside this package. Do not start, stop, restart, install, expose, or mutate connected-service network/listener posture from Agent.',
52
- '- Use the `agent_local_registry` tool when a durable memory, reusable persona, skill, skill bundle, or routine would improve future work. Keep those records local, non-secret, source/provenance tagged, and reviewable. Review memory with a confidence score when it should shape future turns. Starting a routine means applying its steps in this same serial conversation, not creating a background job.',
53
- '- WRFC is never the default Agent reasoning path. Do not create local WRFC chains for planning, research, operations, knowledge, memory, configuration, approvals, automation observability, or ordinary assistant work.',
54
- '- GoodVibes Agent is not the coding TUI. Do not use the `agent` tool to spawn local Engineer, Reviewer, Tester, Verifier, or batch-spawn roots from Agent.',
55
- '- When the user explicitly asks to build, implement, fix, patch, or review code, preserve the full original user ask and delegate one build request to GoodVibes TUI through the public shared-session/build-delegation contract. Include clear executionIntent and request WRFC only for explicit build/fix/review work or when the user explicitly asks for WRFC/agent review.',
56
- '- Do not narrow explicit build/fix/review requests into design-only, read-only, or no-write work unless the user explicitly requested that limitation. TUI owns file edits, git/worktree work, execution isolation UX, and the WRFC owner chain.',
57
- '- If a stable public delegation route is unavailable, say that the task needs GoodVibes TUI delegation and report the missing route instead of pretending to implement it locally or spawning sibling local agents.',
48
+ '- Default to serial, proactive assistant work in the main conversation. Answer, inspect, summarize, remember useful non-secret facts, configure Agent-local state, use read-only connected-host/operator routes, and take safe non-destructive actions without creating separate Agent jobs or GoodVibes TUI delegations.',
49
+ '- GoodVibes Agent connects to a GoodVibes host owned outside this package. Do not start, stop, restart, install, expose, or mutate connected-host network/listener posture from Agent.',
50
+ '- Use the `agent_operator_briefing` tool for read-only main-conversation summaries of connected work plan, approvals, automation, schedules, and scheduler capacity. This tool must not call mutation routes, connected-host lifecycle routes, default knowledge, non-Agent knowledge spaces, separate Agent job creation, or GoodVibes TUI delegation.',
51
+ '- When the user explicitly asks Agent to approve, deny, or cancel a specific approval, run/pause/resume a specific automation job, cancel/retry a specific automation run, or run a specific schedule, use the `agent_operator_action` tool with confirm:true and the original user request. It can call only its allowlisted public operator routes and must not create, edit, delete, or discover automation definitions.',
52
+ '- Use the `agent_work_plan` tool to keep the visible Agent-local work plan current while working in the main conversation. Create, inspect, and update local work items proactively when useful. Removing items or clearing completed items requires an explicit user request and confirm:true.',
53
+ '- Use the `agent_knowledge` tool for Agent Knowledge status, ask, and search from the main conversation. It must use only /api/goodvibes-agent/knowledge/* and must fail closed instead of falling back to default knowledge or non-Agent knowledge spaces.',
54
+ '- When the user explicitly asks Agent to add, import, remember, or ingest a URL, URL-list file, local file, bookmarks file, browser history, or connector input into Agent Knowledge, use the `agent_knowledge_ingest` tool with confirm:true and the original user request. It must write only to /api/goodvibes-agent/knowledge/* ingest routes and never to default knowledge or non-Agent knowledge spaces.',
55
+ '- Use the `agent_local_registry` tool when a scratchpad note, durable memory, reusable persona, skill, skill bundle, or routine would improve later work. Keep those records Agent-local, non-secret, source/provenance tagged, and reviewable. Notes are for temporary/source-triage context; promote them explicitly into memory, skills, personas, routines, or Agent Knowledge only when that is the correct durable home. Review memory with a confidence score when it should shape later turns. Starting a routine means applying its steps in this same serial conversation, not creating a background job.',
56
+ '- When the user explicitly asks Agent to generate an image, video, or other media artifact, use the `agent_media_generate` tool with confirm:true and the original user request. Generated media is stored as artifacts; do not print base64, call default knowledge, use non-Agent knowledge spaces, send channels, create separate Agent jobs, or request GoodVibes TUI delegation for media generation.',
57
+ '- When the user explicitly asks Agent to send an alert, message, or notification to configured notification targets, use the `agent_notify` tool with confirm:true and the original user request. Do not infer external notifications from vague suggestions, and never create channel routes or account authorizations from the main conversation.',
58
+ '- When the user explicitly asks Agent to send one message to a specific configured channel, route, webhook, or link target, use the `agent_channel_send` tool with confirm:true and the original user request. It can deliver one message through configured delivery strategies, but must not create routes, authorize accounts, manage connected-host hosting, use default knowledge, use non-Agent knowledge spaces, create separate Agent jobs, or request GoodVibes TUI delegation.',
59
+ '- When the user explicitly asks for a reminder or asks Agent to schedule a reminder, use the `agent_reminder_schedule` tool with confirm:true and the original user request. That creates one connected schedules.create reminder on the external GoodVibes host. Do not infer reminders from vague suggestions or routine startup, and never create local scheduler jobs.',
60
+ '- GoodVibes TUI delegation is never the default Agent reasoning path. Do not delegate planning, research, operations, knowledge, memory, configuration, approvals, automation observability, or ordinary assistant work.',
61
+ '- GoodVibes Agent is not the coding TUI. Do not use the `agent` tool to create coding-role Agent jobs or batch job roots from Agent.',
62
+ '- When the user explicitly asks to build, implement, fix, patch, or review code, preserve the full original user ask and delegate one build request to GoodVibes TUI through the public shared-session/build-delegation contract. Include clear executionIntent and request delegated review only for explicit build/fix/review work or when the user explicitly asks for delegated Agent review.',
63
+ '- Do not narrow explicit build/fix/review requests into design-only, read-only, or no-write work unless the user explicitly requested that limitation. TUI owns file edits, git/worktree work, execution isolation UX, and delegated review coordination.',
64
+ '- If a stable public delegation route is unavailable, say that the task needs GoodVibes TUI delegation and report the missing route instead of pretending to implement it locally or creating sibling Agent jobs.',
58
65
  ].join('\n');
59
66
 
60
67
  function joinPromptParts(...parts: Array<string | null | undefined>): string {
@@ -128,9 +135,9 @@ export type BootstrapContext = RuntimeContext & {
128
135
  * 1. Config, caches, keybindings
129
136
  * 2. Runtime event bus, conversation, compositor, selection
130
137
  * 3. Tool registry + agent wiring
131
- * 4. Runtime bus subscriptions (WRFC, subagent, hook bridge)
138
+ * 4. Runtime bus subscriptions (delegation, subagent, hook bridge)
132
139
  * 5. Providers, webhooks, PermissionManager, HookDispatcher
133
- * 6. Orchestrator + AcpManager
140
+ * 6. Orchestrator and Agent-local task read models
134
141
  * 7. MCP auto-connect + workspace/panel manager
135
142
  * 8. Command registry + plugin init + CommandContext
136
143
  * 9. Input handler wiring
@@ -183,7 +190,7 @@ export async function bootstrapRuntime(
183
190
  pluginManager,
184
191
  } = services;
185
192
 
186
- // ── Phase 6: Orchestrator + AcpManager ───────────────────────────────────
193
+ // ── Phase 6: Orchestrator and Agent-local task read models ───────────────
187
194
 
188
195
  // Mutable function refs so main.ts can patch these after constructing the scroll/viewport state.
189
196
  // The orchestrator closes over these refs, so patching them in main.ts takes immediate effect.
@@ -243,17 +250,6 @@ export async function bootstrapRuntime(
243
250
  });
244
251
  conversation.setSessionLineageTracker(services.sessionLineageTracker);
245
252
 
246
- const acpManager = new AcpManager({
247
- requestPermission: (request) => permissionPromptRef.requestPermission(request),
248
- runtimeBus,
249
- hookDispatcher: services.hookDispatcher,
250
- });
251
- const acpTaskAdapter = new AcpTaskAdapter(store);
252
- const ACP_TASK_SYNC_INTERVAL_MS = 1_000;
253
- const acpTaskSyncInterval = setInterval(() => {
254
- acpTaskAdapter.sync(acpManager);
255
- }, ACP_TASK_SYNC_INTERVAL_MS);
256
- bootstrapUnsubs.push(() => clearInterval(acpTaskSyncInterval));
257
253
  const opsTaskManager = createTaskManager(store, runtimeBus, userSessionId);
258
254
  const opsControlPlane = services.featureFlags.isEnabled('operator-control-plane')
259
255
  ? new OpsControlPlane(opsTaskManager, runtimeBus, store, userSessionId)
@@ -308,7 +304,7 @@ export async function bootstrapRuntime(
308
304
  },
309
305
  };
310
306
 
311
- // ── Phase 7: External services + deferred startup ──────────────────────
307
+ // ── Phase 7: Connected-host posture + deferred startup ────────────────
312
308
 
313
309
  const deferredStartup = createDeferredStartupCoordinator();
314
310
 
@@ -323,7 +319,7 @@ export async function bootstrapRuntime(
323
319
  return `http://${urlHost}:${port}`;
324
320
  };
325
321
 
326
- const createExternalAgentServiceStatus = (
322
+ const createAgentDependencyStatus = (
327
323
  service: 'daemon' | 'httpListener',
328
324
  ): HostServiceStatus => {
329
325
  const host = String(configManager.get(service === 'daemon' ? 'controlPlane.host' : 'httpListener.host') ?? '127.0.0.1');
@@ -334,7 +330,7 @@ export async function bootstrapRuntime(
334
330
  port,
335
331
  baseUrl: formatHostServiceBaseUrl(host, port),
336
332
  reason: service === 'daemon'
337
- ? 'GoodVibes Agent connects to GoodVibes services owned outside this product and does not start or restart them.'
333
+ ? 'GoodVibes Agent connects to a GoodVibes host owned outside this product and does not start or restart it.'
338
334
  : 'GoodVibes Agent does not own listener lifecycle.',
339
335
  };
340
336
  };
@@ -343,15 +339,15 @@ export async function bootstrapRuntime(
343
339
 
344
340
  const hostServiceIsBlocked = (status: HostServiceStatus): boolean => status.mode === 'blocked';
345
341
 
346
- const inspectExternalServices = () => {
342
+ const inspectAgentDependencies = () => {
347
343
  const daemonStatus = externalServices.daemonStatus;
348
344
  const httpListenerStatus = externalServices.httpListenerStatus;
349
345
  return {
350
- daemonRunning: hostServiceIsActive(daemonStatus),
351
- daemonPortInUse: hostServiceIsBlocked(daemonStatus),
346
+ connectedHostRunning: hostServiceIsActive(daemonStatus),
347
+ connectedHostPortInUse: hostServiceIsBlocked(daemonStatus),
352
348
  httpListenerRunning: hostServiceIsActive(httpListenerStatus),
353
349
  httpListenerPortInUse: hostServiceIsBlocked(httpListenerStatus),
354
- daemonStatus,
350
+ connectedHostStatus: daemonStatus,
355
351
  httpListenerStatus,
356
352
  };
357
353
  };
@@ -359,8 +355,8 @@ export async function bootstrapRuntime(
359
355
  let externalServices: ExternalServicesHandle = {
360
356
  daemonServer: null,
361
357
  httpListener: null,
362
- daemonStatus: createExternalAgentServiceStatus('daemon'),
363
- httpListenerStatus: createExternalAgentServiceStatus('httpListener'),
358
+ daemonStatus: createAgentDependencyStatus('daemon'),
359
+ httpListenerStatus: createAgentDependencyStatus('httpListener'),
364
360
  listRecentControlPlaneEvents: () => [],
365
361
  async stop(): Promise<void> {},
366
362
  };
@@ -368,16 +364,16 @@ export async function bootstrapRuntime(
368
364
  externalServices: NonNullable<typeof uiServices.platform.externalServices>;
369
365
  };
370
366
  platformExternalServices.externalServices = {
371
- inspect: inspectExternalServices,
367
+ inspect: inspectAgentDependencies,
372
368
  restart: async () => {
373
369
  externalServices = {
374
370
  ...externalServices,
375
- daemonStatus: createExternalAgentServiceStatus('daemon'),
376
- httpListenerStatus: createExternalAgentServiceStatus('httpListener'),
371
+ daemonStatus: createAgentDependencyStatus('daemon'),
372
+ httpListenerStatus: createAgentDependencyStatus('httpListener'),
377
373
  };
378
- systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart connected GoodVibes services. Start them from GoodVibes TUI or the owning host, then refresh status.');
374
+ systemMessageRouter.high('[Startup] GoodVibes Agent does not start or restart the connected GoodVibes host. Start it from GoodVibes TUI or the owning host, then refresh status.');
379
375
  requestRender();
380
- return inspectExternalServices();
376
+ return inspectAgentDependencies();
381
377
  },
382
378
  };
383
379
  deferredStartup.schedule({
@@ -452,8 +448,8 @@ export async function bootstrapRuntime(
452
448
  });
453
449
  bootstrapUnsubs.push(() => mcpAutoReload.stop());
454
450
  if (configManager.get('automation.enabled')) {
455
- logger.warn('Local automation startup is disabled in GoodVibes Agent; use connected-service observability instead.');
456
- systemMessageRouter.low('[Startup] Local automation runners are disabled in GoodVibes Agent; use read-only automation observability or explicit connected-service actions.');
451
+ logger.warn('Local automation startup is disabled in GoodVibes Agent; use connected-host observability instead.');
452
+ systemMessageRouter.low('[Startup] Local automation execution is disabled in GoodVibes Agent; use read-only automation observability or explicit connected-host actions.');
457
453
  }
458
454
 
459
455
  // ── Phase 12: Session:start lifecycle hook ─────────────────────────────
@@ -554,12 +550,6 @@ export async function bootstrapRuntime(
554
550
  },
555
551
  };
556
552
 
557
- // ── Phase 12b: Operator intervention wiring (feature-gated) ──────────────
558
- // Keep service-owned control-plane state internal. GoodVibes Agent does not
559
- // expose the local ops-control panel; operator control is surfaced
560
- // through Agent-owned status, approvals, automation, and delegation flows.
561
- ctx.commandContext.ops.acpManager = acpManager;
562
-
563
553
  // Wire exit from options if provided; otherwise main.ts binds the shell bridge.
564
554
  if (options?.exit) {
565
555
  ctx.commandContext.exit = options.exit;
@@ -0,0 +1,47 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+
5
+ type JsonRecord = Record<string, unknown>;
6
+
7
+ export interface ConnectedHostOperatorToken {
8
+ readonly path: string;
9
+ readonly present: boolean;
10
+ readonly token: string | null;
11
+ readonly error?: string;
12
+ }
13
+
14
+ function isRecord(value: unknown): value is JsonRecord {
15
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
16
+ }
17
+
18
+ export function connectedHostOperatorTokenPath(homeDirectory: string): string {
19
+ return join(homeDirectory, '.goodvibes', 'daemon', 'operator-tokens.json');
20
+ }
21
+
22
+ export function readConnectedHostOperatorToken(homeDirectory: string): ConnectedHostOperatorToken {
23
+ const path = connectedHostOperatorTokenPath(homeDirectory);
24
+ if (!existsSync(path)) return { path, present: false, token: null };
25
+ try {
26
+ const parsed = JSON.parse(readFileSync(path, 'utf-8')) as unknown;
27
+ const token = isRecord(parsed) && typeof parsed.token === 'string' && parsed.token.trim().length > 0
28
+ ? parsed.token
29
+ : null;
30
+ return { path, present: true, token };
31
+ } catch (error) {
32
+ return { path, present: true, token: null, error: error instanceof Error ? error.message : String(error) };
33
+ }
34
+ }
35
+
36
+ export function connectedHostOperatorTokenFingerprint(token: string): string {
37
+ return createHash('sha256').update(token).digest('hex').slice(0, 12);
38
+ }
39
+
40
+ export function connectedHostTokenRequiredMessage(path: string): string {
41
+ return [
42
+ 'Connected-host operator token is required.',
43
+ ` token path ${path}`,
44
+ ' Agent does not create or rotate connected-host auth tokens.',
45
+ ' Provision or repair connected-host access through the owning GoodVibes host, then rerun this command.',
46
+ ].join('\n');
47
+ }
@@ -12,8 +12,8 @@ export type { InspectableDomain } from '@/runtime/index.ts';
12
12
  export { HealthPanel } from '@/runtime/index.ts';
13
13
  export { DivergencePanel } from '@/runtime/index.ts';
14
14
  export { ReplayPanel } from '@/runtime/index.ts';
15
- export { PolicyPanel } from './policy.ts';
16
- export type { PolicyPanelSnapshot } from './policy.ts';
15
+ export { PolicyDiagnosticsPanel } from './policy.ts';
16
+ export type { PolicyDiagnosticsSnapshot } from './policy.ts';
17
17
  export { ToolContractsPanel } from '@/runtime/index.ts';
18
18
  export { TransportPanel } from '@/runtime/index.ts';
19
19
  export type { TransportPanelSnapshot } from '@/runtime/index.ts';
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Panel resource diagnostics panel data provider.
3
3
  *
4
- * Polls the shared TUI-owned ComponentHealthMonitor and produces PanelResourceSnapshot
4
+ * Polls the shared shell ComponentHealthMonitor and produces PanelResourceSnapshot
5
5
  * values for the diagnostics panel to render.
6
6
  */
7
7
  import type { ComponentHealthMonitor } from '../../perf/panel-health-monitor.ts';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Policy diagnostics panel data provider.
2
+ * Policy diagnostics data provider.
3
3
  *
4
4
  * Wraps a `PolicyRegistry` and optionally a `DivergencePanel` to expose
5
5
  * combined policy state (current bundle, candidate, simulation status,
@@ -24,7 +24,7 @@ import { logger } from '@pellux/goodvibes-sdk/platform/utils';
24
24
  /**
25
25
  * A point-in-time snapshot of policy state for diagnostics rendering.
26
26
  */
27
- export interface PolicyPanelSnapshot {
27
+ export interface PolicyDiagnosticsSnapshot {
28
28
  /** The currently enforced bundle, or null if no policy is active. */
29
29
  current: PolicyBundleVersion | null;
30
30
  /** The pending candidate bundle, or null if none loaded. */
@@ -48,12 +48,12 @@ export interface PolicyPanelSnapshot {
48
48
  }
49
49
 
50
50
  /**
51
- * PolicyPanel — diagnostics data provider for the policy registry.
51
+ * PolicyDiagnosticsPanel — diagnostics data provider for the policy registry.
52
52
  *
53
53
  * Usage:
54
54
  * ```ts
55
55
  * const registry = new PolicyRegistry();
56
- * const panel = new PolicyPanel(registry, divergencePanel);
56
+ * const panel = new PolicyDiagnosticsPanel(registry, divergencePanel);
57
57
  *
58
58
  * panel.subscribe(() => {
59
59
  * const snap = panel.getSnapshot();
@@ -67,7 +67,7 @@ export interface PolicyPanelSnapshot {
67
67
  * panel.dispose();
68
68
  * ```
69
69
  */
70
- export class PolicyPanel {
70
+ export class PolicyDiagnosticsPanel {
71
71
  private readonly _registry: PolicyRegistry;
72
72
  private readonly _divergencePanel: DivergencePanel | null;
73
73
  private readonly _config: PanelConfig;
@@ -118,7 +118,7 @@ export class PolicyPanel {
118
118
  /**
119
119
  * getSnapshot — Returns the current combined policy + divergence snapshot.
120
120
  */
121
- public getSnapshot(): PolicyPanelSnapshot {
121
+ public getSnapshot(): PolicyDiagnosticsSnapshot {
122
122
  const current = this._registry.getCurrent();
123
123
  const candidate = this._registry.getCandidate();
124
124
  const rawHistory = this._registry.getHistory();
@@ -170,7 +170,7 @@ export class PolicyPanel {
170
170
  try {
171
171
  cb();
172
172
  } catch (err) {
173
- logger.warn(`[PolicyPanel] subscriber error: ${err}`);
173
+ logger.warn(`[PolicyDiagnosticsPanel] subscriber error: ${err}`);
174
174
  }
175
175
  }
176
176
  }