@pellux/goodvibes-agent 0.1.116 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/CHANGELOG.md +48 -661
  2. package/README.md +64 -57
  3. package/bin/goodvibes-agent.ts +16 -2
  4. package/dist/package/main.js +199180 -192185
  5. package/docs/README.md +15 -8
  6. package/docs/channels-remote-and-api.md +50 -0
  7. package/docs/connected-host.md +59 -0
  8. package/docs/getting-started.md +61 -50
  9. package/docs/knowledge-artifacts-and-multimodal.md +91 -0
  10. package/docs/project-planning.md +79 -0
  11. package/docs/providers-and-routing.md +46 -0
  12. package/docs/release-and-publishing.md +48 -11
  13. package/docs/tools-and-commands.md +123 -0
  14. package/docs/voice-and-live-tts.md +51 -0
  15. package/package.json +3 -6
  16. package/src/agent/behavior-discovery-summary.ts +1 -3
  17. package/src/agent/channel-delivery.ts +201 -0
  18. package/src/agent/media-generation.ts +159 -0
  19. package/src/agent/memory-prompt.ts +0 -1
  20. package/src/agent/note-registry.ts +329 -0
  21. package/src/agent/operator-actions.ts +343 -0
  22. package/src/agent/persona-discovery.ts +1 -3
  23. package/src/agent/persona-registry.ts +19 -16
  24. package/src/agent/record-labels.ts +107 -0
  25. package/src/agent/reminder-schedule-format.ts +33 -24
  26. package/src/agent/reminder-schedule.ts +27 -26
  27. package/src/agent/routine-registry.ts +54 -14
  28. package/src/agent/routine-schedule-args.ts +2 -1
  29. package/src/agent/routine-schedule-format.ts +77 -53
  30. package/src/agent/routine-schedule-promotion.ts +35 -33
  31. package/src/agent/routine-schedule-receipts.ts +29 -27
  32. package/src/agent/runtime-profile-starters.ts +5 -5
  33. package/src/agent/runtime-profile.ts +91 -12
  34. package/src/agent/skill-registry.ts +210 -32
  35. package/src/cli/agent-knowledge-args.ts +5 -1
  36. package/src/cli/agent-knowledge-command.ts +40 -34
  37. package/src/cli/agent-knowledge-format.ts +80 -67
  38. package/src/cli/agent-knowledge-methods.ts +1 -1
  39. package/src/cli/agent-knowledge-runtime.ts +32 -26
  40. package/src/cli/bundle-command.ts +14 -9
  41. package/src/cli/config-overrides.ts +37 -36
  42. package/src/cli/entrypoint.ts +16 -7
  43. package/src/cli/external-runtime.ts +10 -4
  44. package/src/cli/help.ts +54 -29
  45. package/src/cli/local-library-command.ts +203 -83
  46. package/src/cli/management-commands.ts +105 -68
  47. package/src/cli/management.ts +55 -74
  48. package/src/cli/memory-command.ts +66 -32
  49. package/src/cli/parser.ts +37 -3
  50. package/src/cli/profiles-command.ts +166 -31
  51. package/src/cli/provider-auth-routes.ts +2 -1
  52. package/src/cli/routines-command.ts +176 -40
  53. package/src/cli/service-posture.ts +16 -16
  54. package/src/cli/status.ts +56 -135
  55. package/src/core/conversation-message-snapshot.ts +131 -0
  56. package/src/input/agent-workspace-access-command-editor-submission.ts +149 -0
  57. package/src/input/agent-workspace-access-command-editors.ts +170 -0
  58. package/src/input/agent-workspace-activation.ts +35 -8
  59. package/src/input/agent-workspace-basic-command-editor-submission.ts +351 -94
  60. package/src/input/agent-workspace-basic-command-editors.ts +502 -9
  61. package/src/input/agent-workspace-categories.ts +423 -51
  62. package/src/input/agent-workspace-channel-command-editor-submission.ts +83 -0
  63. package/src/input/agent-workspace-channel-command-editors.ts +65 -0
  64. package/src/input/agent-workspace-channels.ts +35 -2
  65. package/src/input/agent-workspace-command-editor.ts +41 -3
  66. package/src/input/agent-workspace-config-reader.ts +16 -0
  67. package/src/input/agent-workspace-delegation-editor-submission.ts +55 -0
  68. package/src/input/agent-workspace-editors.ts +166 -1
  69. package/src/input/agent-workspace-knowledge-command-editor-submission.ts +132 -0
  70. package/src/input/agent-workspace-knowledge-command-editors.ts +110 -0
  71. package/src/input/agent-workspace-knowledge-query-editor.ts +1 -1
  72. package/src/input/agent-workspace-learned-behavior.ts +67 -0
  73. package/src/input/agent-workspace-library-command-editor-submission.ts +50 -0
  74. package/src/input/agent-workspace-library-command-editors.ts +35 -0
  75. package/src/input/agent-workspace-local-operations.ts +218 -0
  76. package/src/input/agent-workspace-local-selection.ts +75 -0
  77. package/src/input/agent-workspace-mcp-command-editor-submission.ts +95 -0
  78. package/src/input/agent-workspace-media-command-editor-submission.ts +62 -0
  79. package/src/input/agent-workspace-media-command-editors.ts +27 -0
  80. package/src/input/agent-workspace-memory-command-editor-submission.ts +232 -0
  81. package/src/input/agent-workspace-memory-command-editors.ts +180 -0
  82. package/src/input/agent-workspace-memory-editor.ts +2 -2
  83. package/src/input/agent-workspace-navigation.ts +81 -0
  84. package/src/input/agent-workspace-notify-editor-submission.ts +121 -0
  85. package/src/input/agent-workspace-operations-command-editor-submission.ts +208 -0
  86. package/src/input/agent-workspace-operations-command-editors.ts +196 -0
  87. package/src/input/agent-workspace-panel-route.ts +43 -0
  88. package/src/input/agent-workspace-provider-command-editor-submission.ts +155 -0
  89. package/src/input/agent-workspace-provider-command-editors.ts +93 -0
  90. package/src/input/agent-workspace-reminder-schedule-editor.ts +1 -1
  91. package/src/input/agent-workspace-requirements.ts +11 -0
  92. package/src/input/agent-workspace-routine-schedule-editor.ts +2 -2
  93. package/src/input/agent-workspace-search.ts +169 -0
  94. package/src/input/agent-workspace-secret-editor-submission.ts +153 -0
  95. package/src/input/agent-workspace-session-command-editor-submission.ts +199 -0
  96. package/src/input/agent-workspace-session-command-editors.ts +249 -0
  97. package/src/input/agent-workspace-setup.ts +37 -16
  98. package/src/input/agent-workspace-skill-bundle-command-editor-submission.ts +101 -0
  99. package/src/input/agent-workspace-skill-bundle-command-editors.ts +110 -0
  100. package/src/input/agent-workspace-snapshot.ts +162 -21
  101. package/src/input/agent-workspace-task-command-editor-submission.ts +61 -0
  102. package/src/input/agent-workspace-task-command-editors.ts +47 -0
  103. package/src/input/agent-workspace-token.ts +18 -2
  104. package/src/input/agent-workspace-types.ts +212 -4
  105. package/src/input/agent-workspace-voice-media.ts +4 -7
  106. package/src/input/agent-workspace-web-research-editor.ts +104 -0
  107. package/src/input/agent-workspace-workplan-editor-submission.ts +153 -0
  108. package/src/input/agent-workspace.ts +178 -240
  109. package/src/input/command-registry.ts +5 -2
  110. package/src/input/commands/agent-runtime-profile-runtime.ts +126 -37
  111. package/src/input/commands/agent-skills-runtime.ts +149 -72
  112. package/src/input/commands/agent-workspace-runtime.ts +23 -6
  113. package/src/input/commands/brief-runtime.ts +55 -25
  114. package/src/input/commands/channels-runtime.ts +147 -33
  115. package/src/input/commands/compat-runtime.ts +32 -0
  116. package/src/input/commands/delegation-runtime.ts +29 -23
  117. package/src/input/commands/experience-runtime.ts +6 -4
  118. package/src/input/commands/guidance-runtime.ts +4 -4
  119. package/src/input/commands/health-runtime.ts +149 -126
  120. package/src/input/commands/knowledge.ts +82 -60
  121. package/src/input/commands/local-provider-runtime.ts +43 -21
  122. package/src/input/commands/local-runtime.ts +138 -16
  123. package/src/input/commands/local-setup-review.ts +10 -20
  124. package/src/input/commands/mcp-runtime.ts +63 -46
  125. package/src/input/commands/notify-runtime.ts +38 -9
  126. package/src/input/commands/operator-actions-runtime.ts +138 -0
  127. package/src/input/commands/operator-runtime.ts +6 -76
  128. package/src/input/commands/personas-runtime.ts +46 -31
  129. package/src/input/commands/planning-runtime.ts +1 -1
  130. package/src/input/commands/platform-access-runtime.ts +35 -98
  131. package/src/input/commands/product-runtime.ts +2 -2
  132. package/src/input/commands/provider-accounts-runtime.ts +60 -39
  133. package/src/input/commands/qrcode-runtime.ts +50 -9
  134. package/src/input/commands/recall-bundle.ts +11 -11
  135. package/src/input/commands/recall-capture.ts +13 -11
  136. package/src/input/commands/recall-query.ts +29 -21
  137. package/src/input/commands/recall-review.ts +2 -1
  138. package/src/input/commands/routines-runtime.ts +99 -45
  139. package/src/input/commands/runtime-services.ts +1 -14
  140. package/src/input/commands/schedule-runtime.ts +33 -20
  141. package/src/input/commands/security-runtime.ts +6 -11
  142. package/src/input/commands/session-content.ts +80 -78
  143. package/src/input/commands/session-workflow.ts +134 -104
  144. package/src/input/commands/session.ts +3 -174
  145. package/src/input/commands/shell-core.ts +38 -17
  146. package/src/input/commands/subscription-runtime.ts +54 -185
  147. package/src/input/commands/support-bundle-runtime.ts +53 -0
  148. package/src/input/commands/tasks-runtime.ts +21 -21
  149. package/src/input/commands/work-plan-runtime.ts +33 -8
  150. package/src/input/commands.ts +6 -2
  151. package/src/input/feed-context-factory.ts +2 -2
  152. package/src/input/file-picker.ts +3 -2
  153. package/src/input/handler-command-route.ts +4 -7
  154. package/src/input/handler-content-actions.ts +89 -26
  155. package/src/input/handler-feed-routes.ts +19 -12
  156. package/src/input/handler-feed.ts +6 -5
  157. package/src/input/handler-interactions.ts +9 -36
  158. package/src/input/handler-modal-stack.ts +3 -3
  159. package/src/input/handler-onboarding.ts +52 -91
  160. package/src/input/handler-shortcuts.ts +16 -7
  161. package/src/input/handler.ts +50 -23
  162. package/src/input/input-history.ts +5 -6
  163. package/src/input/keybindings.ts +27 -16
  164. package/src/input/mcp-workspace.ts +90 -26
  165. package/src/input/onboarding/handler-onboarding-routes.ts +3 -1
  166. package/src/input/onboarding/onboarding-wizard-apply.ts +62 -0
  167. package/src/input/onboarding/onboarding-wizard-constants.ts +1 -0
  168. package/src/input/onboarding/onboarding-wizard-helpers.ts +1 -1
  169. package/src/input/onboarding/onboarding-wizard-operator-steps.ts +223 -55
  170. package/src/input/onboarding/onboarding-wizard-steps.ts +59 -35
  171. package/src/input/onboarding/onboarding-wizard-types.ts +4 -1
  172. package/src/input/onboarding/onboarding-wizard.ts +87 -2
  173. package/src/input/profile-picker-modal.ts +31 -12
  174. package/src/input/session-picker-modal.ts +21 -4
  175. package/src/input/settings-modal-agent-policy.ts +6 -6
  176. package/src/input/settings-modal-behavior.ts +0 -3
  177. package/src/input/settings-modal-subscriptions.ts +3 -3
  178. package/src/input/settings-modal-types.ts +2 -13
  179. package/src/input/settings-modal.ts +20 -66
  180. package/src/input/submission-intent.ts +0 -1
  181. package/src/input/submission-router.ts +3 -3
  182. package/src/main.ts +18 -10
  183. package/src/panels/approval-panel.ts +8 -8
  184. package/src/panels/automation-control-panel.ts +4 -4
  185. package/src/panels/base-panel.ts +1 -1
  186. package/src/panels/builtin/agent.ts +1 -1
  187. package/src/panels/builtin/operations.ts +3 -12
  188. package/src/panels/builtin/session.ts +32 -24
  189. package/src/panels/builtin/shared.ts +7 -7
  190. package/src/panels/cost-tracker-panel.ts +1 -1
  191. package/src/panels/docs-panel.ts +5 -3
  192. package/src/panels/index.ts +0 -1
  193. package/src/panels/knowledge-panel.ts +6 -5
  194. package/src/panels/memory-panel.ts +7 -6
  195. package/src/panels/panel-list-panel.ts +36 -80
  196. package/src/panels/project-planning-panel.ts +19 -12
  197. package/src/panels/provider-account-snapshot.ts +51 -25
  198. package/src/panels/provider-accounts-panel.ts +33 -18
  199. package/src/panels/provider-health-domains.ts +48 -7
  200. package/src/panels/provider-health-panel.ts +5 -4
  201. package/src/panels/qr-panel.ts +44 -20
  202. package/src/panels/schedule-panel.ts +9 -17
  203. package/src/panels/security-panel.ts +8 -8
  204. package/src/panels/session-browser-panel.ts +10 -10
  205. package/src/panels/subscription-panel.ts +6 -6
  206. package/src/panels/system-messages-panel.ts +3 -3
  207. package/src/panels/tasks-panel.ts +21 -14
  208. package/src/panels/tool-inspector-panel.ts +19 -12
  209. package/src/panels/work-plan-panel.ts +5 -5
  210. package/src/planning/project-planning-coordinator.ts +3 -3
  211. package/src/provider-auth-route-display.ts +9 -0
  212. package/src/renderer/agent-workspace-style.ts +34 -0
  213. package/src/renderer/agent-workspace.ts +254 -57
  214. package/src/renderer/autocomplete-overlay.ts +25 -6
  215. package/src/renderer/block-actions.ts +1 -3
  216. package/src/renderer/bookmark-modal.ts +19 -4
  217. package/src/renderer/buffer.ts +4 -2
  218. package/src/renderer/context-inspector.ts +50 -13
  219. package/src/renderer/diff.ts +1 -1
  220. package/src/renderer/file-picker-overlay.ts +19 -6
  221. package/src/renderer/help-overlay.ts +112 -34
  222. package/src/renderer/history-search-overlay.ts +19 -4
  223. package/src/renderer/live-tail-modal.ts +27 -5
  224. package/src/renderer/mcp-workspace.ts +176 -43
  225. package/src/renderer/model-picker-overlay.ts +58 -3
  226. package/src/renderer/model-workspace.ts +104 -22
  227. package/src/renderer/onboarding/onboarding-wizard.ts +20 -4
  228. package/src/renderer/process-modal.ts +27 -6
  229. package/src/renderer/profile-picker-modal.ts +21 -5
  230. package/src/renderer/search-overlay.ts +25 -5
  231. package/src/renderer/selection-modal-overlay.ts +46 -14
  232. package/src/renderer/session-picker-modal.ts +18 -1
  233. package/src/renderer/settings-modal-helpers.ts +2 -40
  234. package/src/renderer/settings-modal.ts +88 -55
  235. package/src/renderer/system-message.ts +1 -1
  236. package/src/renderer/tool-call.ts +20 -11
  237. package/src/runtime/agent-runtime-events.ts +129 -0
  238. package/src/runtime/bootstrap-command-context.ts +7 -1
  239. package/src/runtime/bootstrap-command-parts.ts +11 -8
  240. package/src/runtime/bootstrap-core.ts +23 -65
  241. package/src/runtime/bootstrap-hook-bridge.ts +7 -18
  242. package/src/runtime/bootstrap-shell.ts +46 -8
  243. package/src/runtime/bootstrap.ts +36 -46
  244. package/src/runtime/connected-host-auth.ts +47 -0
  245. package/src/runtime/diagnostics/panels/index.ts +2 -2
  246. package/src/runtime/diagnostics/panels/panel-resources.ts +1 -1
  247. package/src/runtime/diagnostics/panels/policy.ts +7 -7
  248. package/src/runtime/index.ts +2 -5
  249. package/src/runtime/onboarding/apply-file-helpers.ts +66 -0
  250. package/src/runtime/onboarding/apply.ts +288 -74
  251. package/src/runtime/onboarding/derivation.ts +10 -13
  252. package/src/runtime/onboarding/snapshot.ts +2 -17
  253. package/src/runtime/onboarding/types.ts +34 -20
  254. package/src/runtime/onboarding/verify.ts +105 -4
  255. package/src/runtime/operator-token-cleanup.ts +3 -3
  256. package/src/runtime/services.ts +95 -11
  257. package/src/runtime/store/selectors/index.ts +3 -3
  258. package/src/runtime/store/state.ts +1 -4
  259. package/src/runtime/surface-feature-flags.ts +41 -6
  260. package/src/runtime/ui-read-models.ts +3 -4
  261. package/src/runtime/ui-services.ts +6 -6
  262. package/src/shell/blocking-input.ts +2 -1
  263. package/src/shell/service-settings-sync.ts +7 -7
  264. package/src/shell/ui-openers.ts +17 -38
  265. package/src/tools/agent-analysis-registry-policy.ts +0 -1
  266. package/src/tools/agent-channel-send-tool.ts +133 -0
  267. package/src/tools/agent-context-policy.ts +1 -1
  268. package/src/tools/agent-knowledge-ingest-tool.ts +405 -0
  269. package/src/tools/agent-knowledge-tool.ts +170 -0
  270. package/src/tools/agent-local-registry-tool.ts +279 -73
  271. package/src/tools/agent-media-generate-tool.ts +133 -0
  272. package/src/tools/agent-notify-tool.ts +143 -0
  273. package/src/tools/agent-operator-action-tool.ts +137 -0
  274. package/src/tools/agent-operator-briefing-tool.ts +217 -0
  275. package/src/tools/agent-reminder-schedule-tool.ts +237 -0
  276. package/src/tools/agent-tool-policy-guard.ts +13 -15
  277. package/src/tools/agent-work-plan-tool.ts +256 -0
  278. package/src/version.ts +1 -1
  279. package/docs/connected-services.md +0 -51
  280. package/src/cli/package-verification.ts +0 -274
  281. package/src/input/commands/policy-dispatch.ts +0 -339
  282. package/src/input/commands/policy.ts +0 -17
  283. package/src/panels/panel-picker.ts +0 -105
  284. package/src/panels/policy-panel.ts +0 -308
  285. package/src/renderer/panel-picker-overlay.ts +0 -202
