@pellux/goodvibes-agent 0.1.117 → 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 (253) hide show
  1. package/CHANGELOG.md +13 -4
  2. package/README.md +35 -14
  3. package/bin/goodvibes-agent.ts +16 -2
  4. package/dist/package/main.js +176073 -170980
  5. package/docs/README.md +11 -5
  6. package/docs/channels-remote-and-api.md +50 -0
  7. package/docs/connected-host.md +3 -3
  8. package/docs/getting-started.md +29 -15
  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 +44 -9
  13. package/docs/tools-and-commands.md +123 -0
  14. package/docs/voice-and-live-tts.md +51 -0
  15. package/package.json +2 -5
  16. package/src/agent/channel-delivery.ts +201 -0
  17. package/src/agent/media-generation.ts +159 -0
  18. package/src/agent/memory-prompt.ts +0 -1
  19. package/src/agent/note-registry.ts +329 -0
  20. package/src/agent/operator-actions.ts +343 -0
  21. package/src/agent/persona-registry.ts +15 -14
  22. package/src/agent/record-labels.ts +107 -0
  23. package/src/agent/reminder-schedule-format.ts +33 -24
  24. package/src/agent/reminder-schedule.ts +26 -25
  25. package/src/agent/routine-registry.ts +13 -12
  26. package/src/agent/routine-schedule-args.ts +2 -1
  27. package/src/agent/routine-schedule-format.ts +77 -53
  28. package/src/agent/routine-schedule-promotion.ts +34 -32
  29. package/src/agent/routine-schedule-receipts.ts +28 -26
  30. package/src/agent/runtime-profile-starters.ts +2 -2
  31. package/src/agent/runtime-profile.ts +18 -17
  32. package/src/agent/skill-registry.ts +25 -24
  33. package/src/cli/agent-knowledge-args.ts +5 -1
  34. package/src/cli/agent-knowledge-command.ts +39 -33
  35. package/src/cli/agent-knowledge-format.ts +80 -67
  36. package/src/cli/agent-knowledge-methods.ts +1 -1
  37. package/src/cli/agent-knowledge-runtime.ts +32 -26
  38. package/src/cli/bundle-command.ts +13 -8
  39. package/src/cli/config-overrides.ts +37 -36
  40. package/src/cli/external-runtime.ts +10 -4
  41. package/src/cli/help.ts +29 -11
  42. package/src/cli/local-library-command.ts +134 -68
  43. package/src/cli/management-commands.ts +98 -62
  44. package/src/cli/management.ts +52 -26
  45. package/src/cli/memory-command.ts +66 -32
  46. package/src/cli/parser.ts +37 -24
  47. package/src/cli/profiles-command.ts +52 -35
  48. package/src/cli/provider-auth-routes.ts +2 -1
  49. package/src/cli/routines-command.ts +44 -36
  50. package/src/cli/service-posture.ts +6 -6
  51. package/src/cli/status.ts +46 -121
  52. package/src/core/conversation-message-snapshot.ts +131 -0
  53. package/src/input/agent-workspace-activation.ts +33 -7
  54. package/src/input/agent-workspace-basic-command-editor-submission.ts +7 -3
  55. package/src/input/agent-workspace-basic-command-editors.ts +30 -10
  56. package/src/input/agent-workspace-categories.ts +276 -64
  57. package/src/input/agent-workspace-channel-command-editor-submission.ts +34 -0
  58. package/src/input/agent-workspace-channel-command-editors.ts +23 -5
  59. package/src/input/agent-workspace-channels.ts +35 -2
  60. package/src/input/agent-workspace-command-editor.ts +18 -2
  61. package/src/input/agent-workspace-config-reader.ts +16 -0
  62. package/src/input/agent-workspace-delegation-editor-submission.ts +1 -1
  63. package/src/input/agent-workspace-editors.ts +140 -2
  64. package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
  65. package/src/input/agent-workspace-learned-behavior.ts +2 -2
  66. package/src/input/agent-workspace-library-command-editor-submission.ts +1 -1
  67. package/src/input/agent-workspace-library-command-editors.ts +2 -2
  68. package/src/input/agent-workspace-local-operations.ts +218 -0
  69. package/src/input/agent-workspace-local-selection.ts +75 -0
  70. package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
  71. package/src/input/agent-workspace-media-command-editors.ts +27 -0
  72. package/src/input/agent-workspace-memory-command-editors.ts +1 -1
  73. package/src/input/agent-workspace-memory-editor.ts +2 -2
  74. package/src/input/agent-workspace-navigation.ts +38 -2
  75. package/src/input/agent-workspace-notify-editor-submission.ts +16 -2
  76. package/src/input/agent-workspace-operations-command-editor-submission.ts +63 -1
  77. package/src/input/agent-workspace-operations-command-editors.ts +80 -3
  78. package/src/input/agent-workspace-panel-route.ts +43 -0
  79. package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
  80. package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
  81. package/src/input/agent-workspace-search.ts +169 -0
  82. package/src/input/agent-workspace-setup.ts +22 -11
  83. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +6 -6
  84. package/src/input/agent-workspace-skill-bundle-command-editors.ts +10 -10
  85. package/src/input/agent-workspace-snapshot.ts +112 -13
  86. package/src/input/agent-workspace-task-command-editors.ts +4 -4
  87. package/src/input/agent-workspace-token.ts +18 -2
  88. package/src/input/agent-workspace-types.ts +92 -4
  89. package/src/input/agent-workspace-voice-media.ts +3 -6
  90. package/src/input/agent-workspace-web-research-editor.ts +104 -0
  91. package/src/input/agent-workspace.ts +136 -208
  92. package/src/input/command-registry.ts +4 -1
  93. package/src/input/commands/agent-runtime-profile-runtime.ts +45 -41
  94. package/src/input/commands/agent-skills-runtime.ts +83 -70
  95. package/src/input/commands/agent-workspace-runtime.ts +23 -7
  96. package/src/input/commands/brief-runtime.ts +25 -24
  97. package/src/input/commands/channels-runtime.ts +145 -31
  98. package/src/input/commands/delegation-runtime.ts +29 -23
  99. package/src/input/commands/experience-runtime.ts +6 -4
  100. package/src/input/commands/guidance-runtime.ts +4 -4
  101. package/src/input/commands/health-runtime.ts +140 -115
  102. package/src/input/commands/knowledge.ts +57 -56
  103. package/src/input/commands/local-provider-runtime.ts +36 -18
  104. package/src/input/commands/local-runtime.ts +138 -16
  105. package/src/input/commands/local-setup-review.ts +7 -7
  106. package/src/input/commands/mcp-runtime.ts +56 -35
  107. package/src/input/commands/notify-runtime.ts +38 -9
  108. package/src/input/commands/operator-actions-runtime.ts +138 -0
  109. package/src/input/commands/operator-runtime.ts +6 -17
  110. package/src/input/commands/personas-runtime.ts +45 -30
  111. package/src/input/commands/planning-runtime.ts +1 -1
  112. package/src/input/commands/platform-access-runtime.ts +29 -29
  113. package/src/input/commands/provider-accounts-runtime.ts +60 -39
  114. package/src/input/commands/qrcode-runtime.ts +45 -6
  115. package/src/input/commands/recall-bundle.ts +11 -11
  116. package/src/input/commands/recall-capture.ts +13 -11
  117. package/src/input/commands/recall-query.ts +29 -21
  118. package/src/input/commands/recall-review.ts +2 -1
  119. package/src/input/commands/routines-runtime.ts +59 -43
  120. package/src/input/commands/schedule-runtime.ts +33 -20
  121. package/src/input/commands/security-runtime.ts +4 -4
  122. package/src/input/commands/session-content.ts +80 -78
  123. package/src/input/commands/session-workflow.ts +132 -93
  124. package/src/input/commands/session.ts +3 -174
  125. package/src/input/commands/shell-core.ts +32 -17
  126. package/src/input/commands/subscription-runtime.ts +53 -179
  127. package/src/input/commands/tasks-runtime.ts +20 -20
  128. package/src/input/commands/work-plan-runtime.ts +33 -8
  129. package/src/input/commands.ts +2 -2
  130. package/src/input/feed-context-factory.ts +2 -1
  131. package/src/input/file-picker.ts +3 -2
  132. package/src/input/handler-command-route.ts +4 -7
  133. package/src/input/handler-content-actions.ts +89 -1
  134. package/src/input/handler-feed-routes.ts +19 -12
  135. package/src/input/handler-feed.ts +6 -3
  136. package/src/input/handler-interactions.ts +7 -5
  137. package/src/input/handler-modal-stack.ts +3 -3
  138. package/src/input/handler-onboarding.ts +24 -80
  139. package/src/input/handler-shortcuts.ts +15 -4
  140. package/src/input/handler.ts +47 -17
  141. package/src/input/input-history.ts +5 -6
  142. package/src/input/keybindings.ts +22 -11
  143. package/src/input/onboarding/onboarding-wizard-apply.ts +13 -0
  144. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
  145. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +147 -57
  146. package/src/input/onboarding/onboarding-wizard-steps.ts +46 -29
  147. package/src/input/onboarding/onboarding-wizard-types.ts +3 -1
  148. package/src/input/onboarding/onboarding-wizard.ts +68 -0
  149. package/src/input/profile-picker-modal.ts +31 -12
  150. package/src/input/session-picker-modal.ts +21 -4
  151. package/src/input/settings-modal-behavior.ts +0 -3
  152. package/src/input/settings-modal-subscriptions.ts +3 -3
  153. package/src/input/settings-modal-types.ts +2 -13
  154. package/src/input/settings-modal.ts +6 -52
  155. package/src/input/submission-intent.ts +0 -1
  156. package/src/input/submission-router.ts +3 -3
  157. package/src/main.ts +18 -8
  158. package/src/panels/approval-panel.ts +8 -8
  159. package/src/panels/automation-control-panel.ts +2 -2
  160. package/src/panels/base-panel.ts +1 -1
  161. package/src/panels/builtin/agent.ts +1 -1
  162. package/src/panels/builtin/operations.ts +1 -10
  163. package/src/panels/builtin/session.ts +9 -9
  164. package/src/panels/builtin/shared.ts +2 -2
  165. package/src/panels/cost-tracker-panel.ts +1 -1
  166. package/src/panels/docs-panel.ts +5 -3
  167. package/src/panels/index.ts +0 -1
  168. package/src/panels/knowledge-panel.ts +6 -5
  169. package/src/panels/memory-panel.ts +7 -6
  170. package/src/panels/panel-list-panel.ts +36 -80
  171. package/src/panels/project-planning-panel.ts +18 -11
  172. package/src/panels/provider-account-snapshot.ts +51 -25
  173. package/src/panels/provider-accounts-panel.ts +33 -18
  174. package/src/panels/provider-health-domains.ts +45 -4
  175. package/src/panels/provider-health-panel.ts +5 -4
  176. package/src/panels/qr-panel.ts +1 -1
  177. package/src/panels/schedule-panel.ts +9 -17
  178. package/src/panels/security-panel.ts +8 -8
  179. package/src/panels/session-browser-panel.ts +10 -10
  180. package/src/panels/subscription-panel.ts +3 -3
  181. package/src/panels/system-messages-panel.ts +1 -1
  182. package/src/panels/tasks-panel.ts +20 -13
  183. package/src/panels/tool-inspector-panel.ts +19 -12
  184. package/src/panels/work-plan-panel.ts +5 -5
  185. package/src/planning/project-planning-coordinator.ts +1 -1
  186. package/src/provider-auth-route-display.ts +9 -0
  187. package/src/renderer/agent-workspace-style.ts +34 -0
  188. package/src/renderer/agent-workspace.ts +228 -52
  189. package/src/renderer/autocomplete-overlay.ts +25 -6
  190. package/src/renderer/bookmark-modal.ts +19 -4
  191. package/src/renderer/buffer.ts +4 -2
  192. package/src/renderer/context-inspector.ts +50 -13
  193. package/src/renderer/diff.ts +1 -1
  194. package/src/renderer/file-picker-overlay.ts +19 -6
  195. package/src/renderer/help-overlay.ts +106 -33
  196. package/src/renderer/history-search-overlay.ts +19 -4
  197. package/src/renderer/live-tail-modal.ts +27 -5
  198. package/src/renderer/mcp-workspace.ts +164 -50
  199. package/src/renderer/model-picker-overlay.ts +58 -2
  200. package/src/renderer/model-workspace.ts +104 -20
  201. package/src/renderer/process-modal.ts +27 -6
  202. package/src/renderer/profile-picker-modal.ts +20 -4
  203. package/src/renderer/search-overlay.ts +25 -5
  204. package/src/renderer/selection-modal-overlay.ts +46 -14
  205. package/src/renderer/session-picker-modal.ts +18 -1
  206. package/src/renderer/settings-modal-helpers.ts +2 -40
  207. package/src/renderer/settings-modal.ts +83 -50
  208. package/src/renderer/tool-call.ts +20 -11
  209. package/src/runtime/agent-runtime-events.ts +6 -6
  210. package/src/runtime/bootstrap-command-context.ts +7 -1
  211. package/src/runtime/bootstrap-command-parts.ts +9 -7
  212. package/src/runtime/bootstrap-core.ts +19 -1
  213. package/src/runtime/bootstrap-hook-bridge.ts +7 -18
  214. package/src/runtime/bootstrap-shell.ts +4 -4
  215. package/src/runtime/bootstrap.ts +31 -22
  216. package/src/runtime/connected-host-auth.ts +7 -2
  217. package/src/runtime/diagnostics/panels/index.ts +2 -2
  218. package/src/runtime/diagnostics/panels/policy.ts +7 -7
  219. package/src/runtime/index.ts +2 -1
  220. package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
  221. package/src/runtime/onboarding/apply.ts +80 -79
  222. package/src/runtime/onboarding/derivation.ts +5 -8
  223. package/src/runtime/onboarding/snapshot.ts +0 -15
  224. package/src/runtime/onboarding/types.ts +8 -19
  225. package/src/runtime/onboarding/verify.ts +32 -10
  226. package/src/runtime/operator-token-cleanup.ts +1 -1
  227. package/src/runtime/services.ts +91 -22
  228. package/src/runtime/store/selectors/index.ts +3 -3
  229. package/src/runtime/store/state.ts +1 -4
  230. package/src/runtime/surface-feature-flags.ts +41 -6
  231. package/src/runtime/ui-read-models.ts +3 -4
  232. package/src/runtime/ui-services.ts +6 -6
  233. package/src/shell/blocking-input.ts +2 -1
  234. package/src/shell/ui-openers.ts +3 -13
  235. package/src/tools/agent-analysis-registry-policy.ts +0 -1
  236. package/src/tools/agent-channel-send-tool.ts +133 -0
  237. package/src/tools/agent-context-policy.ts +1 -1
  238. package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
  239. package/src/tools/agent-knowledge-tool.ts +170 -0
  240. package/src/tools/agent-local-registry-tool.ts +269 -69
  241. package/src/tools/agent-media-generate-tool.ts +133 -0
  242. package/src/tools/agent-notify-tool.ts +143 -0
  243. package/src/tools/agent-operator-action-tool.ts +137 -0
  244. package/src/tools/agent-operator-briefing-tool.ts +217 -0
  245. package/src/tools/agent-reminder-schedule-tool.ts +237 -0
  246. package/src/tools/agent-tool-policy-guard.ts +8 -8
  247. package/src/tools/agent-work-plan-tool.ts +256 -0
  248. package/src/version.ts +1 -1
  249. package/src/input/commands/policy-dispatch.ts +0 -339
  250. package/src/input/commands/policy.ts +0 -13
  251. package/src/panels/panel-picker.ts +0 -105
  252. package/src/panels/policy-panel.ts +0 -308
  253. package/src/renderer/panel-picker-overlay.ts +0 -202
