@pellux/goodvibes-agent 0.1.114 → 0.1.117

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 (168) hide show
  1. package/CHANGELOG.md +41 -650
  2. package/README.md +40 -50
  3. package/dist/package/main.js +38224 -35673
  4. package/docs/README.md +5 -4
  5. package/docs/{connected-services.md → connected-host.md} +18 -10
  6. package/docs/getting-started.md +43 -42
  7. package/docs/release-and-publishing.md +6 -4
  8. package/package.json +3 -3
  9. package/src/agent/behavior-discovery-summary.ts +165 -0
  10. package/src/agent/persona-discovery.ts +1 -3
  11. package/src/agent/persona-registry.ts +5 -3
  12. package/src/agent/reminder-schedule-format.ts +6 -6
  13. package/src/agent/reminder-schedule.ts +1 -1
  14. package/src/agent/routine-registry.ts +43 -4
  15. package/src/agent/routine-schedule-format.ts +6 -6
  16. package/src/agent/routine-schedule-promotion.ts +1 -1
  17. package/src/agent/routine-schedule-receipts.ts +1 -1
  18. package/src/agent/runtime-profile-starters.ts +331 -0
  19. package/src/agent/runtime-profile.ts +228 -330
  20. package/src/agent/skill-registry.ts +190 -13
  21. package/src/cli/agent-knowledge-command.ts +2 -2
  22. package/src/cli/agent-knowledge-format.ts +2 -2
  23. package/src/cli/agent-knowledge-runtime.ts +1 -1
  24. package/src/cli/bundle-command.ts +1 -1
  25. package/src/cli/entrypoint.ts +16 -7
  26. package/src/cli/help.ts +26 -19
  27. package/src/cli/local-library-command.ts +75 -21
  28. package/src/cli/management-commands.ts +7 -6
  29. package/src/cli/management.ts +6 -51
  30. package/src/cli/parser.ts +23 -2
  31. package/src/cli/profiles-command.ts +247 -1
  32. package/src/cli/routines-command.ts +139 -11
  33. package/src/cli/service-posture.ts +11 -11
  34. package/src/cli/status.ts +21 -25
  35. package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
  36. package/src/input/agent-workspace-access-command-editors.ts +170 -0
  37. package/src/input/agent-workspace-activation.ts +2 -1
  38. package/src/input/agent-workspace-basic-command-editor-submission.ts +787 -0
  39. package/src/input/agent-workspace-basic-command-editors.ts +524 -459
  40. package/src/input/agent-workspace-categories.ts +177 -14
  41. package/src/input/agent-workspace-channel-command-editor-submission.ts +49 -0
  42. package/src/input/agent-workspace-channel-command-editors.ts +47 -0
  43. package/src/input/agent-workspace-command-editor.ts +25 -1
  44. package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
  45. package/src/input/agent-workspace-editors.ts +27 -0
  46. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
  47. package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
  48. package/src/input/agent-workspace-learned-behavior.ts +67 -0
  49. package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
  50. package/src/input/agent-workspace-library-command-editors.ts +35 -0
  51. package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
  52. package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
  53. package/src/input/agent-workspace-memory-command-editors.ts +180 -0
  54. package/src/input/agent-workspace-navigation.ts +45 -0
  55. package/src/input/agent-workspace-notify-editor-submission.ts +107 -0
  56. package/src/input/agent-workspace-operations-command-editor-submission.ts +146 -0
  57. package/src/input/agent-workspace-operations-command-editors.ts +119 -0
  58. package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
  59. package/src/input/agent-workspace-provider-command-editors.ts +93 -0
  60. package/src/input/agent-workspace-requirements.ts +11 -0
  61. package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
  62. package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
  63. package/src/input/agent-workspace-session-command-editors.ts +249 -0
  64. package/src/input/agent-workspace-setup.ts +49 -19
  65. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
  66. package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
  67. package/src/input/agent-workspace-snapshot.ts +56 -8
  68. package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
  69. package/src/input/agent-workspace-task-command-editors.ts +47 -0
  70. package/src/input/agent-workspace-types.ts +124 -0
  71. package/src/input/agent-workspace-voice-media.ts +1 -1
  72. package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
  73. package/src/input/agent-workspace.ts +47 -37
  74. package/src/input/command-registry.ts +1 -1
  75. package/src/input/commands/agent-runtime-profile-runtime.ts +160 -6
  76. package/src/input/commands/agent-skills-runtime.ts +76 -12
  77. package/src/input/commands/agent-workspace-runtime.ts +4 -3
  78. package/src/input/commands/brief-runtime.ts +38 -9
  79. package/src/input/commands/channels-runtime.ts +3 -3
  80. package/src/input/commands/compat-runtime.ts +32 -0
  81. package/src/input/commands/health-runtime.ts +22 -24
  82. package/src/input/commands/knowledge.ts +26 -5
  83. package/src/input/commands/local-provider-runtime.ts +7 -3
  84. package/src/input/commands/local-setup-review.ts +4 -14
  85. package/src/input/commands/mcp-runtime.ts +8 -12
  86. package/src/input/commands/operator-runtime.ts +8 -67
  87. package/src/input/commands/personas-runtime.ts +1 -1
  88. package/src/input/commands/platform-access-runtime.ts +7 -70
  89. package/src/input/commands/policy-dispatch.ts +1 -1
  90. package/src/input/commands/policy.ts +1 -5
  91. package/src/input/commands/product-runtime.ts +2 -2
  92. package/src/input/commands/qrcode-runtime.ts +6 -4
  93. package/src/input/commands/routines-runtime.ts +44 -6
  94. package/src/input/commands/runtime-services.ts +1 -14
  95. package/src/input/commands/security-runtime.ts +3 -8
  96. package/src/input/commands/session-content.ts +1 -1
  97. package/src/input/commands/session-workflow.ts +5 -14
  98. package/src/input/commands/shell-core.ts +8 -2
  99. package/src/input/commands/subscription-runtime.ts +1 -6
  100. package/src/input/commands/support-bundle-runtime.ts +53 -0
  101. package/src/input/commands/tasks-runtime.ts +2 -2
  102. package/src/input/commands.ts +4 -0
  103. package/src/input/feed-context-factory.ts +0 -1
  104. package/src/input/handler-content-actions.ts +0 -25
  105. package/src/input/handler-feed.ts +0 -2
  106. package/src/input/handler-interactions.ts +2 -31
  107. package/src/input/handler-onboarding.ts +29 -12
  108. package/src/input/handler-shortcuts.ts +1 -3
  109. package/src/input/handler.ts +4 -7
  110. package/src/input/keybindings.ts +9 -9
  111. package/src/input/mcp-workspace.ts +90 -26
  112. package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
  113. package/src/input/onboarding/onboarding-wizard-apply.ts +49 -0
  114. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  115. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +126 -11
  116. package/src/input/onboarding/onboarding-wizard-steps.ts +15 -8
  117. package/src/input/onboarding/onboarding-wizard-types.ts +1 -0
  118. package/src/input/onboarding/onboarding-wizard.ts +19 -2
  119. package/src/input/profile-picker-modal.ts +2 -2
  120. package/src/input/settings-modal-agent-policy.ts +6 -6
  121. package/src/input/settings-modal-subscriptions.ts +3 -3
  122. package/src/input/settings-modal.ts +14 -14
  123. package/src/main.ts +0 -2
  124. package/src/panels/automation-control-panel.ts +3 -3
  125. package/src/panels/builtin/agent.ts +1 -1
  126. package/src/panels/builtin/operations.ts +2 -2
  127. package/src/panels/builtin/session.ts +26 -18
  128. package/src/panels/builtin/shared.ts +6 -6
  129. package/src/panels/project-planning-panel.ts +1 -1
  130. package/src/panels/provider-health-domains.ts +3 -3
  131. package/src/panels/qr-panel.ts +44 -20
  132. package/src/panels/subscription-panel.ts +3 -3
  133. package/src/panels/system-messages-panel.ts +2 -2
  134. package/src/panels/tasks-panel.ts +4 -4
  135. package/src/planning/project-planning-coordinator.ts +2 -2
  136. package/src/renderer/agent-workspace.ts +52 -5
  137. package/src/renderer/block-actions.ts +1 -3
  138. package/src/renderer/help-overlay.ts +13 -8
  139. package/src/renderer/mcp-workspace.ts +32 -13
  140. package/src/renderer/model-picker-overlay.ts +0 -1
  141. package/src/renderer/model-workspace.ts +0 -2
  142. package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
  143. package/src/renderer/panel-picker-overlay.ts +1 -1
  144. package/src/renderer/profile-picker-modal.ts +2 -2
  145. package/src/renderer/settings-modal-helpers.ts +23 -23
  146. package/src/renderer/settings-modal.ts +18 -18
  147. package/src/renderer/system-message.ts +1 -1
  148. package/src/runtime/agent-runtime-events.ts +129 -0
  149. package/src/runtime/bootstrap-command-parts.ts +3 -2
  150. package/src/runtime/bootstrap-core.ts +4 -64
  151. package/src/runtime/bootstrap-shell.ts +42 -4
  152. package/src/runtime/bootstrap.ts +8 -27
  153. package/src/runtime/connected-host-auth.ts +42 -0
  154. package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
  155. package/src/runtime/index.ts +1 -5
  156. package/src/runtime/onboarding/apply.ts +213 -0
  157. package/src/runtime/onboarding/derivation.ts +25 -6
  158. package/src/runtime/onboarding/snapshot.ts +4 -2
  159. package/src/runtime/onboarding/types.ts +28 -1
  160. package/src/runtime/onboarding/verify.ts +81 -2
  161. package/src/runtime/operator-token-cleanup.ts +2 -2
  162. package/src/runtime/services.ts +27 -12
  163. package/src/shell/service-settings-sync.ts +7 -7
  164. package/src/shell/ui-openers.ts +27 -38
  165. package/src/tools/agent-local-registry-tool.ts +10 -4
  166. package/src/tools/agent-tool-policy-guard.ts +5 -7
  167. package/src/version.ts +1 -1
  168. package/src/cli/package-verification.ts +0 -274