@@ -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
  }
@@ -15,6 +15,11 @@ export interface ProcessEntry {
15
15
 
16
16
  const MAX_LABEL_LENGTH = 80;
17
17
  const MODAL_BORDER_WIDTH = 8;
18
+ const PROCESS_MODAL_TITLE = 'Runtime Activity';
19
+ const PROCESS_MODAL_EMPTY_MESSAGE = 'No running shell processes.';
20
+ const PROCESS_MODAL_EMPTY_HINTS = ['[Esc] Close'];
21
+ const PROCESS_MODAL_ACTIVE_HINTS = ['[Up/Down] Navigate', '[Enter] Output', '[k] Stop process', '[Esc] Close'];
22
+ const PROCESS_MODAL_TYPE_TAG = '[exec]';
18
23
 
19
24
  export interface ProcessModalDeps {
20
25
  readonly processManager: Pick<ProcessManager, 'list' | 'getStatus' | 'stop'>;
@@ -101,6 +106,22 @@ export class ProcessModal {
101
106
  }
102
107
  }
103
108
 
109
+ export function renderProcessModalPackageText(): string {
110
+ return [
111
+ PROCESS_MODAL_TITLE,
112
+ PROCESS_MODAL_EMPTY_MESSAGE,
113
+ PROCESS_MODAL_TYPE_TAG,
114
+ '*',
115
+ '!',
116
+ '-',
117
+ 'running',
118
+ 'failed',
119
+ '<duration>',
120
+ ...PROCESS_MODAL_EMPTY_HINTS,
121
+ ...PROCESS_MODAL_ACTIVE_HINTS,
122
+ ].join('\n');
123
+ }
124
+
104
125
  export function renderProcessModal(modal: ProcessModal, width: number, viewportHeight = 24): Line[] {
105
126
  modal.refresh();
106
127
 
@@ -118,14 +139,14 @@ export function renderProcessModal(modal: ProcessModal, width: number, viewportH
118
139
 
119
140
  if (modal.entries.length === 0) {
120
141
  return ModalFactory.createModal({
121
- title: 'Runtime Activity',
142
+ title: PROCESS_MODAL_TITLE,
122
143
  width: boxW,
123
144
  margin: boxMargin,
124
145
  targetContentRows,
125
146
  sections: [
126
- { type: 'text', content: 'No running shell processes.' },
147
+ { type: 'text', content: PROCESS_MODAL_EMPTY_MESSAGE },
127
148
  ],
128
- hints: ['[Esc] Close'],
149
+ hints: PROCESS_MODAL_EMPTY_HINTS,
129
150
  }, width);
130
151
  }
131
152
 
@@ -138,7 +159,7 @@ export function renderProcessModal(modal: ProcessModal, width: number, viewportH
138
159
  const statusIcon = entry.status === 'running' ? '*' : entry.status === 'failed' ? '!' : '-';
139
160
  const dur = formatDuration(entry.elapsedMs);
140
161
  const suffix = ` ${entry.status} ${dur}`;
141
- const typeTag = '[exec]';
162
+ const typeTag = PROCESS_MODAL_TYPE_TAG;
142
163
  const maxDescW = Math.max(0, maxLabelW - typeTag.length - suffix.length - 4);
143
164
  const desc = entry.label.length > maxDescW ? `${entry.label.slice(0, Math.max(0, maxDescW - 3))}...` : entry.label;
144
165
  return {
@@ -150,7 +171,7 @@ export function renderProcessModal(modal: ProcessModal, width: number, viewportH
150
171
  if (modal.entries.length > maxVisibleRows) sections.push({ type: 'separator' });
151
172
 
152
173
  return ModalFactory.createModal({
153
- title: 'Runtime Activity',
174
+ title: PROCESS_MODAL_TITLE,
154
175
  width: boxW,
155
176
  margin: boxMargin,
156
177
  targetContentRows,
@@ -158,6 +179,6 @@ export function renderProcessModal(modal: ProcessModal, width: number, viewportH
158
179
  helpers: modal.entries.length > maxVisibleRows
159
180
  ? [{ content: `[${window.start + 1}-${window.end} of ${modal.entries.length}]` }]
160
181
  : undefined,
161
- hints: ['[Up/Down] Navigate', '[Enter] Output', '[k] Stop process', '[Esc] Close'],
182
+ hints: PROCESS_MODAL_ACTIVE_HINTS,
162
183
  }, width);
163
184
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * renderProfilePickerModal — renders the /profiles picker modal as Line[]
2
+ * renderProfilePickerModal — renders the Agent profile picker modal as Line[]
3
3
  * using ModalFactory.
4
4
  *
5
5
  * Shows a list of saved profiles with:
@@ -10,6 +10,7 @@
10
10
  import type { Line } from '../types/grid.ts';
11
11
  import { ModalFactory } from './modal-factory.ts';
12
12
  import type { ProfilePickerModal } from '../input/profile-picker-modal.ts';
13
+ import { renderProfilePickerStatePackageText } from '../input/profile-picker-modal.ts';
13
14
  import { formatTimestamp } from './modal-utils.ts';
14
15
  import { fitDisplay } from '../utils/terminal-width.ts';
15
16
  import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay-viewport.ts';
@@ -18,6 +19,23 @@ import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay
18
19
  // Renderer
19
20
  // ---------------------------------------------------------------------------
20
21
 
22
+ export function renderProfilePickerPackageText(): string {
23
+ return [
24
+ 'Profiles',
25
+ 'No saved profiles.',
26
+ 'Open Agent Workspace -> Profiles to create and manage isolated Agent profile homes.',
27
+ 'Name',
28
+ 'Saved',
29
+ 'Settings',
30
+ '(display/provider/behavior)',
31
+ '[Up/Down] Navigate',
32
+ '[Enter] Load',
33
+ 'Agent profiles: /agent profiles',
34
+ '[Esc] Close',
35
+ renderProfilePickerStatePackageText(),
36
+ ].join('\n');
37
+ }
38
+
21
39
  /**
22
40
  * Render the profile picker modal as Line[] for overlay in the viewport.
23
41
  *
@@ -51,7 +69,7 @@ export function renderProfilePickerModal(
51
69
  });
52
70
  sections.push({
53
71
  type: 'text',
54
- content: 'Use /profiles save <name> --yes to save the current settings as a profile.',
72
+ content: 'Open Agent Workspace -> Profiles to create and manage isolated Agent profile homes.',
55
73
  style: { fg: '240', dim: true },
56
74
  });
57
75
  } else {
@@ -79,8 +97,6 @@ export function renderProfilePickerModal(
79
97
 
80
98
  const tsStr = fitDisplay(formatTimestamp(prof.timestamp), tsW);
81
99
 
82
- // Read the profile file to get a preview of settings
83
- // (We only have name/timestamp in ProfileInfo, so show a placeholder)
84
100
  const preview = fitDisplay('(display/provider/behavior)', previewW);
85
101
 
86
102
  const label = `${nameStr} ${tsStr} ${preview}`;
@@ -114,7 +130,7 @@ export function renderProfilePickerModal(
114
130
  margin: boxMargin,
115
131
  targetContentRows,
116
132
  sections,
117
- hints: ['[Up/Down] Navigate', '[Enter] Load', '/profiles save|delete --yes', '[Esc] Close'],
133
+ hints: ['[Up/Down] Navigate', '[Enter] Load', 'Agent profiles: /agent profiles', '[Esc] Close'],
118
134
  },
119
135
  width,
120
136
  );
@@ -3,6 +3,26 @@ import { fitDisplay, getDisplayWidth, truncateDisplay } from '../utils/terminal-
3
3
  import type { SearchManager } from '../input/search.ts';
4
4
  import { createBottomBarLine, writeBottomBarText } from './bottom-bar.ts';
5
5
 
6
+ const SEARCH_OVERLAY_LABEL = ' Find: ';
7
+ const SEARCH_OVERLAY_NO_MATCHES = 'No matches';
8
+ const SEARCH_OVERLAY_COUNT_SUFFIX = 'up/down';
9
+ const SEARCH_OVERLAY_LOCKED_HINTS = ' [Up/Down] or [jk] navigate [Bksp] edit [Esc] close';
10
+ const SEARCH_OVERLAY_UNLOCKED_HINTS = ' [Enter/Tab] lock [Esc] close';
11
+
12
+ function searchOverlayMatchCount(current: string | number, total: string | number): string {
13
+ return `${current}/${total} ${SEARCH_OVERLAY_COUNT_SUFFIX}`;
14
+ }
15
+
16
+ export function renderSearchOverlayPackageText(): string {
17
+ return [
18
+ SEARCH_OVERLAY_LABEL.trim(),
19
+ searchOverlayMatchCount('<current>', '<total>'),
20
+ SEARCH_OVERLAY_NO_MATCHES,
21
+ SEARCH_OVERLAY_LOCKED_HINTS.trim(),
22
+ SEARCH_OVERLAY_UNLOCKED_HINTS.trim(),
23
+ ].join('\n');
24
+ }
25
+
6
26
  /**
7
27
  * Render the search bar as a single Line[] overlay at the bottom of the viewport.
8
28
  * Format: [ Find: <query> 3/17 up/down [n] next [N] prev [Esc] close ]
@@ -14,18 +34,18 @@ export function renderSearchOverlay(
14
34
  ): Line[] {
15
35
  // Match count text — displayed in dim grey, right of query, left of hints
16
36
  const matchCount = manager.matches?.length > 0
17
- ? `${manager.currentMatch + 1}/${manager.matches.length} up/down`
37
+ ? searchOverlayMatchCount(manager.currentMatch + 1, manager.matches.length)
18
38
  : manager.query.length > 0
19
- ? 'No matches'
39
+ ? SEARCH_OVERLAY_NO_MATCHES
20
40
  : '';
21
41
 
22
42
  const locked = manager.locked;
23
43
  const cursor = locked ? '' : '█';
24
44
  const queryDisplay = manager.query + cursor;
25
45
  const hints = locked
26
- ? ' [Up/Down] or [jk] navigate [Bksp] edit [Esc] close'
27
- : ' [Enter/Tab] lock [Esc] close';
28
- const label = ' Find: ';
46
+ ? SEARCH_OVERLAY_LOCKED_HINTS
47
+ : SEARCH_OVERLAY_UNLOCKED_HINTS;
48
+ const label = SEARCH_OVERLAY_LABEL;
29
49
  const matchStr = matchCount ? ` ${matchCount}` : '';
30
50
 
31
51
  // Build left portion: label + query (no match count — that gets separate styling)
@@ -1,6 +1,6 @@
1
1
  import { type Line } from '../types/grid.ts';
2
2
  import { fitDisplay, getDisplayWidth, truncateDisplay } from '../utils/terminal-width.ts';
3
- import type { SelectionModal } from '../input/selection-modal.ts';
3
+ import type { SelectionAction, SelectionModal } from '../input/selection-modal.ts';
4
4
  import {
5
5
  createOverlayBoxLayout,
6
6
  createOverlayContentLine,
@@ -18,6 +18,14 @@ const BODY_FG = DEFAULT_OVERLAY_PALETTE.bodyFg;
18
18
  const MUTED_FG = DEFAULT_OVERLAY_PALETTE.mutedFg;
19
19
  const CATEGORY_FG = '#4488cc';
20
20
  const SELECTED_BG = DEFAULT_OVERLAY_PALETTE.selectedBg;
21
+ const SELECTION_MODAL_SEARCH_LABEL = ' Search';
22
+ const SELECTION_MODAL_RESULTS_LABEL = ' Results';
23
+ const SELECTION_MODAL_NO_MATCHING_ITEMS = 'No matching items';
24
+ const SELECTION_MODAL_NO_ITEMS = 'No items';
25
+ const SELECTION_MODAL_NAVIGATION_HINT = '[Up/Down] Navigate';
26
+ const SELECTION_MODAL_CLOSE_HINT = '[Esc] Close';
27
+ const SELECTION_MODAL_SEARCH_HINT = '[/] Search';
28
+ const SELECTION_MODAL_SPACE_TOGGLE_HINT = '[Space] Toggle';
21
29
 
22
30
  interface CellStyle {
23
31
  fg: string;
@@ -30,6 +38,36 @@ function putText(line: Line, startX: number, maxWidth: number, text: string, sty
30
38
  putOverlayText(line, startX, maxWidth, text, style);
31
39
  }
32
40
 
41
+ function primaryVerbForAction(primaryAction: SelectionAction | undefined): string {
42
+ return primaryAction === 'toggle'
43
+ ? '[Enter] Toggle'
44
+ : primaryAction === 'edit'
45
+ ? '[Enter] Edit'
46
+ : primaryAction === 'delete'
47
+ ? '[Enter] Delete'
48
+ : '[Enter] Select';
49
+ }
50
+
51
+ export function renderSelectionModalPackageText(): string {
52
+ return [
53
+ SELECTION_MODAL_SEARCH_LABEL.trim(),
54
+ SELECTION_MODAL_RESULTS_LABEL.trim(),
55
+ SELECTION_MODAL_NO_MATCHING_ITEMS,
56
+ SELECTION_MODAL_NO_ITEMS,
57
+ '(<above> above, <below> below)',
58
+ '(<below> below)',
59
+ '(<above> above)',
60
+ SELECTION_MODAL_NAVIGATION_HINT,
61
+ primaryVerbForAction(undefined),
62
+ primaryVerbForAction('toggle'),
63
+ primaryVerbForAction('edit'),
64
+ primaryVerbForAction('delete'),
65
+ SELECTION_MODAL_CLOSE_HINT,
66
+ SELECTION_MODAL_SEARCH_HINT,
67
+ SELECTION_MODAL_SPACE_TOGGLE_HINT,
68
+ ].join('\n');
69
+ }
70
+
33
71
  /**
34
72
  * Render the selection modal as Line[] for overlay in the viewport.
35
73
  */
@@ -62,7 +100,7 @@ export function renderSelectionModalOverlay(
62
100
 
63
101
  if (modal.allowSearch) {
64
102
  const labelLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
65
- putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(' Search', layout.innerWidth), {
103
+ putText(labelLine, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_SEARCH_LABEL, layout.innerWidth), {
66
104
  fg: CATEGORY_FG,
67
105
  dim: true,
68
106
  });
@@ -86,7 +124,7 @@ export function renderSelectionModalOverlay(
86
124
  }
87
125
 
88
126
  const listTitle = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
89
- putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(' Results', layout.innerWidth), {
127
+ putText(listTitle, layout.margin + 2, layout.innerWidth, fitDisplay(SELECTION_MODAL_RESULTS_LABEL, layout.innerWidth), {
90
128
  fg: CATEGORY_FG,
91
129
  dim: true,
92
130
  });
@@ -95,7 +133,7 @@ export function renderSelectionModalOverlay(
95
133
  const items = modal.filteredItems;
96
134
  if (items.length === 0) {
97
135
  const line = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.bodyBg);
98
- const message = modal.query ? 'No matching items' : 'No items';
136
+ const message = modal.query ? SELECTION_MODAL_NO_MATCHING_ITEMS : SELECTION_MODAL_NO_ITEMS;
99
137
  putText(line, layout.margin + 2, layout.innerWidth, fitDisplay(message, layout.innerWidth), { fg: MUTED_FG, dim: true });
100
138
  lines.push(line);
101
139
  } else {
@@ -189,16 +227,10 @@ export function renderSelectionModalOverlay(
189
227
 
190
228
  const footerLine = createOverlayContentLine(width, layout, BORDER_FG, DEFAULT_OVERLAY_PALETTE.sectionBg);
191
229
  const selectedItem = modal.getSelected();
192
- const primaryVerb = selectedItem?.primaryAction === 'toggle'
193
- ? '[Enter] Toggle'
194
- : selectedItem?.primaryAction === 'edit'
195
- ? '[Enter] Edit'
196
- : selectedItem?.primaryAction === 'delete'
197
- ? '[Enter] Delete'
198
- : '[Enter] Select';
199
- let hints = `[Up/Down] Navigate ${primaryVerb} [Esc] Close`;
200
- if (modal.allowSearch) hints += ' [/] Search';
201
- if (selectedItem?.primaryAction === 'toggle' && !selectedItem.actions) hints += ' [Space] Toggle';
230
+ const primaryVerb = primaryVerbForAction(selectedItem?.primaryAction);
231
+ let hints = `${SELECTION_MODAL_NAVIGATION_HINT} ${primaryVerb} ${SELECTION_MODAL_CLOSE_HINT}`;
232
+ if (modal.allowSearch) hints += ` ${SELECTION_MODAL_SEARCH_HINT}`;
233
+ if (selectedItem?.primaryAction === 'toggle' && !selectedItem.actions) hints += ` ${SELECTION_MODAL_SPACE_TOGGLE_HINT}`;
202
234
  if (selectedItem?.actions) hints += ` ${selectedItem.actions}`;
203
235
  putText(
204
236
  footerLine,
@@ -10,6 +10,7 @@
10
10
  import type { Line } from '../types/grid.ts';
11
11
  import { ModalFactory } from './modal-factory.ts';
12
12
  import type { SessionPickerModal } from '../input/session-picker-modal.ts';
13
+ import { renderSessionPickerStatePackageText } from '../input/session-picker-modal.ts';
13
14
  import { formatTimestamp } from './modal-utils.ts';
14
15
  import { fitDisplay } from '../utils/terminal-width.ts';
15
16
  import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay-viewport.ts';
@@ -18,6 +19,22 @@ import { getOverlaySurfaceMetrics, getStableOverlayContentRows } from './overlay
18
19
  // Renderer
19
20
  // ---------------------------------------------------------------------------
20
21
 
22
+ export function renderSessionPickerPackageText(): string {
23
+ return [
24
+ 'Sessions',
25
+ 'No saved sessions.',
26
+ 'Open Agent Workspace -> Conversation -> Save current session.',
27
+ 'Name',
28
+ 'Saved',
29
+ 'Msgs',
30
+ '[\u2191\u2193] Navigate',
31
+ '[Enter] Load',
32
+ 'Delete: /session delete <id> --yes',
33
+ '[Esc] Close',
34
+ renderSessionPickerStatePackageText(),
35
+ ].join('\n');
36
+ }
37
+
21
38
  /**
22
39
  * Render the session picker modal as Line[] for overlay in the viewport.
23
40
  *
@@ -51,7 +68,7 @@ export function renderSessionPickerModal(
51
68
  });
52
69
  sections.push({
53
70
  type: 'text',
54
- content: 'Use /save [name] to save the current session.',
71
+ content: 'Open Agent Workspace -> Conversation -> Save current session.',
55
72
  style: { fg: '240', dim: true },
56
73
  });
57
74
  } else {
@@ -82,33 +82,21 @@ export const CATEGORY_LABELS: Record<(typeof SETTINGS_CATEGORIES)[number], strin
82
82
  behavior: 'Behavior',
83
83
  storage: 'Storage',
84
84
  permissions: 'Permissions',
85
- orchestration: 'Orchestration',
86
- wrfc: 'WRFC Delegation',
87
85
  helper: 'Helper',
88
86
  tts: 'TTS',
89
- service: 'Runtime Install',
90
- controlPlane: 'Runtime API',
91
- httpListener: 'Inbound Events',
92
- web: 'Browser Companion',
93
- batch: 'Batch',
94
87
  automation: 'Automation',
95
- watchers: 'Watchers',
96
- runtime: 'Runtime',
97
88
  telemetry: 'Telemetry',
98
89
  cache: 'Cache',
99
90
  mcp: 'MCP',
100
91
  surfaces: 'Channels',
101
- release: 'Release',
102
- danger: 'Danger',
92
+ release: 'Update Channel',
103
93
  tools: 'Tools',
104
- flags: 'Feature Flags',
105
- network: 'Network',
94
+ flags: 'Feature Controls',
106
95
  };
107
96
 
108
97
  export const SETTING_LABELS: Partial<Record<string, string>> = {
109
98
  'ui.systemMessages': 'System Message Target',
110
99
  'ui.operationalMessages': 'Operational Message Target',
111
- 'ui.wrfcMessages': 'Delegated WRFC Message Target',
112
100
  'ui.voiceEnabled': 'Voice Interaction',
113
101
  'behavior.autoCompactThreshold': 'Auto-Compact %',
114
102
  'behavior.staleContextWarnings': 'Context Warnings',
@@ -123,32 +111,6 @@ export const SETTING_LABELS: Partial<Record<string, string>> = {
123
111
  'helper.enabled': 'Helper Enabled',
124
112
  'helper.globalProvider': 'Helper Provider',
125
113
  'helper.globalModel': 'Helper Model',
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',
145
- // Browser companion
146
- 'web.enabled': 'Web Enabled',
147
- 'web.hostMode': 'Web Host Mode',
148
- 'web.host': 'Web Host',
149
- 'web.port': 'Web Port',
150
- 'web.publicBaseUrl': 'Web Public Base URL',
151
- 'web.staticAssetsDir': 'Web Static Assets Dir',
152
114
  'surfaces.ntfy.enabled': 'ntfy Enabled',
153
115
  'surfaces.ntfy.baseUrl': 'ntfy Base URL',
154
116
  'surfaces.ntfy.topic': 'ntfy Default Delivery Topic',