@@ -1,11 +1,19 @@
1
1
  import { REASONING_OPTIONS, HITL_MODE_OPTIONS, GUIDANCE_MODE_OPTIONS, PERMISSION_MODE_OPTIONS, SECRET_POLICY_OPTIONS } from './onboarding-wizard-constants.ts';
2
2
  import { modelSelectionLabel, normalizeText } from './onboarding-wizard-helpers.ts';
3
- import { buildAgentKnowledgeStep, buildAutomationStep, buildCommunicationStep, buildDelegationPolicyStep, buildLocalStateStep, buildToolsStep, buildVoiceMediaStep } from './onboarding-wizard-operator-steps.ts';
3
+ import { buildAgentKnowledgeStep, buildAutomationStep, buildCommunicationStep, buildDelegationPolicyStep, buildLocalStateStep, buildResearchStep, buildToolsStep, buildVoiceMediaStep } from './onboarding-wizard-operator-steps.ts';
4
4
  import { listAgentRuntimeProfileTemplates } from '../../agent/runtime-profile.ts';
5
5
  import type { OnboardingWizardController } from './onboarding-wizard.ts';
6
6
  import type { OnboardingWizardActionFieldDefinition, OnboardingWizardFieldDefinition, OnboardingWizardModelPickerFieldDefinition, OnboardingWizardRadioFieldDefinition, OnboardingWizardRadioOption, OnboardingWizardStepDefinition } from './onboarding-wizard-types.ts';