@@ -104,6 +104,31 @@ function setupChecklistLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLi
104
104
  return lines;
105
105
  }
106
106
 
107
+ function discoverySummaryLine(label: string, summary: AgentWorkspaceRuntimeSnapshot['discoveredBehavior']['personas'], command: string): ContextLine[] {
108
+ if (summary.count === 0) return [];
109
+ const names = summary.names.length > 0
110
+ ? ` ${summary.names.join(', ')}${summary.count > summary.names.length ? `, +${summary.count - summary.names.length} more` : ''}.`
111
+ : '';
112
+ return [
113
+ { text: `${label}: ${summary.count} discovered; project ${summary.projectLocalCount}; global ${summary.globalCount}.`, fg: PALETTE.info, bold: true },
114
+ { text: ` ${command} to preview, then use the import form after review.${names}`, fg: PALETTE.muted },
115
+ ];
116
+ }
117
+
118
+ function behaviorDiscoveryLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine[] {
119
+ const lines: ContextLine[] = [
120
+ ...discoverySummaryLine('Discovered personas', snapshot.discoveredBehavior.personas, '/personas discover'),
121
+ ...discoverySummaryLine('Discovered skills', snapshot.discoveredBehavior.skills, '/agent-skills discover'),
122
+ ...discoverySummaryLine('Discovered routines', snapshot.discoveredBehavior.routines, '/routines discover'),
123
+ ];
124
+ if (lines.length === 0) return [];
125
+ return [
126
+ { text: '' },
127
+ { text: 'Discovered Behavior Files', fg: PALETTE.title, bold: true },
128
+ ...lines,
129
+ ];
130
+ }
131
+
107
132
  function localLibraryLines(
108
133
  title: string,
109
134
  items: readonly AgentWorkspaceRuntimeSnapshot['localPersonas'][number][],
@@ -125,6 +150,9 @@ function localLibraryLines(
125
150
  item.enabled === true ? 'enabled' : item.enabled === false ? 'disabled' : '',
126
151
  item.scope && item.cls ? `${item.scope}/${item.cls}` : '',
127
152
  item.confidence !== undefined ? `${item.confidence}%` : '',
153
+ item.requirementCount !== undefined && item.requirementCount > 0
154
+ ? (item.missingRequirementCount && item.missingRequirementCount > 0 ? `needs ${item.missingRequirementCount}/${item.requirementCount}` : `ready ${item.requirementCount}/${item.requirementCount}`)
155
+ : '',
128
156
  item.reviewState,
129
157
  item.startCount !== undefined ? `starts ${item.startCount}` : '',
130
158
  ].filter(Boolean).join(' / ');
@@ -137,6 +165,9 @@ function localLibraryLines(
137
165
  bold: selected || item.active === true,
138
166
  });
