@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
@@ -16,7 +16,7 @@ export const MCP_WORKSPACE_MODAL_NAME = 'mcpWorkspace';
16
16
  const MCP_ROLES = ['general', 'docs', 'filesystem', 'git', 'database', 'browser', 'automation', 'ops', 'remote'] as const;
17
17
  const MCP_FORM_TRUST_MODES = ['constrained', 'ask-on-risk', 'blocked'] as const;
18
18
 
19
- export type McpWorkspaceMode = 'browse' | 'form' | 'delete-confirm';
19
+ export type McpWorkspaceMode = 'browse' | 'form' | 'delete-confirm' | 'reload-confirm';
20
20
 
21
21
  export interface McpWorkspaceServerRow {
22
22
  readonly name: string;
@@ -62,6 +62,7 @@ export interface McpWorkspaceForm {
62
62
  env: string;
63
63
  allowedPaths: string;
64
64
  allowedHosts: string;
65
+ confirm: string;
65
66
  }
66
67
 
67
68
  interface McpWorkspaceSnapshot {
@@ -71,8 +72,12 @@ interface McpWorkspaceSnapshot {
71
72
  readonly servers: readonly McpWorkspaceServerRow[];
72
73
  }
73
74
 
74
- function isTextField(field: keyof McpWorkspaceForm | 'save' | 'cancel'): field is 'name' | 'command' | 'args' | 'env' | 'allowedPaths' | 'allowedHosts' {
75
- return field === 'name' || field === 'command' || field === 'args' || field === 'env' || field === 'allowedPaths' || field === 'allowedHosts';
75
+ function isTextField(field: keyof McpWorkspaceForm | 'save' | 'cancel'): field is 'name' | 'command' | 'args' | 'env' | 'allowedPaths' | 'allowedHosts' | 'confirm' {
76
+ return field === 'name' || field === 'command' || field === 'args' || field === 'env' || field === 'allowedPaths' || field === 'allowedHosts' || field === 'confirm';
77
+ }
78
+
79
+ function isAffirmative(value: string): boolean {
80
+ return /^(y|yes|true)$/i.test(value.trim());
76
81
  }
77
82
 
78
83
  function splitList(value: string): string[] {
@@ -141,6 +146,7 @@ function serverConfigToForm(server?: McpServerConfig): McpWorkspaceForm {
141
146
  env: server?.env ? Object.entries(server.env).map(([key, value]) => `${key}=${value}`).join(', ') : '',
142
147
  allowedPaths: server?.allowedPaths?.join(', ') ?? '',
143
148
  allowedHosts: server?.allowedHosts?.join(', ') ?? '',
149
+ confirm: '',
144
150
  };
145
151
  }
146
152
 
@@ -214,7 +220,7 @@ export class McpWorkspace {
214
220
  public formIndex = 0;
215
221
  public form: McpWorkspaceForm = serverConfigToForm();
216
222
  public editingServerName: string | null = null;
217
- public status = 'Ready. Inspect MCP servers and tools. Config writes/reloads require explicit /mcp ... --yes commands.';
223
+ public status = 'Ready. Inspect MCP servers and tools. Config writes/reloads require explicit workspace confirmation.';
218
224
  public tools: readonly RegisteredTool[] = [];
219
225
  public loadingTools = false;
220
226
  public lastError: string | null = null;
@@ -257,8 +263,8 @@ export class McpWorkspace {
257
263
  get rows(): readonly McpWorkspaceRow[] {
258
264
  return [
259
265
  ...this.snapshot.servers.map((server): McpWorkspaceRow => ({ type: 'server', server })),
260
- { type: 'action', id: 'add', label: 'Add server preview', detail: `Draft server details here, then run /mcp add ... --scope ${this.form.scope} --yes to write config.` },
261
- { type: 'action', id: 'reload', label: 'Reload guidance', detail: 'Runtime reload is blocked from the workspace; run /mcp reload --yes explicitly.' },
266
+ { type: 'action', id: 'add', label: 'Add or update server', detail: `Open a confirmed Agent workspace form to save an MCP server in ${this.form.scope} scope.` },
267
+ { type: 'action', id: 'reload', label: 'Reload runtime', detail: 'Confirm an MCP runtime reload from this workspace after external config edits.' },
262
268
  { type: 'action', id: 'refresh-tools', label: 'Refresh tools', detail: 'Fetch the currently available MCP tool list from connected servers.' },
263
269
  { type: 'action', id: 'config', label: 'Config locations', detail: 'Show SDK-scanned config files and writable project/global paths.' },
264
270
  ];
@@ -284,7 +290,8 @@ export class McpWorkspace {
284
290
  { id: 'env', label: 'Environment', value: this.form.env, help: 'Comma-separated KEY=VALUE entries. Prefer env var references or secure secrets for sensitive values.', editable: true },
285
291
  { id: 'allowedPaths', label: 'Allowed paths', value: this.form.allowedPaths, help: 'Comma-separated path prefixes for filesystem-oriented servers.', editable: true },
286
292
  { id: 'allowedHosts', label: 'Allowed hosts', value: this.form.allowedHosts, help: 'Comma-separated hostnames for network-oriented servers.', editable: true },
287
- { id: 'save', label: 'Show save command', value: '', help: 'No workspace write. Shows the explicit /mcp add ... --yes command to run from the prompt.', editable: false },
293
+ { id: 'confirm', label: 'Confirm', value: this.form.confirm, help: 'Type yes to save this MCP server through the TUI command dispatcher.', editable: true },
294
+ { id: 'save', label: 'Save server', value: '', help: 'Dispatch the confirmed MCP server add/update through the workspace.', editable: false },
288
295
  { id: 'cancel', label: 'Cancel', value: '', help: 'Return to the MCP server browser without changing config.', editable: false },
289
296
  ];
290
297
  }
@@ -323,11 +330,15 @@ export class McpWorkspace {
323
330
  }
324
331
  }
325
332
 
326
- async reloadRuntime(): Promise<void> {
327
- if (!this.context) return;
333
+ requestReload(): void {
328
334
  this.lastError = null;
329
- this.status = 'MCP runtime reload is blocked in the workspace. Run /mcp reload --yes from the prompt to explicitly reload.';
330
- this.context.renderRequest();
335
+ this.mode = 'reload-confirm';
336
+ this.status = 'Confirm MCP runtime reload. Press Enter or y to reload; Esc or n cancels.';
337
+ this.context?.renderRequest();
338
+ }
339
+
340
+ async reloadRuntime(): Promise<void> {
341
+ await this.dispatchMcpCommand(['reload', '--yes'], 'MCP runtime reload');
331
342
  }
332
343
 
333
344
  openAddForm(): void {
@@ -335,7 +346,7 @@ export class McpWorkspace {
335
346
  this.formIndex = 0;
336
347
  this.editingServerName = null;
337
348
  this.form = serverConfigToForm();
338
- this.status = 'Draft an MCP server. Saving from this workspace is blocked; use the shown /mcp add ... --yes command.';
349
+ this.status = 'Draft an MCP server. Type yes on the Confirm field, then press Enter on Save server.';
339
350
  }
340
351
 
341
352
  openEditForm(serverName: string): void {
@@ -345,7 +356,7 @@ export class McpWorkspace {
345
356
  this.editingServerName = serverName;
346
357
  this.form = { ...serverConfigToForm(entry?.server), scope: entry?.source.scope === 'global' ? 'global' : 'project' };
347
358
  this.status = entry
348
- ? `Viewing ${serverName}. Workspace saves are blocked; copy the generated /mcp add ... --yes command if you intend to change it.`
359
+ ? `Editing ${serverName}. Type yes on the Confirm field, then press Enter on Save server to update it.`
349
360
  : `Viewing ${serverName}. Runtime status exists, but no launch config was found.`;
350
361
  }
351
362
 
@@ -354,23 +365,38 @@ export class McpWorkspace {
354
365
  this.editingServerName = serverName;
355
366
  const entry = this.snapshot.effectiveConfig.servers.find((configEntry) => configEntry.server.name === serverName);
356
367
  const scope = entry?.source.scope === 'global' ? 'global' : 'project';
357
- this.status = `MCP server removal is blocked in the workspace. Run /mcp remove ${serverName} --scope ${scope} --yes from the prompt.`;
368
+ this.status = `Confirm removal of ${serverName} from ${scope} MCP config. Press Enter or y to remove; Esc or n cancels.`;
358
369
  }
359
370
 
360
371
  async saveForm(): Promise<void> {
361
372
  if (!this.context) return;
362
373
  try {
374
+ if (!isAffirmative(this.form.confirm)) {
375
+ this.status = 'MCP server add/update not confirmed. Type yes on the Confirm field, then press Enter on Save server.';
376
+ this.context.renderRequest();
377
+ return;
378
+ }
363
379
  const server = formToServerConfig(this.form);
380
+ const args = [
381
+ 'add',
382
+ server.name,
383
+ server.command,
384
+ ...(server.args ?? []),
385
+ '--scope',
386
+ this.form.scope,
387
+ ];
388
+ if (server.role) args.push('--role', server.role);
389
+ if (server.trustMode) args.push('--trust', server.trustMode);
390
+ for (const [key, value] of Object.entries(server.env ?? {})) args.push('--env', `${key}=${value}`);
391
+ for (const path of server.allowedPaths ?? []) args.push('--path', path);
392
+ for (const host of server.allowedHosts ?? []) args.push('--host', host);
393
+ args.push('--yes');
364
394
  this.mode = 'browse';
365
395
  this.editingServerName = null;
366
- const args = server.args?.length ? ` ${server.args.join(' ')}` : '';
367
- const role = server.role ? ` --role ${server.role}` : '';
368
- const trust = server.trustMode ? ` --trust ${server.trustMode}` : '';
369
- this.status = `MCP config write blocked here. Run: /mcp add ${server.name} ${server.command}${args} --scope ${this.form.scope}${role}${trust} --yes`;
370
- this.context.renderRequest();
396
+ await this.dispatchMcpCommand(args, `MCP server ${server.name} add/update`);
371
397
  } catch (error) {
372
398
  this.lastError = summarizeError(error);
373
- this.status = `Save command preview failed: ${this.lastError}`;
399
+ this.status = `MCP server save failed before dispatch: ${this.lastError}`;
374
400
  this.context.renderRequest();
375
401
  }
376
402
  }
@@ -382,8 +408,7 @@ export class McpWorkspace {
382
408
  const scope = server?.source.scope === 'global' ? 'global' : 'project';
383
409
  this.mode = 'browse';
384
410
  this.editingServerName = null;
385
- this.status = `MCP removal blocked here. Run: /mcp remove ${name} --scope ${scope} --yes`;
386
- this.context.renderRequest();
411
+ await this.dispatchMcpCommand(['remove', name, '--scope', scope, '--yes'], `MCP server ${name} removal`);
387
412
  }
388
413
 
389
414
  cancelForm(): void {
@@ -392,6 +417,35 @@ export class McpWorkspace {
392
417
  this.status = 'Returned to MCP server browser.';
393
418
  }
394
419
 
420
+ private async dispatchMcpCommand(args: readonly string[], summary: string): Promise<void> {
421
+ const context = this.context;
422
+ if (!context?.executeCommand) {
423
+ this.status = `${summary} blocked: command dispatch is unavailable in this workspace.`;
424
+ this.lastError = 'Command dispatch is unavailable.';
425
+ context?.renderRequest();
426
+ return;
427
+ }
428
+ this.status = `${summary} dispatched from MCP workspace.`;
429
+ this.lastError = null;
430
+ context.renderRequest();
431
+ try {
432
+ const handled = await context.executeCommand('mcp', [...args]);
433
+ if (!handled) {
434
+ this.status = `${summary} failed: the command router did not handle /mcp.`;
435
+ this.lastError = 'Command router did not handle /mcp.';
436
+ context.renderRequest();
437
+ return;
438
+ }
439
+ this.refreshSnapshot();
440
+ this.status = `${summary} completed through MCP workspace.`;
441
+ } catch (error) {
442
+ this.lastError = summarizeError(error);
443
+ this.status = `${summary} failed: ${this.lastError}`;
444
+ } finally {
445
+ context.renderRequest();
446
+ }
447
+ }
448
+
395
449
  moveSelection(delta: number): void {
396
450
  const total = this.mode === 'form' ? this.formFields.length : this.rows.length;
397
451
  if (total <= 0) return;
@@ -413,6 +467,11 @@ export class McpWorkspace {
413
467
  await this.confirmDelete();
414
468
  return;
415
469
  }
470
+ if (this.mode === 'reload-confirm') {
471
+ this.mode = 'browse';
472
+ await this.reloadRuntime();
473
+ return;
474
+ }
416
475
  const row = this.selectedRow;
417
476
  if (!row) return;
418
477
  if (row.type === 'server') {
@@ -420,7 +479,7 @@ export class McpWorkspace {
420
479
  return;
421
480
  }
422
481
  if (row.id === 'add') this.openAddForm();
423
- else if (row.id === 'reload') await this.reloadRuntime();
482
+ else if (row.id === 'reload') this.requestReload();
424
483
  else if (row.id === 'refresh-tools') await this.refreshTools();
425
484
  else if (row.id === 'config') {
426
485
  this.status = [
@@ -478,12 +537,17 @@ export function handleMcpWorkspaceToken(
478
537
  } else if (workspace.mode === 'delete-confirm') {
479
538
  if (token.value.toLowerCase() === 'y') void workspace.confirmDelete();
480
539
  else if (token.value.toLowerCase() === 'n') workspace.cancelForm();
540
+ } else if (workspace.mode === 'reload-confirm') {
541
+ if (token.value.toLowerCase() === 'y') {
542
+ workspace.mode = 'browse';
543
+ void workspace.reloadRuntime();
544
+ } else if (token.value.toLowerCase() === 'n') workspace.cancelForm();
481
545
  } else {
482
546
  const value = token.value.toLowerCase();
483
547
  if (value === 'a') workspace.openAddForm();
484
548
  else if (value === 'e' && workspace.selectedServer) workspace.openEditForm(workspace.selectedServer.name);
485
549
  else if (value === 'd' && workspace.selectedServer) workspace.requestDelete(workspace.selectedServer.name);
486
- else if (value === 'r') void workspace.reloadRuntime();
550
+ else if (value === 'r') workspace.requestReload();
487
551
  else if (value === 't') void workspace.refreshTools();
488
552
  }
489
553
  requestRender();
@@ -492,7 +556,7 @@ export function handleMcpWorkspaceToken(
492
556
 
493
557
  if (token.type !== 'key') return true;
494
558
  if (token.logicalName === 'escape') {
495
- if (workspace.mode === 'form' || workspace.mode === 'delete-confirm') {
559
+ if (workspace.mode === 'form' || workspace.mode === 'delete-confirm' || workspace.mode === 'reload-confirm') {
496
560
  workspace.cancelForm();
497
561
  requestRender();
498
562
  } else {
@@ -520,7 +584,7 @@ export function handleMcpWorkspaceToken(
520
584
  } else if (token.logicalName === 'd' && workspace.mode === 'browse' && workspace.selectedServer) {
521
585
  workspace.requestDelete(workspace.selectedServer.name);
522
586
  } else if (token.logicalName === 'r' && workspace.mode === 'browse') {
523
- void workspace.reloadRuntime();
587
+ workspace.requestReload();
524
588
  } else if (token.logicalName === 't' && workspace.mode === 'browse') {
525
589
  void workspace.refreshTools();
526
590
  }
@@ -62,7 +62,9 @@ export function handleOnboardingWizardToken(state: OnboardingRouteState, token:
62
62
  }
63
63
 
64
64
  if (editing) {
65
- if (isEnterKey(token)) {
65
+ if (token.ctrl && (token.logicalName === 'j' || isEnterKey(token))) {
66
+ state.onboardingWizard.editNewline();
67
+ } else if (isEnterKey(token)) {
66
68
  state.onboardingWizard.commitEdit();
67
69
  } else if ((token.ctrl && token.logicalName === 'u') || token.logicalName === 'delete') {
68
70
  state.onboardingWizard.clearEditingValue();
@@ -21,6 +21,58 @@ export function buildOnboardingApplyRequest(controller: OnboardingWizardControll
21
21
  medium,
22
22
  });
23
23
  };
24
+ const readText = (fieldId: string): string => controller.getStringFieldValue(fieldId, '').trim();
25
+ const readList = (fieldId: string): readonly string[] => readText(fieldId).split(',').map((entry) => entry.trim()).filter(Boolean);
26
+ const maybeCreateLocalNote = (): void => {
27
+ const title = readText('agent-local-state.note-title');
28
+ const body = readText('agent-local-state.note-body');
29
+ if (!title && !body) return;
30
+ operations.push({
31
+ kind: 'create-local-note',
32
+ title,
33
+ body,
34
+ tags: readList('agent-local-state.note-tags'),
35
+ });
36
+ };
37
+ const maybeCreateLocalPersona = (): void => {
38
+ const name = readText('agent-local-state.persona-name');
39
+ const description = readText('agent-local-state.persona-description');
40
+ const body = readText('agent-local-state.persona-body');
41
+ if (!name && !description && !body) return;
42
+ operations.push({
43
+ kind: 'create-local-persona',
44
+ name,
45
+ description,
46
+ body,
47
+ activate: true,
48
+ });
49
+ };
50
+ const maybeCreateLocalSkill = (): void => {
51
+ const name = readText('agent-local-state.skill-name');
52
+ const description = readText('agent-local-state.skill-description');
53
+ const procedure = readText('agent-local-state.skill-procedure');
54
+ if (!name && !description && !procedure) return;
55
+ operations.push({
56
+ kind: 'create-local-skill',
57
+ name,
58
+ description,
59
+ procedure,
60
+ enabled: true,
61
+ });
62
+ };
63
+ const maybeCreateLocalRoutine = (): void => {
64
+ const name = readText('agent-local-state.routine-name');
65
+ const description = readText('agent-local-state.routine-description');
66
+ const steps = readText('agent-local-state.routine-steps');
67
+ if (!name && !description && !steps) return;
68
+ operations.push({
69
+ kind: 'create-local-routine',
70
+ name,
71
+ description,
72
+ steps,
73
+ enabled: true,
74
+ });
75
+ };
24
76
 
25
77
  // GoodVibes Agent onboarding owns only Agent-local setup and provider
26
78
  // routing. Server lifecycle, non-Agent entrypoints, and non-Agent knowledge
@@ -46,7 +98,17 @@ export function buildOnboardingApplyRequest(controller: OnboardingWizardControll
46
98
  name: profileName,
47
99
  ...(selectedTemplate.length > 0 && selectedTemplate !== 'none' ? { templateId: selectedTemplate } : {}),
48
100
  });
101
+ if (controller.getBooleanFieldValue('agent-setup.profile-default', true)) {
102
+ operations.push({
103
+ kind: 'select-agent-profile',
104
+ name: profileName,
105
+ });
106
+ }
49
107
  }
108
+ maybeCreateLocalNote();
109
+ maybeCreateLocalPersona();
110
+ maybeCreateLocalSkill();
111
+ maybeCreateLocalRoutine();
50
112
 
51
113
  return {
52
114
  mode: controller.mode,
@@ -6,6 +6,7 @@ export const STEP_ORDER: readonly OnboardingWizardStepId[] = [
6
6
  'default-model',
7
7
  'agent-communication',
8
8
  'agent-tools',
9
+ 'agent-research',
9
10
  'agent-knowledge',
10
11
  'agent-local-state',
11
12
  'agent-automation',
@@ -49,7 +49,7 @@ export function buildDefaultDerivedState(): OnboardingStepDerivationState {
49
49
  required: false,
50
50
  accepted: false,
51
51
  reason: 'not-needed',
52
- detail: 'No connected-service auth signal needs confirmation.',
52
+ detail: 'No connected-host auth signal needs confirmation.',
53
53
  },
54
54
  },
55
55
  };