7
7
  import type { OnboardingProviderAccountRecord, OnboardingStep1CapabilityId, OnboardingStep1CapabilityItem } from '../../runtime/onboarding/index.ts';
8
8
 
9
+ const DEFAULT_STARTER_TEMPLATE_ID = 'personal-productivity';
10
+
11
+ function defaultStarterTemplateId(): string {
12
+ const templates = listAgentRuntimeProfileTemplates();
13
+ if (templates.some((template) => template.id === DEFAULT_STARTER_TEMPLATE_ID)) return DEFAULT_STARTER_TEMPLATE_ID;
14
+ return templates[0]?.id ?? 'none';
15
+ }
16
+
9
17
  function buildStarterTemplateOptions(): readonly OnboardingWizardRadioOption[] {
10
18
  return [
11
19
  {
@@ -30,6 +38,7 @@ export function buildOnboardingWizardSteps(controller: OnboardingWizardControlle
30
38
  buildDefaultModelStep(controller),
31
39
  buildCommunicationStep(),
32
40
  buildToolsStep(),
41
+ buildResearchStep(),
33
42
  buildAgentKnowledgeStep(),
34
43
  buildLocalStateStep(controller.runtimeSnapshot?.localBehaviorDiscovery),
35
44
  buildAutomationStep(),
@@ -139,14 +148,21 @@ function buildReviewReadinessFields(controller: OnboardingWizardController): rea
139
148
  kind: 'status',
140
149
  id: 'review.readiness.knowledge',
141
150
  label: 'Agent Knowledge segment',
142
- hint: 'Ask, search, status, and ingest stay on /api/goodvibes-agent/knowledge/* with no default wiki or non-Agent fallback.',
151
+ hint: 'Ask, search, status, and ingest stay on /api/goodvibes-agent/knowledge/* with no default knowledge or non-Agent fallback.',
143
152
  defaultValue: 'Isolated',
144
153
  },
154
+ {
155
+ kind: 'status',
156
+ id: 'review.readiness.research',
157
+ label: 'Research and source triage',
158
+ hint: 'Web research and URL inspection stay in the main conversation; durable source storage requires explicit Agent Knowledge ingest.',
159
+ defaultValue: 'Read-only',
160
+ },
145
161
  {
146
162
  kind: 'status',
147
163
  id: 'review.readiness.local-behavior',
148
164
  label: 'Local behavior library',
149
- hint: localBehavior?.detail ?? 'Agent-local memory, routines, skills, and personas remain local until a stable shared registry exists.',
165
+ hint: localBehavior?.detail ?? 'Agent-local memory, notes, routines, skills, and personas remain local until a stable shared registry exists.',
150
166
  defaultValue: localBehavior?.selected ? 'Customized' : 'Starter ready',
151
167
  },
152
168
  {
@@ -206,13 +222,13 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
206
222
  id: 'agent-setup',
207
223
  title: 'Agent setup',
208
224
  shortLabel: 'Agent',
209
- description: 'Set up the Agent operator workspace: local identity, provider access, isolated Agent Knowledge, reusable local behavior, and explicit build delegation.',
225
+ description: 'Set up the Agent operator workspace with local identity, provider access, isolated Agent Knowledge, reusable local behavior, and explicit build delegation.',
210
226
  summaryTitle: 'Agent setup posture',
211
227
  summaryLines: [
212
228
  'Agent owns the operator TUI and local behavior registry.',
213
229
  'Optional starter profile: create an isolated Agent home from setup.',
214
230
  'Setup here changes only Agent-owned settings and local state.',
215
- `Secret policy: ${controller.getStringFieldValue('agent-setup.secret-policy', secretPolicy)}`,
231
+ `Secret policy ${controller.getStringFieldValue('agent-setup.secret-policy', secretPolicy)}`,
216
232
  collectionIssues > 0 ? `${collectionIssues} setup snapshot issue(s)` : 'Setup snapshot collected cleanly',
217
233
  ],
218
234
  fields: [
@@ -244,7 +260,7 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
244
260
  kind: 'text',
245
261
  id: 'agent-setup.profile-name',
246
262
  label: 'Create starter profile',
247
- hint: 'Optional: enter a new Agent profile name to create an isolated home during setup. Leave blank to keep the current home.',
263
+ hint: 'Optional Agent profile name creates an isolated home during setup. Leave blank to keep the current home.',
248
264
  placeholder: 'research-desk',
249
265
  defaultValue: '',
250
266
  },
@@ -252,23 +268,24 @@ export function buildAgentSetupStep(controller: OnboardingWizardController): Onb
252
268
  kind: 'radio',
253
269
  id: 'agent-setup.profile-template',
254
270
  label: 'Starter profile template',
255
- hint: 'Choose the persona, skills, and routine bundle to seed into the optional new Agent profile.',
271
+ hint: 'Choose the persona, skills, and routine bundle to seed into the optional new Agent profile. Select No profile only when you intentionally want an empty Agent home.',
256
272
  options: buildStarterTemplateOptions(),
257
- defaultValue: 'none',
273
+ defaultValue: defaultStarterTemplateId(),
258
274
  },
259
275
  {
260
276
  kind: 'checklist',
261
277
  id: 'agent-setup.profile-default',
262
278
  label: 'Use created profile by default',
263
- hint: 'When a starter profile name is provided, make that isolated Agent profile the default for future plain goodvibes-agent launches.',
279
+ hint: 'When a starter profile name is provided, make that isolated Agent profile the default for later plain goodvibes-agent runs.',
264
280
  defaultValue: true,
265
281
  },
266
282
  {
267
- kind: 'status',
283
+ kind: 'action',
268
284
  id: 'agent-setup.profile-guide',
285
+ action: 'open-agent-workspace:profiles',
269
286
  label: 'Profile guidance',
270
- hint: 'Use /agent-profile guide after setup to export, customize, import, and launch Agent profiles.',
271
- defaultValue: 'Available',
287
+ hint: 'Open the Profiles workspace to browse starters, export, customize, import, create, and select isolated Agent profiles.',
288
+ defaultValue: 'Open Profiles',
272
289
  },
273
290
  ],
274
291
  };
@@ -313,8 +330,8 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
313
330
  id: 'providers.subscription-sessions',
314
331
  label: 'Subscription sessions',
315
332
  hint: [
316
- `active: ${formatBoundedList(activeSubscriptionProviders, 'none')}`,
317
- `pending: ${formatBoundedList(pendingSubscriptionProviders, 'none')}`,
333
+ `active ${formatBoundedList(activeSubscriptionProviders, 'none')}`,
334
+ `pending ${formatBoundedList(pendingSubscriptionProviders, 'none')}`,
318
335
  ].join(' '),
319
336
  defaultValue: `${activeSubscriptions.length} active / ${pendingSubscriptions.length} pending`,
320
337
  },