139
167
  lines.push({ text: ` ${item.description}${tags}${triggers}`, fg: PALETTE.muted });
168
+ if (item.missingRequirements && item.missingRequirements.length > 0) {
169
+ lines.push({ text: ` missing setup: ${item.missingRequirements.join(', ')}`, fg: PALETTE.warn });
170
+ }
140
171
  }
141
172
  if (items.length > 8) {
142
173
  lines.push({ text: `${items.length - 8} more item(s). Open the library command for the full list.`, fg: PALETTE.dim });
@@ -155,7 +186,16 @@ function profileLines(snapshot: AgentWorkspaceRuntimeSnapshot): ContextLine[] {
155
186
  for (const profile of snapshot.runtimeProfiles.slice(0, 6)) {
156
187
  const starter = profile.starterTemplateId ? ` starter=${profile.starterTemplateId}` : ' starter=none';
157
188
  const created = profile.createdAt ? ` created=${profile.createdAt.slice(0, 10)}` : '';
158
- lines.push({ text: `${profile.id}${starter}${created}`, fg: PALETTE.info, bold: profile.id === snapshot.activeRuntimeProfile });
189
+ const states = [
190
+ profile.id === snapshot.activeRuntimeProfile ? 'active' : '',
191
+ profile.id === snapshot.selectedRuntimeProfile ? 'default' : '',
192
+ ].filter(Boolean).join(', ');
193
+ const stateText = states ? ` [${states}]` : '';
194
+ lines.push({
195
+ text: `${profile.id}${stateText}${starter}${created}`,
196
+ fg: profile.id === snapshot.selectedRuntimeProfile ? PALETTE.good : PALETTE.info,
197
+ bold: profile.id === snapshot.activeRuntimeProfile || profile.id === snapshot.selectedRuntimeProfile,
198
+ });
159
199
  lines.push({ text: ` home: ${profile.homeDirectory}`, fg: PALETTE.muted });
160
200
  }
161
201
  if (snapshot.runtimeProfiles.length > 6) {
@@ -199,6 +239,7 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
199
239
  { text: `Connection: ${snapshot.runtimeBaseUrl}`, fg: PALETTE.info },
200
240
  { text: 'Agent role: interactive operator TUI; setup changes here are Agent-local.', fg: PALETTE.good },
201
241
  ...setupChecklistLines(snapshot),
242
+ ...behaviorDiscoveryLines(snapshot),
202
243
  { text: '' },
203
244
  { text: `Workspace: ${snapshot.workingDirectory}`, fg: PALETTE.muted },
204
245
  { text: `Home: ${snapshot.homeDirectory}`, fg: PALETTE.muted },
@@ -246,8 +287,8 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
246
287
  } else if (category.id === 'tools') {
247
288
  base.push(
248
289
  { text: `MCP servers: ${snapshot.mcpConnectedServerCount}/${snapshot.mcpServerCount} connected; quarantined ${snapshot.mcpQuarantinedServerCount}; allow-all ${snapshot.mcpAllowAllServerCount}.`, fg: snapshot.mcpQuarantinedServerCount > 0 || snapshot.mcpAllowAllServerCount > 0 ? PALETTE.warn : PALETTE.info },
249
- { text: 'Open MCP workspace for live server status, tool inventory, config paths, and command previews.', fg: PALETTE.info },
250
- { text: 'Add/update requires typed confirmation and dispatches /mcp add ... --yes through the command router.', fg: PALETTE.good },
290
+ { text: 'Open MCP workspace for live server status, tool inventory, config paths, and confirmed add/remove/reload actions.', fg: PALETTE.info },
291
+ { text: 'Add/update requires typed confirmation and dispatches through the TUI command router.', fg: PALETTE.good },
251
292
  { text: 'Trust changes remain explicit; allow-all is kept behind the settings workspace.', fg: PALETTE.warn },
252
293
  { text: 'Useful first actions: /mcp review, /mcp tools, /mcp config, and Add MCP server.', fg: PALETTE.muted },
253
294
  { text: 'Normal assistant chat can use tools serially when policy allows; onboarding does not start hidden tool work.', fg: PALETTE.muted },
@@ -291,8 +332,12 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
291
332
  { text: 'Image input uses prompt attachments; media generation/provider setup stays behind explicit commands and configured providers.', fg: PALETTE.muted },
292
333
  );
293
334
  } else if (category.id === 'profiles') {
335
+ const defaultProfile = snapshot.selectedRuntimeProfile
336
+ ? `${snapshot.selectedRuntimeProfile}${snapshot.selectedRuntimeProfileExists ? '' : ' (missing)'}`
337
+ : '(base Agent home)';
294
338
  base.push(
295
339
  { text: `Active Agent profile: ${snapshot.activeRuntimeProfile}`, fg: PALETTE.info },
340
+ { text: `Default for next launch: ${defaultProfile}`, fg: snapshot.selectedRuntimeProfileExists || !snapshot.selectedRuntimeProfile ? PALETTE.info : PALETTE.warn },
296
341
  { text: `Agent profiles under this home: ${snapshot.runtimeProfileCount}`, fg: PALETTE.info },
297
342
  { text: `Starter templates: ${snapshot.runtimeStarterTemplateCount}; local custom: ${snapshot.localStarterTemplateCount}`, fg: PALETTE.info },
298
343
  { text: `Starter ids: ${snapshot.runtimeStarterTemplates.map((template) => template.id).join(', ') || 'none'}`, fg: PALETTE.info },
@@ -305,7 +350,7 @@ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCatego
305
350
  { text: '' },
306
351
  { text: 'Named Agent profiles isolate local config, sessions, memory, personas, skills, routines, setup, and bundles.', fg: PALETTE.good },
307
352
  { text: 'Starter authoring: browse, export, edit, import, and create Agent profiles from inside this workspace.', fg: PALETTE.info },
308
- { text: 'Connected GoodVibes services stay shared unless the owning host is configured separately.', fg: PALETTE.warn },
353
+ { text: 'The connected GoodVibes host stays shared unless that host is configured separately.', fg: PALETTE.warn },
309
354
  { text: 'Portable bundles require explicit export/import commands with real paths and --yes.', fg: PALETTE.muted },
310
355
  );
311
356
  } else if (category.id === 'memory') {
@@ -460,7 +505,9 @@ function buildEditorFieldRows(editor: AgentWorkspaceLocalEditor, index: number,
460
505
  const selected = index === editor.selectedFieldIndex;
461
506
  const marker = selected ? GLYPHS.navigation.selected : ' ';
462
507
  const required = field.required ? ' *' : '';
463
- const value = field.value.length > 0 ? field.value : '(empty)';
508
+ const value = field.value.length > 0
509
+ ? field.redact ? '*'.repeat(Math.min(12, Math.max(6, Array.from(field.value).length))) : field.value
510
+ : '(empty)';
464
511
  const color = selected ? PALETTE.text : field.value.length > 0 ? PALETTE.info : PALETTE.muted;
465
512
  const rows: WorkspaceRow[] = [{
466
513
  text: `${marker} ${field.label}${required}`,
@@ -1,6 +1,6 @@
1
1
  import type { BlockMeta } from '../core/conversation';
2
2
 
3
- export type BlockActionId = 'copy' | 'bookmark' | 'toggle' | 'apply' | 'rerun';
3
+ export type BlockActionId = 'copy' | 'bookmark' | 'toggle' | 'rerun';
4
4
 
5
5
  export interface BlockAction {
6
6
  id: BlockActionId;
@@ -12,7 +12,6 @@ const ALL_ACTIONS: BlockAction[] = [
12
12
  { id: 'copy', label: 'Copy', key: 'c' },
13
13
  { id: 'bookmark', label: 'Bookmark', key: 'b' },
14
14
  { id: 'toggle', label: 'Collapse/Expand',key: 'Tab' },
15
- { id: 'apply', label: 'Diff apply blocked', key: 'a' },
16
15
  { id: 'rerun', label: 'Re-run tool', key: 'r' },
17
16
  ];
18
17
 
@@ -36,7 +35,6 @@ export class BlockActionsMenu {
36
35
  open(block: BlockMeta): void {
37
36
  this.block = block;
38
37
  this.actions = ALL_ACTIONS.filter(a => {
39
- if (a.id === 'apply') return block.type === 'diff';
40
38
  if (a.id === 'rerun') return block.type === 'tool';
41
39
  return true;
42
40
  });
@@ -57,11 +57,11 @@ export function renderHelpOverlay(
57
57
  ` ${kb('paste').padEnd(20)} Paste (image priority)`,
58
58
  ` ${(kb('undo') + ' / ' + kb('redo')).padEnd(20)} Undo / redo`,
59
59
  '',
60
- ' Overlays And Panels',
60
+ ' Overlays And Workspace',
61
61
  ' ' + '\u2500'.repeat(40),
62
62
  ` ${'?'.padEnd(20)} Toggle help`,
63
63
  ` ${'/shortcuts'.padEnd(20)} Full keyboard shortcuts`,
64
- ` ${kb('panel-picker').padEnd(20)} Open or focus the panel workspace`,
64
+ ` ${kb('panel-picker').padEnd(20)} Open the Agent operator workspace`,
65
65
  '',
66
66
  ];
67
67
 
@@ -70,6 +70,9 @@ export function renderHelpOverlay(
70
70
  // Commands not registered in the live registry are omitted at render time.
71
71
  const FEATURED_COMMANDS: Array<[name: string, argHint: string, desc: string]> = [
72
72
  ['agent', '', 'Open the Agent operator workspace'],
73
+ ['agent', 'setup', 'Open setup, local behavior, channel, and voice workspaces'],
74
+ ['agent', 'knowledge', 'Open isolated Agent Knowledge workflows'],
75
+ ['agent', 'voice-media', 'Open voice, image, browser, and media setup'],
73
76
  ['setup', '', 'Open Agent setup with current settings preloaded'],
74
77
  ['knowledge', 'status', 'Inspect isolated Agent Knowledge readiness'],
75
78
  ['memory', '', 'Manage local Agent memory records'],
@@ -85,6 +88,8 @@ export function renderHelpOverlay(
85
88
  ['model', '', 'Select the active model route'],
86
89
  ['subscription', '', 'Review provider logins and subscriptions'],
87
90
  ['secrets', '', 'Manage secret references without printing values'],
91
+ ['bundle', 'inspect', 'Inspect Agent support bundles from the TUI'],
92
+ ['compat', '', 'Inspect connected-host and Agent Knowledge compatibility'],
88
93
  ['health', '', 'Run Agent runtime and setup diagnostics'],
89
94
  ];
90
95
 
@@ -238,7 +243,7 @@ export function renderShortcutsOverlay(
238
243
  row(kb('clear-prompt'), 'Clear prompt'),
239
244
  row(kb('delete-word'), 'Delete word backward'),
240
245
  row(kb('kill-line'), 'Kill to end of line'),
241
- row(kb('apply-diff-line-start'), 'Delegate diff changes / line start'),
246
+ row(kb('line-start'), 'Move to start of line'),
242
247
  row(kb('next-error-line-end'), 'Next error / line end'),
243
248
  '',
244
249
  ' Actions',
@@ -252,12 +257,12 @@ export function renderShortcutsOverlay(
252
257
  row('?', 'Help overlay'),
253
258
  row(`${kb('clear-cancel')} x2`, 'Exit'),
254
259
  '',
255
- ' Panels',
260
+ ' Workspace',
256
261
  ' ' + '\u2500'.repeat(40),
257
- row('Tab', 'Swap focus between input and panel workspace'),
258
- row(kb('panel-picker'), 'Open / focus / hide panel workspace'),
259
- row(kb('panel-tab-next'), 'Next workspace panel tab'),
260
- row(kb('panel-tab-prev'), 'Previous workspace panel tab'),
262
+ row('Tab', 'Swap focus between input and active Agent workspace'),
263
+ row(kb('panel-picker'), 'Open the Agent operator workspace'),
264
+ row(kb('panel-tab-next'), 'Reserved for future Agent workspace tabs'),
265
+ row(kb('panel-tab-prev'), 'Reserved for future Agent workspace tabs'),
261
266
  '',
262
267
  ` Config: /keybindings to list and customize`,
263
268
  ];
@@ -82,16 +82,22 @@ function selectedDetailLines(workspace: McpWorkspace, width: number): WorkspaceR
82
82
  if (workspace.mode === 'form') {
83
83
  const field = workspace.formFields[workspace.formIndex];
84
84
  lines.push(
85
- workspace.editingServerName ? `Previewing server: ${workspace.editingServerName}` : 'Drafting an MCP server command',
86
- 'Workspace writes/reloads are blocked. Use the generated /mcp add ... --yes command from the prompt.',
85
+ workspace.editingServerName ? `Editing server: ${workspace.editingServerName}` : 'Drafting an MCP server',
86
+ 'Workspace writes require explicit confirmation. Type yes on the Confirm field, then save from here.',
87
87
  field ? `${field.label}: ${field.help}` : '',
88
- 'Project/global config locations are shown for review. This workspace does not write or reload MCP config.',
88
+ 'Project/global config locations are shown for review. The workspace dispatches confirmed MCP changes through the TUI command router.',
89
89
  );
90
90
  } else if (workspace.mode === 'delete-confirm') {
91
91
  lines.push(
92
- `Removal blocked for server: ${workspace.editingServerName ?? '(unknown)'}`,
93
- 'Use /mcp remove <server> --scope <project|global> --yes from the prompt for explicit removal.',
94
- 'Press n or Esc to return.',
92
+ `Remove server: ${workspace.editingServerName ?? '(unknown)'}`,
93
+ 'Press Enter or y to remove through the TUI command router.',
94
+ 'Press n or Esc to return without changing config.',
95
+ );
96
+ } else if (workspace.mode === 'reload-confirm') {
97
+ lines.push(
98
+ 'Reload MCP runtime',
99
+ 'Press Enter or y to reload MCP runtime from the current config through the TUI command router.',
100
+ 'Press n or Esc to return without reloading.',
95
101
  );
96
102
  } else {
97
103
  const selected = workspace.selectedRow;
@@ -200,27 +206,40 @@ function buildDeleteRows(workspace: McpWorkspace, height: number): WorkspaceRow[
200
206
  return rows.slice(0, height);
201
207
  }
202
208
 
209
+ function buildReloadRows(height: number): WorkspaceRow[] {
210
+ const rows: WorkspaceRow[] = [
211
+ { text: `${GLYPHS.navigation.selected} Confirm MCP runtime reload`, selected: true, fg: PALETTE.warn, bold: true },
212
+ { text: ' Cancel and return to MCP server browser', fg: PALETTE.muted },
213
+ ];
214
+ while (rows.length < height) rows.push({ text: '', kind: 'empty' });
215
+ return rows.slice(0, height);
216
+ }
217
+
203
218
  function buildControlRows(workspace: McpWorkspace, width: number, height: number): WorkspaceRow[] {
204
219
  if (workspace.mode === 'form') return buildFormRows(workspace, width, height);
205
220
  if (workspace.mode === 'delete-confirm') return buildDeleteRows(workspace, height);
221
+ if (workspace.mode === 'reload-confirm') return buildReloadRows(height);
206
222
  return buildToolRows(workspace, width, height);
207
223
  }
208
224
 
209
225
  function footerText(workspace: McpWorkspace): string {
210
- if (workspace.mode === 'form') return 'Focus server command preview · Up/Down field · Left/Right cycle · Type edit · Enter show command · Esc back';
211
- if (workspace.mode === 'delete-confirm') return 'Focus remove guidance · n/Esc cancel';
212
- return 'Focus MCP workspace · Up/Down choose · Enter view/action · a draft · d removal command · r reload command · t tools · Esc close';
226
+ if (workspace.mode === 'form') return 'Focus MCP server form · Up/Down field · Left/Right cycle · Type edit · Enter save/cancel · Esc back';
227
+ if (workspace.mode === 'delete-confirm') return 'Focus remove confirmation · Enter/y remove · n/Esc cancel';
228
+ if (workspace.mode === 'reload-confirm') return 'Focus reload confirmation · Enter/y reload · n/Esc cancel';
229
+ return 'Focus MCP workspace · Up/Down choose · Enter view/action · a add · d remove · r reload · t tools · Esc close';
213
230
  }
214
231
 
215
232
  export function renderMcpWorkspace(workspace: McpWorkspace, width: number, height: number): Line[] {
216
233
  const metrics = getFullscreenWorkspaceMetrics({ width, height });
217
234
  const connected = workspace.servers.filter((server) => server.connected).length;
218
- const stateLabel = workspace.mode === 'browse' ? 'Browse' : workspace.mode === 'form' ? 'Command Preview' : 'Remove Guidance';
235
+ const stateLabel = workspace.mode === 'browse' ? 'Browse' : workspace.mode === 'form' ? 'Server Form' : workspace.mode === 'delete-confirm' ? 'Remove Confirm' : 'Reload Confirm';
219
236
  const mainHeader = workspace.mode === 'form'
220
- ? 'MCP server command preview'
237
+ ? 'MCP server form'
221
238
  : workspace.mode === 'delete-confirm'
222
- ? 'MCP remove command'
223
- : `Servers ${connected}/${workspace.servers.length} connected · Tools ${workspace.tools.length}`;
239
+ ? 'MCP remove confirmation'
240
+ : workspace.mode === 'reload-confirm'
241
+ ? 'MCP reload confirmation'
242
+ : `Servers ${connected}/${workspace.servers.length} connected · Tools ${workspace.tools.length}`;
224
243
 
225
244
  return renderFullscreenWorkspace({
226
245
  width,
@@ -240,7 +240,6 @@ export function renderModelPickerOverlay(
240
240
  if (caps.reasoning) capParts.push('Reasoning: \u2713');
241
241
  if (caps.multimodal) capParts.push('Vision: \u2713');
242
242
  if (caps.toolCalling) capParts.push('Tools: \u2713');
243
- if (caps.codeEditing) capParts.push('Code: \u2713');
244
243
  const capText = capParts.join(' ');
245
244
  const capLine = createOverlayContentLine(width, layout, borderFg, DEFAULT_OVERLAY_PALETTE.bodyBg);
246
245
  putRowText(capLine, layout.margin + 2, contentW, fitDisplay(truncateDisplay(capText, contentW), contentW), '244');
@@ -184,7 +184,6 @@ function detailLines(picker: ModelPickerModal, width: number): string[] {
184
184
  caps.reasoning ? 'reasoning' : '',
185
185
  caps.multimodal ? 'vision' : '',
186
186
  caps.toolCalling ? 'tools' : '',
187
- caps.codeEditing ? 'code' : '',
188
187
  ].filter(Boolean).join(', ') || 'standard';
189
188
  lines.push(`Selected: ${modelKey(selected)} | ${selected.displayName} | context ${formatContext(selected.contextWindow)} | ${capText}`);
190
189
  }
@@ -261,7 +260,6 @@ function renderModelRows(picker: ModelPickerModal, lines: Line[], rows: number,
261
260
  caps.reasoning ? 'R' : '-',
262
261
  caps.multimodal ? 'V' : '-',
263
262
  caps.toolCalling ? 'T' : '-',
264
- caps.codeEditing ? 'C' : '-',
265
263
  ].join('');
266
264
  let x = startX + 1;
267
265
  writeText(line, x, 2, padDisplay(marker, 2), { fg: PALETTE.text, bg, bold: selected }); x += 2;
@@ -161,16 +161,28 @@ function fieldHint(
161
161
  const rawValue = wizard.editBuffer.length > 0 ? wizard.editBuffer : field.placeholder;
162
162
  const editingValue = field.kind === 'masked' && wizard.editBuffer.length > 0
163
163
  ? '•'.repeat(Math.min(12, Math.max(4, wizard.editBuffer.length)))
164
- : rawValue;
164
+ : formatEditingValue(rawValue, field.kind === 'text' && field.multiline === true);
165
165
  return `Editing: ${editingValue}█`;
166
166
  }
167
167
 
168
168
  if (selected && field.kind === 'modelPicker') return `${field.hint} Press Enter to open picker.`;
169
- if (selected && field.kind === 'text') return `${field.hint} Press Enter to edit inline.`;
169
+ if (selected && field.kind === 'text') {
170
+ return field.multiline === true
171
+ ? `${field.hint} Press Enter to edit; Ctrl-J inserts a new line.`
172
+ : `${field.hint} Press Enter to edit inline.`;
173
+ }
170
174
  if (selected && field.kind === 'masked') return `${field.hint} Press Enter to edit inline.`;
171
175
  return field.hint;
172
176
  }
173
177
 
178
+ function formatEditingValue(value: string, multiline: boolean): string {
179
+ if (!multiline) return value;
180
+ const lines = value.split(/\r?\n/);
181
+ if (lines.length <= 1) return value;
182
+ const preview = lines[lines.length - 1] ?? '';
183
+ return `${preview} (${lines.length} lines)`;
184
+ }
185
+
174
186
  function fieldRowPrefix(
175
187
  wizard: OnboardingWizardController,
176
188
  field: OnboardingWizardFieldDefinition,
@@ -255,7 +267,9 @@ function renderFieldRow(
255
267
 
256
268
  function footerText(wizard: OnboardingWizardController): string {
257
269
  if (wizard.isEditingTextField()) {
258
- return '[Enter] Save value [Esc] Cancel edit [Backspace] Delete char [Del/Ctrl+U] Clear value';
270
+ return wizard.isEditingMultilineTextField()
271
+ ? '[Enter] Save value [Ctrl-J] New line [Esc] Cancel edit [Backspace] Delete char [Del/Ctrl+U] Clear value'
272
+ : '[Enter] Save value [Esc] Cancel edit [Backspace] Delete char [Del/Ctrl+U] Clear value';
259
273
  }
260
274
 
261
275
  return '[Enter] Toggle/open [Esc] Close [Tab/Shift+Tab] Screen [↑↓] Move [Del/Ctrl+U] Clear input';
@@ -263,7 +277,9 @@ function footerText(wizard: OnboardingWizardController): string {
263
277
 
264
278
  function controlsText(wizard: OnboardingWizardController): string {
265
279
  if (wizard.isEditingTextField()) {
266
- return 'Controls: Enter saves, Esc cancels, Backspace deletes, Del clears.';
280
+ return wizard.isEditingMultilineTextField()
281
+ ? 'Controls: Enter saves, Ctrl-J inserts a line, Esc cancels, Backspace deletes, Del clears.'
282
+ : 'Controls: Enter saves, Esc cancels, Backspace deletes, Del clears.';
267
283
  }
268
284
  return 'Controls: Enter selects, Del clears, Tab moves.';
269
285
  }
@@ -46,7 +46,7 @@ export function renderPanelPickerOverlay(
46
46
 
47
47
  // ── Title bar ──────────────────────────────────────────────────────────────
48
48
  const titleLine = createOverlayBorderLine(width, layout, '┌', '─', '┐', borderFg);
49
- putOverlayText(titleLine, layout.margin + 2, layout.width - 4, 'Open Panel Workspace', { fg: titleFg, bold: true });
49
+ putOverlayText(titleLine, layout.margin + 2, layout.width - 4, 'Deferred Workspace Picker', { fg: titleFg, bold: true });
50
50
  lines.push(titleLine);
51
51
 
52
52
  // ── Search bar (shown when query is non-empty) ──────────────────────────────
@@ -51,7 +51,7 @@ export function renderProfilePickerModal(
51
51
  });
52
52
  sections.push({
53
53
  type: 'text',
54
- content: 'Use /profiles save <name> --yes to save the current settings as a profile.',
54
+ content: 'Use /agent profiles to create and manage isolated Agent profile homes.',
55
55
  style: { fg: '240', dim: true },
56
56
  });
57
57
  } else {
@@ -114,7 +114,7 @@ export function renderProfilePickerModal(
114
114
  margin: boxMargin,
115
115
  targetContentRows,
116
116
  sections,
117
- hints: ['[Up/Down] Navigate', '[Enter] Load', '/profiles save|delete --yes', '[Esc] Close'],
117
+ hints: ['[Up/Down] Navigate', '[Enter] Load', 'Agent profiles: /agent profiles', '[Esc] Close'],
118
118
  },
119
119
  width,
120
120
  );
@@ -83,12 +83,12 @@ export const CATEGORY_LABELS: Record<(typeof SETTINGS_CATEGORIES)[number], strin
83
83
  storage: 'Storage',
84
84
  permissions: 'Permissions',
85
85
  orchestration: 'Orchestration',
86
- wrfc: 'WRFC Delegation',
86
+ wrfc: 'Build Delegation',
87
87
  helper: 'Helper',
88
88
  tts: 'TTS',
89
- service: 'Runtime Install',
90
- controlPlane: 'Runtime API',
91
- httpListener: 'Inbound Events',
89
+ service: 'Connected Host',
90
+ controlPlane: 'Connected API',
91
+ httpListener: 'Inbound Delivery',
92
92
  web: 'Browser Companion',
93
93
  batch: 'Batch',
94
94
  automation: 'Automation',
@@ -108,7 +108,7 @@ export const CATEGORY_LABELS: Record<(typeof SETTINGS_CATEGORIES)[number], strin
108
108
  export const SETTING_LABELS: Partial<Record<string, string>> = {
109
109
  'ui.systemMessages': 'System Message Target',
110
110
  'ui.operationalMessages': 'Operational Message Target',
111
- 'ui.wrfcMessages': 'Delegated WRFC Message Target',
111
+ 'ui.wrfcMessages': 'Delegated Build Message Target',
112
112
  'ui.voiceEnabled': 'Voice Interaction',
113
113
  'behavior.autoCompactThreshold': 'Auto-Compact %',
114
114
  'behavior.staleContextWarnings': 'Context Warnings',
@@ -124,24 +124,24 @@ export const SETTING_LABELS: Partial<Record<string, string>> = {
124
124
  'helper.globalProvider': 'Helper Provider',
125
125
  'helper.globalModel': 'Helper Model',
126
126
  // Runtime API
127
- 'controlPlane.enabled': 'Runtime API Enabled',
128
- 'controlPlane.hostMode': 'Runtime API Host Mode',
129
- 'controlPlane.host': 'Runtime API Host',
130
- 'controlPlane.port': 'Runtime API Port',
131
- 'controlPlane.baseUrl': 'Runtime API Base URL',
132
- 'controlPlane.streamMode': 'Runtime API Stream Mode',
133
- 'controlPlane.allowRemote': 'Runtime API Allow Remote',
134
- 'controlPlane.trustProxy': 'Runtime API Trust Proxy',
135
- 'controlPlane.tls.mode': 'Runtime API TLS Mode',
136
- 'controlPlane.tls.certFile': 'Runtime API TLS Cert',
137
- 'controlPlane.tls.keyFile': 'Runtime API TLS Key',
138
- // Inbound event endpoint
139
- 'httpListener.hostMode': 'HTTP Host Mode',
140
- 'httpListener.host': 'HTTP Host',
141
- 'httpListener.port': 'HTTP Port',
142
- 'httpListener.trustProxy': 'HTTP Trust Proxy',
143
- 'httpListener.tls.mode': 'HTTP TLS Mode',
144
- 'httpListener.tls.certFile': 'HTTP TLS Cert',
127
+ 'controlPlane.enabled': 'Connected API Enabled',
128
+ 'controlPlane.hostMode': 'Connected API Host Mode',
129
+ 'controlPlane.host': 'Connected API Host',
130
+ 'controlPlane.port': 'Connected API Port',
131
+ 'controlPlane.baseUrl': 'Connected API Base URL',
132
+ 'controlPlane.streamMode': 'Connected API Stream Mode',
133
+ 'controlPlane.allowRemote': 'Connected API Allow Remote',
134
+ 'controlPlane.trustProxy': 'Connected API Trust Proxy',
135
+ 'controlPlane.tls.mode': 'Connected API TLS Mode',
136
+ 'controlPlane.tls.certFile': 'Connected API TLS Cert',
137
+ 'controlPlane.tls.keyFile': 'Connected API TLS Key',
138
+ // Inbound delivery endpoint
139
+ 'httpListener.hostMode': 'Inbound Delivery Host Mode',
140
+ 'httpListener.host': 'Inbound Delivery Host',
141
+ 'httpListener.port': 'Inbound Delivery Port',
142
+ 'httpListener.trustProxy': 'Inbound Delivery Trust Proxy',
143
+ 'httpListener.tls.mode': 'Inbound Delivery TLS Mode',
144
+ 'httpListener.tls.certFile': 'Inbound Delivery TLS Cert',
145
145
  // Browser companion
146
146
  'web.enabled': 'Web Enabled',
147
147
  'web.hostMode': 'Web Host Mode',
@@ -7,7 +7,7 @@
7
7
 
8
8
  import type { Line } from '../types/grid.ts';
9
9
  import type { SettingsModal, SettingEntry, FlagEntry, McpEntry, SubscriptionEntry, SettingsCategory } from '../input/settings-modal.ts';
10
- import { isExternalDaemonOwnedSettingKey, SETTINGS_CATEGORIES, SETTINGS_CATEGORY_GROUPS } from '../input/settings-modal.ts';
10
+ import { isExternalHostOwnedSettingKey, SETTINGS_CATEGORIES, SETTINGS_CATEGORY_GROUPS } from '../input/settings-modal.ts';
11
11
  import { getDisplayWidth, wrapText } from '../utils/terminal-width.ts';
12
12
  import { CATEGORY_LABELS, describeUiRouting, formatValue, getSettingLabel, inferSubscriptionRouteReason, valueColor } from './settings-modal-helpers.ts';
13
13
  import { isSecretConfigKey } from '../config/secret-config.ts';
@@ -30,34 +30,34 @@ const CATEGORY_INFO: Record<SettingsCategory, string> = {
30
30
  behavior: 'Day-to-day shell behavior: approval posture, compaction, history, guidance, notifications, stale-context warnings, return context, and Human-in-the-Loop mode.',
31
31
  storage: 'Local storage posture, including secret storage policy and maximum artifact size for Agent Knowledge, artifacts, and document ingestion.',
32
32
  permissions: 'Permission mode and tool-class policy. These settings decide whether the shell prompts before read/write/exec/network/agent actions.',
33
- orchestration: 'Agent orchestration limits and recursion controls.',
34
- wrfc: 'WRFC is external to normal Agent operation. Review these compatibility values only for explicit GoodVibes TUI build delegation.',
33
+ orchestration: 'Hidden compatibility settings. Normal Agent operation stays serial and does not expose local spawn fanout.',
34
+ wrfc: 'Build-review routing is external to normal Agent operation. Review these compatibility values only for explicit delegated build work.',
35
35
  helper: 'Helper model defaults used by helper subsystems when they do not use the main chat route.',
36
36
  tts: 'Text-to-speech provider, voice, and optional spoken-turn LLM overrides.',
37
- service: 'Connected-service installation posture. Agent shows these compatibility keys for inspection only and does not install, start, stop, restart, or autostart anything.',
38
- controlPlane: 'Connected-service API settings. Agent uses these settings for access and does not mutate bind posture.',
39
- httpListener: 'Inbound event endpoint settings owned by connected GoodVibes services. Agent inspects readiness and does not expose endpoints.',
37
+ service: 'Connected-host status posture. Agent inspects these values only and does not install, start, stop, restart, or autostart anything.',
38
+ controlPlane: 'Connected API settings. Agent uses these values for access and does not mutate bind posture.',
39
+ httpListener: 'Inbound delivery endpoint settings owned by the connected GoodVibes host. Agent inspects readiness and does not expose endpoints.',
40
40
  web: 'External browser companion settings. Agent does not own browser hosting or network bind lifecycle.',
41
- batch: 'Batch execution settings reported from connected GoodVibes services. Agent does not own remote queue provisioning.',
41
+ batch: 'Queued execution settings reported from the connected GoodVibes host. Agent does not own remote queue provisioning.',
42
42
  automation: 'Scheduled and automated run settings, concurrency, timeout, catch-up, cooldown, and retention behavior.',
43
43
  watchers: 'File/process watcher heartbeat, polling, and recovery-window behavior.',
44
- runtime: 'Connected-service guardrails such as companion chat limiter and event bus listener caps.',
44
+ runtime: 'Connected-host guardrails such as companion chat limits and event-stream caps.',
45
45
  telemetry: 'Telemetry payload policy.',
46
46
  cache: 'Provider and model cache behavior, TTL, and hit-rate monitoring.',
47
47
  mcp: 'MCP server trust and scope review. Trust changes can expose local files, tools, databases, browsers, or remote automation depending on the server.',
48
48
  surfaces: 'Messaging and notification channel accounts such as Slack, Discord, ntfy, Telegram, chat bridges, and delivery providers.',
49
49
  release: 'Release-channel preference.',
50
- danger: 'High-impact service switches. Agent renders service-owned switches read-only; change them outside Agent.',
50
+ danger: 'High-impact host switches. Agent renders host-owned switches read-only; change them outside Agent.',
51
51
  tools: 'Tool LLM and helper model routing. Empty provider/model values inherit the active chat route unless a specific helper/tool route is set.',
52
52
  flags: 'Feature flags are SDK gates. They are separate from normal config keys because they enable or disable staged behavior.',
53
- network: 'Read-only view of connected GoodVibes API, inbound-event, and browser companion bind posture plus editable Agent network settings.',
53
+ network: 'Read-only view of connected GoodVibes API, inbound delivery, and browser companion bind posture plus editable Agent network settings.',
54
54
  };
55
55
 
56
56
  const ENUM_VALUE_DESCRIPTIONS: Record<string, Record<string, string>> = {
57
57
  'behavior.hitlMode': {
58
58
  quiet: 'Minimize operational interruptions and surface fewer Human-in-the-Loop prompts.',
59
59
  balanced: 'Show important Human-in-the-Loop prompts without turning routine work into noise.',
60
- operator: 'Surface more operational detail for users actively supervising agents, tools, services, and automation.',
60
+ operator: 'Surface more operational detail for users actively supervising agents, tools, connected-host posture, and automation.',
61
61
  },
62
62
  'behavior.guidanceMode': {
63
63
  off: 'Do not add extra guidance beyond direct command output.',
@@ -105,9 +105,9 @@ const ENUM_VALUE_DESCRIPTIONS: Record<string, Record<string, string>> = {
105
105
  both: 'Show operational messages in both panels and the transcript.',
106
106
  },
107
107
  'ui.wrfcMessages': {
108
- panel: 'Show explicit delegated-build WRFC messages in panels only.',
109
- conversation: 'Show explicit delegated-build WRFC messages inline in the transcript.',
110
- both: 'Show explicit delegated-build WRFC messages in both panels and the transcript.',
108
+ panel: 'Show explicit delegated build messages in panels only.',
109
+ conversation: 'Show explicit delegated build messages inline in the transcript.',
110
+ both: 'Show explicit delegated build messages in both panels and the transcript.',
111
111
  },
112
112
  'surfaces.telegram.mode': {
113
113
  webhook: 'Receive Telegram updates through externally hosted delivery.',
@@ -148,7 +148,7 @@ function buildSettingContext(modal: SettingsModal, entry: SettingEntry): string[
148
148
  ];
149
149
 
150
150
  if (entry.locked) lines.push(`Locked: ${entry.lockReason ?? 'This setting is locked by a higher-priority layer.'}`);
151
- if (entry.conflict) lines.push(`Conflict: inspect with /settings and resolve service-owned sync state in the owning host.`);
151
+ if (entry.conflict) lines.push(`Conflict: inspect with /settings and resolve host-owned sync state in the owning host.`);
152
152
 
153
153
  lines.push('', entry.setting.description);
154
154
 
@@ -248,7 +248,7 @@ function buildSubscriptionContext(modal: SettingsModal, entry: SubscriptionEntry
248
248
  ? modal.subscriptionLogoutConfirmationTarget === entry.provider
249
249
  ? `Press Enter again to sign out ${entry.provider}. Move selection or close config to cancel.`
250
250
  : 'Press Enter to review sign-out for this provider session.'
251
- : `Use /subscription login ${entry.provider} start to begin OAuth sign-in for this provider.`;
251
+ : `Open /agent setup and choose Start subscription login for ${entry.provider}.`;
252
252
  return [
253
253
  entry.provider,
254
254
  `State: ${entry.state}`,
@@ -478,8 +478,8 @@ function footerText(modal: SettingsModal): string {
478
478
  if (modal.currentCategory === 'mcp') return 'Focus settings · Up/Down server · Left categories · Tab pane · Enter edit trust · Esc close';
479
479
  if (modal.currentCategory === 'flags') return 'Focus feature flags · Up/Down flag · Left categories · Tab pane · Enter/Space toggle · Esc close';
480
480
  const selected = modal.getSelected();
481
- if (selected && isExternalDaemonOwnedSettingKey(selected.setting.key)) {
482
- return 'Read-only connected-service setting · Change from GoodVibes TUI or the owning host · Esc close';
481
+ if (selected && isExternalHostOwnedSettingKey(selected.setting.key)) {
482
+ return 'Read-only connected-host setting · Change from GoodVibes TUI or the owning host · Esc close';
483
483
  }
484
484
  return 'Focus settings · Up/Down setting · Left categories · Tab pane · Enter/Space edit/toggle · R reset · Esc close';
485
485
  }
@@ -20,7 +20,7 @@ export function classifySystemMessage(content: string): SystemMessageType {
20
20
  if (/FAILED|cascade abort/i.test(content)) return 'error';
21
21
  // Review failed to reach threshold → warning (yellow, retry in progress)
22
22
  if (/spawning a fix agent/i.test(content)) return 'warning';
23
- // All other WRFC messages (started, passed, auto-committed, gate passed, review ok) → info
23
+ // All other explicit delegated review/build messages classify as info.
24
24
  return 'info';
25
25
  }
26
26