@@ -330,8 +347,8 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
330
347
  id: 'providers.openai-api-key',
331
348
  label: 'OpenAI API key quick start',
332
349
  hint: openAiApiKeyConfigured
333
- ? 'Optional quick start: an OpenAI API key is already stored. Leave blank to keep it; enter a new key to replace it through the secret manager.'
334
- : 'Optional quick start: enter an OpenAI API key now. Other providers can be configured from /secrets, /provider, and the model picker.',
350
+ ? 'Optional quick start already has an OpenAI API key stored. Leave blank to keep it; enter a new key to replace it through the secret manager.'
351
+ : 'Optional quick start can store an OpenAI API key now. Other providers can be configured from the Setup workspace, Tools & MCP workspace, and model picker.',
335
352
  placeholder: openAiApiKeyConfigured ? 'already configured' : 'sk-...',
336
353
  defaultValue: '',
337
354
  },
@@ -380,10 +397,10 @@ export function buildProviderAccessStep(controller: OnboardingWizardController):
380
397
  description: 'Review provider and model access for the Agent conversation. Credentials stay masked and provider-specific setup remains configurable.',
381
398
  summaryTitle: 'Provider access summary',
382
399
  summaryLines: [
383
- `Default route: ${providerRouteLabel}`,
384
- `Provider account routes: ${configuredAccounts.length}`,
385
- `Subscription sessions: ${activeSubscriptions.length} active / ${pendingSubscriptions.length} pending`,
386
- `Provider credential references: ${providerSecretCount}`,
400
+ `Default route ${providerRouteLabel}`,
401
+ `Provider account routes ${configuredAccounts.length}`,
402
+ `Subscription sessions ${activeSubscriptions.length} active / ${pendingSubscriptions.length} pending`,
403
+ `Provider credential references ${providerSecretCount}`,
387
404
  ],
388
405
  fields,
389
406
  };
@@ -419,8 +436,8 @@ export function buildDefaultModelStep(controller: OnboardingWizardController): O
419
436
  description: 'Choose the default provider, model, and reasoning posture for normal Agent conversation.',
420
437
  summaryTitle: 'Default model summary',
421
438
  summaryLines: [
422
- `Main: ${modelSelectionLabel(controller.modelSelectionState.get('main') ?? primarySelectionField.defaultSelection)}`,
423
- `Reasoning: ${controller.getFieldValueLabel(reasoningField)}`,
439
+ `Main ${modelSelectionLabel(controller.modelSelectionState.get('main') ?? primarySelectionField.defaultSelection)}`,
440
+ `Reasoning ${controller.getFieldValueLabel(reasoningField)}`,
424
441
  ],
425
442
  fields: [primarySelectionField, reasoningField],
426
443
  };
@@ -434,9 +451,9 @@ export function buildExperienceStep(controller: OnboardingWizardController): Onb
434
451
  description: 'Tune the Agent conversation style and approval posture for day-to-day operator use.',
435
452
  summaryTitle: 'Experience posture',
436
453
  summaryLines: [
437
- `Human-in-the-Loop (HITL): ${controller.getStringFieldValue('experience.hitl', controller.runtimeSnapshot?.runtimeDefaults.behavior.hitlMode ?? 'balanced')}`,
438
- `Guidance: ${controller.getStringFieldValue('experience.guidance', controller.runtimeSnapshot?.runtimeDefaults.behavior.guidanceMode ?? 'minimal')}`,
439
- `Permissions: ${controller.getStringFieldValue('experience.permissions', controller.runtimeSnapshot?.runtimeDefaults.permissionsMode ?? 'prompt')}`,
454
+ `Human-in-the-Loop (HITL) ${controller.getStringFieldValue('experience.hitl', controller.runtimeSnapshot?.runtimeDefaults.behavior.hitlMode ?? 'balanced')}`,
455
+ `Guidance ${controller.getStringFieldValue('experience.guidance', controller.runtimeSnapshot?.runtimeDefaults.behavior.guidanceMode ?? 'minimal')}`,
456
+ `Permissions ${controller.getStringFieldValue('experience.permissions', controller.runtimeSnapshot?.runtimeDefaults.permissionsMode ?? 'prompt')}`,
440
457
  ],
441
458
  fields: [
442
459
  {
@@ -500,11 +517,11 @@ export function buildReviewStep(controller: OnboardingWizardController): Onboard
500
517
  description: 'Review the Agent day-one checklist and apply setup directly from the wizard.',
501
518
  summaryTitle: 'Agent day-one readiness',
502
519
  summaryLines: [
503
- `Day-one readiness: ${dayOneReadiness}`,
520
+ `Day-one readiness ${dayOneReadiness}`,
504
521
  unsavedLabel,
505
522
  `${controller.buildApplyRequest().operations.length} Agent setting change(s) ready to apply`,
506
- feedback ? `Last apply: ${feedback.title}` : 'No apply errors reported',
507
- controller.isEditingTextField() ? `Editing: ${controller.editingFieldId}` : 'Ready to apply',
523
+ feedback ? `Last apply ${feedback.title}` : 'No apply errors reported',
524
+ controller.isEditingTextField() ? `Editing ${controller.editingFieldId}` : 'Ready to apply',
508
525
  ],
509
526
  fields: [
510
527
  ...feedbackFields,
@@ -521,7 +538,7 @@ export function buildReviewStep(controller: OnboardingWizardController): Onboard
521
538
  id: 'review.apply',
522
539
  action: 'apply',
523
540
  label: 'Apply Agent settings and verify',
524
- hint: 'Persist Agent-owned settings and verify that setup did not request non-Agent entrypoints, default wiki access, or non-Agent knowledge setup.',
541
+ hint: 'Persist Agent-owned settings and verify that setup did not request non-Agent entrypoints, default knowledge access, or non-Agent knowledge setup.',
525
542
  defaultValue: 'Ready',
526
543
  },
527
544
  ],
@@ -17,6 +17,7 @@ export type OnboardingWizardStepId =
17
17
  | 'agent-communication'
18
18
  | 'agent-tools'
19
19
  | 'agent-knowledge'
20
+ | 'agent-research'
20
21
  | 'agent-local-state'
21
22
  | 'agent-automation'
22
23
  | 'agent-voice-media'
@@ -40,7 +41,8 @@ export type OnboardingWizardAction =
40
41
  | 'apply'
41
42
  | 'apply-and-continue'
42
43
  | 'start-openai-subscription'
43
- | 'finish-openai-subscription';
44
+ | 'finish-openai-subscription'
45
+ | `open-agent-workspace:${string}`;
44
46
 
45
47
  export type OnboardingWizardApplyFeedbackSeverity = 'info' | 'warning' | 'error';
46
48
 
@@ -621,3 +621,71 @@ export class OnboardingWizardController {
621
621
  public isFieldDirtyByDefinition(field: OnboardingWizardFieldDefinition): boolean { return isFieldDirtyByDefinitionForController(this, field); }
622
622
  public isFieldSatisfied(field: OnboardingWizardFieldDefinition): boolean { return isFieldSatisfiedForController(this, field); }
623
623
  }
624
+
625
+ function pushOnboardingPackageText(lines: string[], ...values: readonly (string | undefined)[]): void {
626
+ for (const value of values) {
627
+ const normalized = normalizeText(value);
628
+ if (normalized.length > 0) lines.push(normalized);
629
+ }
630
+ }
631
+
632
+ function appendOnboardingFieldPackageText(
633
+ lines: string[],
634
+ wizard: OnboardingWizardController,
635
+ field: OnboardingWizardFieldDefinition,
636
+ ): void {
637
+ pushOnboardingPackageText(lines, field.kind, field.id, field.label, field.hint, wizard.getFieldValueLabel(field));
638
+
639
+ if (field.kind === 'text' || field.kind === 'masked') {
640
+ pushOnboardingPackageText(lines, field.placeholder, field.defaultValue);
641
+ return;
642
+ }
643
+
644
+ if (field.kind === 'radio') {
645
+ for (const option of field.options) {
646
+ pushOnboardingPackageText(lines, option.id, option.label, option.hint);
647
+ }
648
+ return;
649
+ }
650
+
651
+ if (field.kind === 'action') {
652
+ pushOnboardingPackageText(lines, field.action, field.defaultValue);
653
+ return;
654
+ }
655
+
656
+ if (field.kind === 'acknowledgement') {
657
+ pushOnboardingPackageText(lines, field.reason);
658
+ return;
659
+ }
660
+
661
+ if (field.kind === 'modelPicker') {
662
+ pushOnboardingPackageText(
663
+ lines,
664
+ field.target,
665
+ field.defaultSelection.providerId,
666
+ field.defaultSelection.modelId,
667
+ );
668
+ }
669
+ }
670
+
671
+ export function renderOnboardingWizardPackageText(): string {
672
+ const wizard = new OnboardingWizardController();
673
+ const lines: string[] = ['GoodVibes Agent onboarding wizard'];
674
+
675
+ for (const step of wizard.steps) {
676
+ pushOnboardingPackageText(
677
+ lines,
678
+ step.id,
679
+ step.shortLabel,
680
+ step.title,
681
+ step.description,
682
+ step.summaryTitle,
683
+ ...step.summaryLines,
684
+ );
685
+ for (const field of step.fields) {
686
+ appendOnboardingFieldPackageText(lines, wizard, field);
687
+ }
688
+ }
689
+
690
+ return lines.join('\n');
691
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ProfilePickerModal — state management for the /profiles picker modal.
2
+ * ProfilePickerModal — state management for the Agent profile picker modal.
3
3
  *
4
4
  * Lists profiles from ProfileManager.list(), tracks selected index,
5
5
  * and handles load actions.
@@ -24,20 +24,39 @@ const BEHAVIOR_KEYS: ConfigKey[] = [
24
24
  'behavior.saveHistory', 'behavior.notifyOnComplete',
25
25
  ] as const;
26
26
 
27
+ function configProfileDeletionDisabledMessage(name: string): string {
28
+ return `Config-profile deletion is disabled in Agent for ${name}. Open Agent Workspace -> Profiles for isolated Agent profile homes.`;
29
+ }
30
+
31
+ function configProfileSavingDisabledMessage(name: string): string {
32
+ return `Config-profile saving is disabled in Agent for ${name}. Open Agent Workspace -> Profiles to create isolated Agent homes.`;
33
+ }
34
+
35
+ export function renderProfilePickerStatePackageText(): string {
36
+ return [
37
+ 'Profile name cannot be empty',
38
+ 'Loaded profile',
39
+ 'Saved profile',
40
+ 'Error',
41
+ configProfileDeletionDisabledMessage('<profile>'),
42
+ configProfileSavingDisabledMessage('<profile>'),
43
+ ].join('\n');
44
+ }
45
+
27
46
  /**
28
47
  * Apply a profile data category to the config manager.
29
48
  * Iterates only known/valid keys rather than open-ended Object.entries.
30
49
  */
31
50
  function applyProfileCategory(
32
51
  cm: ConfigManager,
33
- data: Record<string, unknown>,
52
+ data: object,
34
53
  keys: ConfigKey[],
35
54
  ): void {
36
55
  for (const key of keys) {
37
56
  const field = key.split('.')[1];
38
- if (field && Object.prototype.hasOwnProperty.call(data, field)) {
57
+ if (field && Object.hasOwn(data, field)) {
39
58
  try {
40
- cm.setDynamic(key, data[field]);
59
+ cm.setDynamic(key, Reflect.get(data, field));
41
60
  } catch (e) { logger.debug('applyProfileCategory: key set failed', { key, error: summarizeError(e) }); }
42
61
  }
43
62
  }
@@ -114,7 +133,7 @@ export class ProfilePickerModal {
114
133
 
115
134
  // Apply display settings using validated key list
116
135
  if (data.display) {
117
- applyProfileCategory(configManager, data.display as Record<string, unknown>, DISPLAY_KEYS);
136
+ applyProfileCategory(configManager, data.display, DISPLAY_KEYS);
118
137
  }
119
138
 
120
139
  // Apply provider settings (model + reasoningEffort only)
@@ -129,14 +148,14 @@ export class ProfilePickerModal {
129
148
 
130
149
  // Apply behavior settings using validated key list
131
150
  if (data.behavior) {
132
- applyProfileCategory(configManager, data.behavior as Record<string, unknown>, BEHAVIOR_KEYS);
151
+ applyProfileCategory(configManager, data.behavior, BEHAVIOR_KEYS);
133
152
  }
134
153
 
135
154
  configManager.save();
136
- this.statusMessage = `Loaded profile: ${profile.name}`;
155
+ this.statusMessage = `Loaded profile ${profile.name}`;
137
156
  return true;
138
157
  } catch (e) {
139
- this.statusMessage = `Error: ${summarizeError(e)}`;
158
+ this.statusMessage = `Error ${summarizeError(e)}`;
140
159
  return false;
141
160
  }
142
161
  }
@@ -145,7 +164,7 @@ export class ProfilePickerModal {
145
164
  const profile = this.getSelected();
146
165
  if (!profile) return false;
147
166
  this.deleteConfirmationTarget = null;
148
- this.statusMessage = `Config-profile deletion is disabled in Agent for ${profile.name}. Use /agent profiles for isolated Agent profile homes.`;
167
+ this.statusMessage = configProfileDeletionDisabledMessage(profile.name);
149
168
  return false;
150
169
  }
151
170
 
@@ -158,7 +177,7 @@ export class ProfilePickerModal {
158
177
  return false;
159
178
  }
160
179
  void configManager;
161
- this.statusMessage = `Config-profile saving is disabled in Agent for ${name}. Use /agent profiles to create isolated Agent homes.`;
180
+ this.statusMessage = configProfileSavingDisabledMessage(name);
162
181
  return false;
163
182
  }
164
183
 
@@ -182,11 +201,11 @@ export class ProfilePickerModal {
182
201
 
183
202
  // Reload list
184
203
  this.profiles = this.profileManager.list();
185
- this.statusMessage = `Saved profile: ${name}`;
204
+ this.statusMessage = `Saved profile ${name}`;
186
205
  this._clampScroll();
187
206
  return true;
188
207
  } catch (e) {
189
- this.statusMessage = `Error: ${summarizeError(e)}`;
208
+ this.statusMessage = `Error ${summarizeError(e)}`;
190
209
  return false;
191
210
  }
192
211
  }
@@ -8,6 +8,23 @@
8
8
  import type { SessionInfo, SessionManager } from '@pellux/goodvibes-sdk/platform/sessions';
9
9
  import type { ConversationManager } from '../core/conversation';
10
10
  import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils';
11
+ import { readConversationMessageSnapshots } from '../core/conversation-message-snapshot.ts';
12
+
13
+ function sessionLoadedMessage(name: string, messageCount: number): string {
14
+ return `Loaded session ${name} (${messageCount} messages)`;
15
+ }
16
+
17
+ function sessionDeletionCommandRequiredMessage(name: string): string {
18
+ return `Deletion requires an explicit command: /session delete ${name} --yes`;
19
+ }
20
+
21
+ export function renderSessionPickerStatePackageText(): string {
22
+ return [
23
+ 'Loaded session <session> (<count> messages)',
24
+ 'Error',
25
+ sessionDeletionCommandRequiredMessage('<session>'),
26
+ ].join('\n');
27
+ }
11
28
 
12
29
  // ---------------------------------------------------------------------------
13
30
  // SessionPickerModal
@@ -78,13 +95,13 @@ export class SessionPickerModal {
78
95
  try {
79
96
  const { meta, messages } = this.sessionManager.load(session.name);
80
97
  conversationManager.resetAll();
81
- conversationManager.fromJSON({ messages: messages as never[] });
98
+ conversationManager.fromJSON({ messages: readConversationMessageSnapshots(messages) });
82
99
  if (meta.title) conversationManager.title = meta.title;
83
100
  conversationManager.rebuildHistory();
84
- this.statusMessage = `Loaded: ${session.name} (${messages.length} messages)`;
101
+ this.statusMessage = sessionLoadedMessage(session.name, messages.length);
85
102
  return true;
86
103
  } catch (e) {
87
- this.statusMessage = `Error: ${summarizeError(e)}`;
104
+ this.statusMessage = `Error ${summarizeError(e)}`;
88
105
  return false;
89
106
  }
90
107
  }
@@ -93,7 +110,7 @@ export class SessionPickerModal {
93
110
  const session = this.getSelected();
94
111
  if (!session) return false;
95
112
  this.deleteConfirmationTarget = null;
96
- this.statusMessage = `Deletion requires an explicit command: /session delete ${session.name} --yes`;
113
+ this.statusMessage = sessionDeletionCommandRequiredMessage(session.name);
97
114
  return false;
98
115
  }
99
116
 
@@ -30,8 +30,5 @@ export function getNumericAdjustmentMeta(setting: ConfigSetting): {
30
30
  max?: number;
31
31
  precision: number;
32
32
  } {
33
- if (setting.key === 'wrfc.scoreThreshold') {
34
- return { step: 0.1, min: 0, max: 10, precision: 1 };
35
- }
36
33
  return { step: 1, precision: 0 };
37
34
  }
@@ -23,7 +23,7 @@ export function buildSubscriptionEntries(
23
23
  activeRoute: 'unconfigured',
24
24
  authFreshness: 'unconfigured',
25
25
  routeReason: 'Built-in subscription adapter is available, but no active subscription session is stored yet.',
26
- nextActions: [`Open /agent setup and choose Start subscription login for ${provider}.`],
26
+ nextActions: [`Open Agent Workspace -> Setup -> Start subscription login for ${provider}.`],
27
27
  });
28
28
  }
29
29
 
@@ -38,7 +38,7 @@ export function buildSubscriptionEntries(
38
38
  activeRoute: providers.get(provider)?.activeRoute ?? 'unconfigured',
39
39
  authFreshness: providers.get(provider)?.authFreshness ?? 'unconfigured',
40
40
  routeReason: providers.get(provider)?.routeReason ?? 'OAuth metadata is configured for this provider.',
41
- nextActions: providers.get(provider)?.nextActions ?? [`Open /agent setup and choose Start subscription login for ${provider}.`],
41
+ nextActions: providers.get(provider)?.nextActions ?? [`Open Agent Workspace -> Setup -> Start subscription login for ${provider}.`],
42
42
  });
43
43
  }
44
44
 
@@ -51,7 +51,7 @@ export function buildSubscriptionEntries(
51
51
  activeRoute: 'unconfigured',
52
52
  authFreshness: 'pending',
53
53
  routeReason: 'OAuth login is pending completion for this provider.',
54
- nextActions: [`Open /agent setup and choose Finish subscription login for ${pending.provider}.`],
54
+ nextActions: [`Open Agent Workspace -> Setup -> Finish subscription login for ${pending.provider}.`],
55
55
  });
56
56
  }
57
57
 
@@ -27,27 +27,16 @@ export type SettingsCategory =
27
27
  | 'behavior'
28
28
  | 'storage'
29
29
  | 'permissions'
30
- | 'orchestration'
31
- | 'wrfc'
32
30
  | 'tools'
33
31
  | 'helper'
34
32
  | 'tts'
35
- | 'service'
36
- | 'controlPlane'
37
- | 'httpListener'
38
- | 'web'
39
- | 'network'
40
33
  | 'surfaces'
41
- | 'batch'
42
34
  | 'automation'
43
- | 'watchers'
44
- | 'runtime'
45
35
  | 'telemetry'
46
36
  | 'cache'
47
37
  | 'mcp'
48
38
  | 'flags'
49
- | 'release'
50
- | 'danger';
39
+ | 'release';
51
40
 
52
41
  export type SettingsFocusPane = 'categories' | 'settings';
53
42
 
@@ -57,7 +46,7 @@ export const SETTINGS_CATEGORY_GROUPS: ReadonlyArray<{
57
46
  }> = [
58
47
  { label: 'Agent Experience', categories: ['display', 'ui', 'behavior', 'permissions'] },
59
48
  { label: 'Models and Providers', categories: ['provider', 'subscriptions', 'helper', 'tools', 'tts'] },
60
- { label: 'Local Agent State', categories: ['storage', 'cache', 'telemetry'] },
49
+ { label: 'Agent-local state', categories: ['storage', 'cache', 'telemetry'] },
61
50
  { label: 'Channels and Tools', categories: ['surfaces', 'mcp', 'automation'] },
62
51
  { label: 'Advanced', categories: ['flags', 'release'] },
63
52
  ];
@@ -99,12 +99,6 @@ export class SettingsModal {
99
99
  /** Provider subscription entries (populated when subscriptions tab is active). */
100
100
  public subscriptionEntries: SubscriptionEntry[] = [];
101
101
 
102
- /**
103
- * Set after a network-category save that touches controlPlane or httpListener
104
- * config keys. Renderer reads this to display a transient restart notice.
105
- * Cleared on next open() or close().
106
- */
107
- public lastSaveTriggeredRestart: 'control-plane' | 'http-listener' | 'web' | null = null;
108
102
  public lastSettingEffectMessage: string | null = null;
109
103
 
110
104
  private configManager: ConfigManager | null = null;
@@ -151,7 +145,6 @@ export class SettingsModal {
151
145
  this.pendingSettingsPickerAction = null;
152
146
  this.mcpAllowAllConfirmationTarget = null;
153
147
  this.subscriptionLogoutConfirmationTarget = null;
154
- this.lastSaveTriggeredRestart = null;
155
148
  this.lastSettingEffectMessage = null;
156
149
  this.active = true;
157
150
  }
@@ -165,7 +158,6 @@ export class SettingsModal {
165
158
  this.pendingSettingsPickerAction = null;
166
159
  this.mcpAllowAllConfirmationTarget = null;
167
160
  this.subscriptionLogoutConfirmationTarget = null;
168
- this.lastSaveTriggeredRestart = null;
169
161
  this.lastSettingEffectMessage = null;
170
162
  this.serviceRegistry = null;
171
163
  this.secretsManager = null;
@@ -452,8 +444,9 @@ export class SettingsModal {
452
444
  /**
453
445
  * Toggle the currently selected feature flag.
454
446
  *
455
- * Killed flags cannot be toggled. Non-runtimeToggleable flags toggle in config
456
- * only (require restart). runtimeToggleable flags toggle immediately.
447
+ * Killed flags cannot be toggled. Non-runtimeToggleable flags are saved as
448
+ * overrides for the next Agent launch or owning-host reload; runtimeToggleable
449
+ * flags toggle immediately.
457
450
  */
458
451
  toggleSelectedFlag(): void {
459
452
  const flagEntry = this.getSelectedFlag();
@@ -474,7 +467,7 @@ export class SettingsModal {
474
467
  const { flag } = flagEntry;
475
468
 
476
469
  if (!flag.runtimeToggleable) {
477
- // Persist to config only takes effect on restart
470
+ // Persist to config only; the flag owner applies it on the next run.
478
471
  this._persistFlagState(flag.id, newState, flag.defaultState as FlagState);
479
472
  flagEntry.state = newState;
480
473
  } else {
@@ -639,9 +632,6 @@ export class SettingsModal {
639
632
  lockReason: hostOwned ? AGENT_EXTERNAL_HOST_SETTING_LOCK_REASON : resolved?.lockReason,
640
633
  };
641
634
  if (this.groups.has(cat)) this.groups.get(cat)!.push(entry);
642
- if ((rawCat === 'controlPlane' || rawCat === 'httpListener' || rawCat === 'web') && this.groups.has('network')) {
643
- this.groups.get('network')!.push(entry);
644
- }
645
635
  }
646
636
 
647
637
  const uiEntries = this.groups.get('ui');
@@ -649,8 +639,7 @@ export class SettingsModal {
649
639
  const uiPriority: Record<string, number> = {
650
640
  'ui.systemMessages': 0,
651
641
  'ui.operationalMessages': 1,
652
- 'ui.wrfcMessages': 2,
653
- 'ui.voiceEnabled': 3,
642
+ 'ui.voiceEnabled': 2,
654
643
  };
655
644
  uiEntries.sort((a, b) => (uiPriority[a.setting.key] ?? 99) - (uiPriority[b.setting.key] ?? 99));
656
645
  }
@@ -712,25 +701,7 @@ export class SettingsModal {
712
701
  /** Returns [] for the flags category (flags use flagEntries instead). */
713
702
  private _currentItems(): SettingEntry[] {
714
703
  if (this.currentCategory === 'flags' || this.currentCategory === 'mcp' || this.currentCategory === 'subscriptions') return [];
715
- const items = this.groups.get(this.currentCategory) ?? [];
716
- if (this.currentCategory === 'network') {
717
- return items.filter(entry => {
718
- if (entry.setting.key === 'controlPlane.host') {
719
- const hostMode = this.configManager?.get('controlPlane.hostMode');
720
- return hostMode === 'custom';
721
- }
722
- if (entry.setting.key === 'httpListener.host') {
723
- const hostMode = this.configManager?.get('httpListener.hostMode');
724
- return hostMode === 'custom';
725
- }
726
- if (entry.setting.key === 'web.host') {
727
- const hostMode = this.configManager?.get('web.hostMode');
728
- return hostMode === 'custom';
729
- }
730
- return true;
731
- });
732
- }
733
- return items;
704
+ return this.groups.get(this.currentCategory) ?? [];
734
705
  }
735
706
 
736
707
  private _refreshAllEntries(): void {
@@ -749,26 +720,9 @@ export class SettingsModal {
749
720
  this.lastSettingEffectMessage = AGENT_EXTERNAL_HOST_SETTING_LOCK_REASON;
750
721
  return;
751
722
  }
752
- // Diff previous value before writing — avoids false restart notices on no-op saves
753
723
  const previousValue = this.configManager.get(key);
754
- const isRestartKey = ['host', 'port', 'hostMode', 'enabled'].includes(key.split('.')[1] ?? '');
755
724
  try {
756
725
  this.configManager.setDynamic(key, value);
757
- const rawCat = key.split('.')[0] as string;
758
- if (rawCat === 'controlPlane') {
759
- if (isRestartKey && previousValue !== value) {
760
- this.lastSaveTriggeredRestart = 'control-plane';
761
- }
762
- } else if (rawCat === 'httpListener') {
763
- if (isRestartKey && previousValue !== value) {
764
- this.lastSaveTriggeredRestart = 'http-listener';
765
- }
766
- } else if (rawCat === 'web') {
767
- if (isRestartKey && previousValue !== value) {
768
- this.lastSaveTriggeredRestart = 'web';
769
- }
770
- }
771
-
772
726
  for (const entries of this.groups.values()) {
773
727
  const entry = entries.find((candidate) => candidate.setting.key === key);
774
728
  if (entry) {
@@ -5,7 +5,6 @@ export type SubmissionIntentKind =
5
5
  | 'orchestration'
6
6
  | 'delegation'
7
7
  | 'plan'
8
- | 'panel-action'
9
8
  | 'shell'
10
9
  | 'memory-pin';
11
10