@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
@@ -2,6 +2,7 @@ import type { MemoryApi } from '@pellux/goodvibes-sdk/platform/knowledge';
2
2
  import type { MemoryRecord } from '@pellux/goodvibes-sdk/platform/state';
3
3
  import type { ShellPathService } from '@/runtime/index.ts';
4
4
  import type { CommandContext } from './command-registry.ts';
5
+ import { AgentNoteRegistry } from '../agent/note-registry.ts';
5
6
  import { AgentPersonaRegistry } from '../agent/persona-registry.ts';
6
7
  import { AgentRoutineRegistry } from '../agent/routine-registry.ts';
7
8
  import { createAgentRuntimeProfile, type AgentRuntimeProfileInfo } from '../agent/runtime-profile.ts';
@@ -9,26 +10,19 @@ import { AgentSkillRegistry } from '../agent/skill-registry.ts';
9
10
  import { activateAgentWorkspaceSelection } from './agent-workspace-activation.ts';
10
11
  import { AGENT_WORKSPACE_CATEGORIES } from './agent-workspace-categories.ts';
11
12
  import { buildAgentWorkspaceCommandEditorSubmission, isAgentWorkspaceCommandEditorKind } from './agent-workspace-command-editor.ts';
12
- import { quoteSlashCommandArg } from './slash-command-parser.ts';
13
- import { createDeleteEditor, createMemoryUpdateEditor, createPersonaUpdateEditor, createRoutineUpdateEditor, createSkillUpdateEditor, editorCategoryId, isAffirmative, splitList } from './agent-workspace-editors.ts';
13
+ import { createDeleteEditor, editorCategoryId, isAffirmative, splitList } from './agent-workspace-editors.ts';
14
+ import { createAgentWorkspaceLearnedBehavior } from './agent-workspace-learned-behavior.ts';
15
+ import { clampAgentWorkspaceLocalLibrarySelection, moveAgentWorkspaceLocalLibraryItemSelection, selectedAgentWorkspaceLocalLibraryItem, type AgentWorkspaceLocalSelectionIndexes } from './agent-workspace-local-selection.ts';
16
+ import { applyAgentWorkspaceLocalLibraryOperation } from './agent-workspace-local-operations.ts';
14
17
  import { deleteAgentWorkspaceMemoryEditor, submitAgentWorkspaceMemoryEditor } from './agent-workspace-memory-editor.ts';
18
+ import { jumpAgentWorkspaceSelection, moveAgentWorkspaceSelection, selectAgentWorkspaceCategory } from './agent-workspace-navigation.ts';
19
+ import { buildAgentWorkspaceRequirements } from './agent-workspace-requirements.ts';
20
+ import { appendAgentWorkspaceActionSearchText, backspaceAgentWorkspaceActionSearch, beginAgentWorkspaceActionSearch, clearAgentWorkspaceActionSearch, commitAgentWorkspaceActionSearchSelection, searchAgentWorkspaceActions } from './agent-workspace-search.ts';
15
21
  import { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
16
- import type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceCategory, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
22
+ import type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceActionSearchResult, AgentWorkspaceCategory, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspacePromptDispatcher, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
17
23
 
18
24
  export type { AgentWorkspaceChannelRisk, AgentWorkspaceChannelStatus } from './agent-workspace-channels.ts';
19
- export type {
20
- AgentWorkspaceAction,
21
- AgentWorkspaceActionResult,
22
- AgentWorkspaceCategory,
23
- AgentWorkspaceCommandDispatcher,
24
- AgentWorkspaceEditorField,
25
- AgentWorkspaceFocusPane,
26
- AgentWorkspaceLocalEditor,
27
- AgentWorkspaceLocalEditorKind,
28
- AgentWorkspaceLocalLibraryItem,
29
- AgentWorkspaceLocalOperation,
30
- AgentWorkspaceRuntimeSnapshot,
31
- } from './agent-workspace-types.ts';
25
+ export type { AgentWorkspaceAction, AgentWorkspaceActionResult, AgentWorkspaceActionSearchResult, AgentWorkspaceCategory, AgentWorkspaceCategoryId, AgentWorkspaceCommandDispatcher, AgentWorkspaceEditorField, AgentWorkspaceFocusPane, AgentWorkspaceLocalEditor, AgentWorkspaceLocalEditorKind, AgentWorkspaceLocalLibraryItem, AgentWorkspaceLocalOperation, AgentWorkspacePromptDispatcher, AgentWorkspaceRuntimeSnapshot } from './agent-workspace-types.ts';
32
26
  export { AGENT_WORKSPACE_MODAL_NAME } from './agent-workspace-types.ts';
33
27
  export { buildAgentWorkspaceRuntimeSnapshot } from './agent-workspace-snapshot.ts';
34
28
  export { handleAgentWorkspaceToken } from './agent-workspace-token.ts';
@@ -42,8 +36,11 @@ export class AgentWorkspace {
42
36
  public runtimeSnapshot: AgentWorkspaceRuntimeSnapshot | null = null;
43
37
  public lastActionResult: AgentWorkspaceActionResult | null = null;
44
38
  public localEditor: AgentWorkspaceLocalEditor | null = null;
45
- private readonly selectedLibraryItemIndexes: Record<AgentWorkspaceLocalEditorKind, number> = {
39
+ public actionSearchActive = false;
40
+ public actionSearchQuery = '';
41
+ public readonly selectedLibraryItemIndexes: AgentWorkspaceLocalSelectionIndexes = {
46
42
  memory: 0,
43
+ note: 0,
47
44
  persona: 0,
48
45
  skill: 0,
49
46
  routine: 0,
@@ -51,16 +48,30 @@ export class AgentWorkspace {
51
48
  };
52
49
  private context: CommandContext | null = null;
53
50
  private dispatchCommand: AgentWorkspaceCommandDispatcher | null = null;
51
+ private dispatchPrompt: AgentWorkspacePromptDispatcher | null = null;
54
52
 
55
- open(context: CommandContext, dispatchCommand: AgentWorkspaceCommandDispatcher): void {
53
+ open(context: CommandContext, dispatchCommand: AgentWorkspaceCommandDispatcher, categoryId?: string, dispatchPrompt?: AgentWorkspacePromptDispatcher): void {
56
54
  this.context = context;
57
55
  this.dispatchCommand = dispatchCommand;
56
+ this.dispatchPrompt = dispatchPrompt ?? null;
58
57
  this.runtimeSnapshot = buildAgentWorkspaceRuntimeSnapshot(context);
59
58
  this.active = true;
60
59
  this.focusPane = 'actions';
61
60
  this.status = 'Ready. Choose an operator flow; ordinary assistant work stays in the main conversation.';
62
61
  this.lastActionResult = null;
63
62
  this.localEditor = null;
63
+ this.actionSearchActive = false;
64
+ this.actionSearchQuery = '';
65
+ if (categoryId && !this.selectCategory(categoryId)) {
66
+ const normalized = categoryId.trim();
67
+ this.status = `Unknown Agent workspace area: ${normalized}`;
68
+ this.lastActionResult = {
69
+ kind: 'guidance',
70
+ title: 'Unknown Agent workspace area',
71
+ detail: `Use one of ${this.categories.map((category) => category.id).join(', ')}.`,
72
+ safety: 'safe',
73
+ };
74
+ }
64
75
  this.clampSelection();
65
76
  }
66
77
 
@@ -72,6 +83,8 @@ export class AgentWorkspace {
72
83
  close(): void {
73
84
  this.active = false;
74
85
  this.localEditor = null;
86
+ this.actionSearchActive = false;
87
+ this.actionSearchQuery = '';
75
88
  }
76
89
 
77
90
  get categories(): readonly AgentWorkspaceCategory[] {
@@ -83,6 +96,7 @@ export class AgentWorkspace {
83
96
  }
84
97
 
85
98
  get actions(): readonly AgentWorkspaceAction[] {
99
+ if (this.actionSearchActive) return this.actionSearchResults.map((result) => result.action);
86
100
  return this.selectedCategory.actions;
87
101
  }
88
102
 
@@ -90,11 +104,37 @@ export class AgentWorkspace {
90
104
  return this.actions[this.selectedActionIndex] ?? null;
91
105
  }
92
106
 
107
+ get selectedActionCategory(): AgentWorkspaceCategory {
108
+ if (this.actionSearchActive) return this.selectedActionSearchResult?.category ?? this.selectedCategory;
109
+ return this.selectedCategory;
110
+ }
111
+
112
+ get actionSearchResults(): readonly AgentWorkspaceActionSearchResult[] {
113
+ return this.actionSearchActive ? searchAgentWorkspaceActions(this.categories, this.actionSearchQuery) : [];
114
+ }
115
+
116
+ get selectedActionSearchResult(): AgentWorkspaceActionSearchResult | null {
117
+ if (!this.actionSearchActive) return null;
118
+ return this.actionSearchResults[this.selectedActionIndex] ?? null;
119
+ }
120
+
121
+ selectCategory(categoryIdOrLabel: string): boolean {
122
+ return selectAgentWorkspaceCategory(this, categoryIdOrLabel);
123
+ }
124
+
125
+ cycleCategory(direction: 'next' | 'prev'): void {
126
+ const total = this.categories.length;
127
+ if (total === 0) return;
128
+ const delta = direction === 'next' ? 1 : -1;
129
+ this.selectedCategoryIndex = (this.selectedCategoryIndex + delta + total) % total;
130
+ this.selectedActionIndex = 0;
131
+ this.focusPane = 'actions';
132
+ this.clampSelection();
133
+ this.status = `Agent workspace category: ${this.selectedCategory.label}.`;
134
+ }
135
+
93
136
  selectedLocalLibraryItem(kind: AgentWorkspaceLocalEditorKind): AgentWorkspaceLocalLibraryItem | null {
94
- const items = this.localLibraryItems(kind);
95
- if (items.length === 0) return null;
96
- const index = Math.max(0, Math.min(this.selectedLibraryItemIndexes[kind], items.length - 1));
97
- return items[index] ?? null;
137
+ return selectedAgentWorkspaceLocalLibraryItem(this.runtimeSnapshot, this.selectedLibraryItemIndexes, kind);
98
138
  }
99
139
 
100
140
  focusCategories(): void {
@@ -110,35 +150,19 @@ export class AgentWorkspace {
110
150
  }
111
151
 
112
152
  moveUp(): void {
113
- if (this.focusPane === 'categories') {
114
- this.selectedCategoryIndex = Math.max(0, this.selectedCategoryIndex - 1);
115
- this.selectedActionIndex = 0;
116
- } else {
117
- this.selectedActionIndex = Math.max(0, this.selectedActionIndex - 1);
118
- }
119
- this.clampSelection();
153
+ moveAgentWorkspaceSelection(this, -1);
120
154
  }
121
155
 
122
156
  moveDown(): void {
123
- if (this.focusPane === 'categories') {
124
- this.selectedCategoryIndex = Math.min(this.categories.length - 1, this.selectedCategoryIndex + 1);
125
- this.selectedActionIndex = 0;
126
- } else {
127
- this.selectedActionIndex = Math.min(this.actions.length - 1, this.selectedActionIndex + 1);
128
- }
129
- this.clampSelection();
157
+ moveAgentWorkspaceSelection(this, 1);
130
158
  }
131
159
 
132
160
  jumpHome(): void {
133
- if (this.focusPane === 'categories') this.selectedCategoryIndex = 0;
134
- else this.selectedActionIndex = 0;
135
- this.clampSelection();
161
+ jumpAgentWorkspaceSelection(this, 'home');
136
162
  }
137
163
 
138
164
  jumpEnd(): void {
139
- if (this.focusPane === 'categories') this.selectedCategoryIndex = this.categories.length - 1;
140
- else this.selectedActionIndex = this.actions.length - 1;
141
- this.clampSelection();
165
+ jumpAgentWorkspaceSelection(this, 'end');
142
166
  }
143
167
 
144
168
  refreshRuntimeSnapshot(): void {
@@ -168,10 +192,30 @@ export class AgentWorkspace {
168
192
  this.lastActionResult = {
169
193
  kind: 'guidance',
170
194
  title: `${title} cancelled`,
171
- detail: 'No local Agent registry changes were written.',
195
+ detail: 'No Agent-local registry changes were written.',
172
196
  };
173
197
  }
174
198
 
199
+ beginActionSearch(): void {
200
+ beginAgentWorkspaceActionSearch(this);
201
+ }
202
+
203
+ appendActionSearchText(text: string): void {
204
+ appendAgentWorkspaceActionSearchText(this, text);
205
+ }
206
+
207
+ actionSearchBackspace(): void {
208
+ backspaceAgentWorkspaceActionSearch(this);
209
+ }
210
+
211
+ clearActionSearch(): void {
212
+ clearAgentWorkspaceActionSearch(this);
213
+ }
214
+
215
+ commitActionSearchSelection(): boolean {
216
+ return commitAgentWorkspaceActionSearchSelection(this, this.selectedActionSearchResult);
217
+ }
218
+
175
219
  moveEditorField(delta: number): void {
176
220
  const editor = this.localEditor;
177
221
  if (!editor) return;
@@ -184,7 +228,7 @@ export class AgentWorkspace {
184
228
  if (!editor || text.length === 0) return;
185
229
  const field = editor.fields[editor.selectedFieldIndex];
186
230
  if (!field) return;
187
- this.replaceEditorField(editor.selectedFieldIndex, `${field.value}${text}`, editor.message);
231
+ this.replaceEditorField(editor.selectedFieldIndex, `${field.value}${field.multiline ? text.replace(/\r\n?/g, '\n') : text.replace(/[\r\n]+/g, ' ')}`, editor.message);
188
232
  }
189
233
 
190
234
  appendEditorNewline(): void {
@@ -226,201 +270,45 @@ export class AgentWorkspace {
226
270
  return Boolean(this.context?.executeCommand && this.dispatchCommand);
227
271
  }
228
272
 
273
+ hasPromptDispatch(): boolean {
274
+ return Boolean(this.context?.submitInput && this.dispatchPrompt);
275
+ }
276
+
229
277
  dispatchWorkspaceCommand(command: string): void {
230
278
  this.dispatchCommand?.(command);
231
279
  }
232
280
 
281
+ dispatchWorkspacePrompt(prompt: string): void {
282
+ this.dispatchPrompt?.(prompt);
283
+ }
284
+
233
285
  clampSelection(): void {
234
286
  this.selectedCategoryIndex = Math.max(0, Math.min(this.selectedCategoryIndex, this.categories.length - 1));
235
287
  this.selectedActionIndex = Math.max(0, Math.min(this.selectedActionIndex, this.actions.length - 1));
236
- this.clampLocalLibrarySelection('memory');
237
- this.clampLocalLibrarySelection('persona');
238
- this.clampLocalLibrarySelection('skill');
239
- this.clampLocalLibrarySelection('routine');
240
- }
241
-
242
- private localLibraryItems(kind: AgentWorkspaceLocalEditorKind): readonly AgentWorkspaceLocalLibraryItem[] {
243
- if (kind === 'memory') return this.runtimeSnapshot?.localMemories ?? [];
244
- if (kind === 'persona') return this.runtimeSnapshot?.localPersonas ?? [];
245
- if (kind === 'skill') return this.runtimeSnapshot?.localSkills ?? [];
246
- if (kind === 'profile') return [];
247
- return this.runtimeSnapshot?.localRoutines ?? [];
248
- }
249
-
250
- private clampLocalLibrarySelection(kind: AgentWorkspaceLocalEditorKind): void {
251
- const length = this.localLibraryItems(kind).length;
252
- this.selectedLibraryItemIndexes[kind] = length === 0
253
- ? 0
254
- : Math.max(0, Math.min(this.selectedLibraryItemIndexes[kind], length - 1));
288
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, 'memory');
289
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, 'note');
290
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, 'persona');
291
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, 'skill');
292
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, 'routine');
255
293
  }
256
294
 
257
295
  moveLocalLibraryItemSelection(kind: AgentWorkspaceLocalEditorKind, delta: number): void {
258
- const items = this.localLibraryItems(kind);
259
- if (items.length === 0) {
260
- this.status = `No local ${kind} records to select.`;
261
- this.lastActionResult = {
262
- kind: 'guidance',
263
- title: `No ${kind} records`,
264
- detail: `Create a local ${kind} before using selection actions.`,
265
- safety: 'safe',
266
- };
267
- return;
268
- }
269
- this.selectedLibraryItemIndexes[kind] = Math.max(0, Math.min(items.length - 1, this.selectedLibraryItemIndexes[kind] + delta));
270
- const selected = this.selectedLocalLibraryItem(kind);
271
- this.status = selected ? `Selected ${kind}: ${selected.name}.` : `Selected ${kind} updated.`;
272
- this.lastActionResult = {
273
- kind: 'guidance',
274
- title: selected ? `Selected ${selected.name}` : `Selected ${kind}`,
275
- detail: selected ? `${selected.name} (${selected.id}) is now the selected local ${kind}.` : `Selection changed for ${kind}.`,
276
- safety: 'safe',
277
- };
296
+ moveAgentWorkspaceLocalLibraryItemSelection(this, kind, delta);
278
297
  }
279
298
 
280
299
  applyLocalLibraryOperation(operation: AgentWorkspaceLocalOperation): void {
281
- const shellPaths = this.context?.workspace?.shellPaths;
282
- if (!shellPaths) {
283
- this.status = 'Local Agent registry files are unavailable.';
284
- this.lastActionResult = {
285
- kind: 'error',
286
- title: 'Local registry unavailable',
287
- detail: 'The Agent workspace cannot locate the Agent-local registry files for this runtime.',
288
- };
289
- return;
290
- }
291
- try {
292
- if (operation === 'persona-clear') {
293
- AgentPersonaRegistry.fromShellPaths(shellPaths).clearActive();
294
- this.finishLocalOperation('persona', 'Cleared active persona', 'The default Agent policy will apply to future turns.');
295
- return;
296
- }
297
- const selected = this.selectedItemForOperation(operation);
298
- if (!selected) {
299
- this.status = 'No selected local registry item.';
300
- this.lastActionResult = {
301
- kind: 'guidance',
302
- title: 'Nothing selected',
303
- detail: 'Create or select a local library item before running this action.',
304
- safety: 'safe',
305
- };
306
- return;
307
- }
308
- if (operation === 'memory-edit') {
309
- const memory = this.memoryApi();
310
- const record = memory.get(selected.id);
311
- if (!record) throw new Error(`Unknown Agent memory: ${selected.id}`);
312
- this.localEditor = createMemoryUpdateEditor(record);
313
- this.status = `Editing memory: ${record.id}.`;
314
- this.lastActionResult = {
315
- kind: 'guidance',
316
- title: this.localEditor.title,
317
- detail: this.localEditor.message,
318
- safety: 'safe',
319
- };
320
- } else if (operation === 'memory-review') {
321
- const record = this.memoryApi().review(selected.id, { state: 'reviewed', confidence: selected.confidence ?? 100, reviewedBy: 'operator' });
322
- if (!record) throw new Error(`Unknown Agent memory: ${selected.id}`);
323
- this.finishLocalOperation('memory', `Reviewed memory ${record.id}`, `${record.summary} is marked reviewed.`);
324
- } else if (operation === 'memory-stale') {
325
- const record = this.memoryApi().review(selected.id, { state: 'stale', staleReason: 'Marked stale from Agent workspace', reviewedBy: 'operator' });
326
- if (!record) throw new Error(`Unknown Agent memory: ${selected.id}`);
327
- this.finishLocalOperation('memory', `Marked memory stale ${record.id}`, `${record.summary} needs review before reuse.`);
328
- } else if (operation === 'memory-delete') {
329
- this.openDeleteEditor('memory', selected);
330
- } else if (operation === 'persona-edit') {
331
- const registry = AgentPersonaRegistry.fromShellPaths(shellPaths);
332
- const persona = registry.get(selected.id);
333
- if (!persona) throw new Error(`Unknown persona: ${selected.id}`);
334
- this.localEditor = createPersonaUpdateEditor(persona, registry.snapshot().activePersonaId === persona.id);
335
- this.status = `Editing persona: ${persona.name}.`;
336
- this.lastActionResult = {
337
- kind: 'guidance',
338
- title: this.localEditor.title,
339
- detail: this.localEditor.message,
340
- safety: 'safe',
341
- };
342
- } else if (operation === 'persona-use') {
343
- AgentPersonaRegistry.fromShellPaths(shellPaths).setActive(selected.id);
344
- this.finishLocalOperation('persona', `Using persona ${selected.name}`, `${selected.name} will shape future main-conversation turns.`);
345
- } else if (operation === 'persona-review') {
346
- AgentPersonaRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
347
- this.finishLocalOperation('persona', `Reviewed persona ${selected.name}`, `${selected.name} is marked reviewed.`);
348
- } else if (operation === 'persona-delete') {
349
- this.openDeleteEditor('persona', selected);
350
- } else if (operation === 'skill-edit') {
351
- const skill = AgentSkillRegistry.fromShellPaths(shellPaths).get(selected.id);
352
- if (!skill) throw new Error(`Unknown skill: ${selected.id}`);
353
- this.localEditor = createSkillUpdateEditor(skill);
354
- this.status = `Editing skill: ${skill.name}.`;
355
- this.lastActionResult = {
356
- kind: 'guidance',
357
- title: this.localEditor.title,
358
- detail: this.localEditor.message,
359
- safety: 'safe',
360
- };
361
- } else if (operation === 'skill-enable') {
362
- AgentSkillRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, true);
363
- this.finishLocalOperation('skill', `Enabled skill ${selected.name}`, `${selected.name} can now inform main-conversation turns.`);
364
- } else if (operation === 'skill-disable') {
365
- AgentSkillRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, false);
366
- this.finishLocalOperation('skill', `Disabled skill ${selected.name}`, `${selected.name} remains saved but is no longer injected into guidance.`);
367
- } else if (operation === 'skill-review') {
368
- AgentSkillRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
369
- this.finishLocalOperation('skill', `Reviewed skill ${selected.name}`, `${selected.name} is marked reviewed.`);
370
- } else if (operation === 'skill-delete') {
371
- this.openDeleteEditor('skill', selected);
372
- } else if (operation === 'routine-edit') {
373
- const routine = AgentRoutineRegistry.fromShellPaths(shellPaths).get(selected.id);
374
- if (!routine) throw new Error(`Unknown routine: ${selected.id}`);
375
- this.localEditor = createRoutineUpdateEditor(routine);
376
- this.status = `Editing routine: ${routine.name}.`;
377
- this.lastActionResult = {
378
- kind: 'guidance',
379
- title: this.localEditor.title,
380
- detail: this.localEditor.message,
381
- safety: 'safe',
382
- };
383
- } else if (operation === 'routine-start') {
384
- if (this.hasCommandDispatch()) {
385
- const command = `/routines start ${quoteSlashCommandArg(selected.id)}`;
386
- this.dispatchWorkspaceCommand(command);
387
- this.status = `Opening routine: ${selected.name}.`;
388
- this.lastActionResult = {
389
- kind: 'dispatched',
390
- title: `Opening routine ${selected.name}`,
391
- detail: `${selected.name} will print its workflow steps in the main conversation. No hidden job was created.`,
392
- command,
393
- safety: 'safe',
394
- };
395
- return;
396
- }
397
- AgentRoutineRegistry.fromShellPaths(shellPaths).markStarted(selected.id);
398
- this.finishLocalOperation('routine', `Started routine ${selected.name}`, `${selected.name} was marked started for this main-conversation workflow. No hidden job was created.`);
399
- } else if (operation === 'routine-enable') {
400
- AgentRoutineRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, true);
401
- this.finishLocalOperation('routine', `Enabled routine ${selected.name}`, `${selected.name} can now inform main-conversation turns.`);
402
- } else if (operation === 'routine-disable') {
403
- AgentRoutineRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, false);
404
- this.finishLocalOperation('routine', `Disabled routine ${selected.name}`, `${selected.name} remains saved but is no longer injected into guidance.`);
405
- } else if (operation === 'routine-review') {
406
- AgentRoutineRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
407
- this.finishLocalOperation('routine', `Reviewed routine ${selected.name}`, `${selected.name} is marked reviewed.`);
408
- } else {
409
- this.openDeleteEditor('routine', selected);
410
- }
411
- } catch (error) {
412
- const detail = error instanceof Error ? error.message : String(error);
413
- this.status = detail;
414
- this.lastActionResult = {
415
- kind: 'error',
416
- title: 'Local registry action failed',
417
- detail,
418
- };
419
- }
300
+ applyAgentWorkspaceLocalLibraryOperation(this, operation, {
301
+ shellPaths: () => this.context?.workspace?.shellPaths,
302
+ selectedItemForOperation: (selectedOperation) => this.selectedItemForOperation(selectedOperation),
303
+ memoryApi: () => this.memoryApi(),
304
+ finishLocalOperation: (kind, title, detail) => this.finishLocalOperation(kind, title, detail),
305
+ openDeleteEditor: (kind, selected) => this.openDeleteEditor(kind, selected),
306
+ });
420
307
  }
421
308
 
422
309
  private selectedItemForOperation(operation: AgentWorkspaceLocalOperation): AgentWorkspaceLocalLibraryItem | null {
423
310
  if (operation.startsWith('memory-')) return this.selectedLocalLibraryItem('memory');
311
+ if (operation.startsWith('note-')) return this.selectedLocalLibraryItem('note');
424
312
  if (operation.startsWith('persona-')) return this.selectedLocalLibraryItem('persona');
425
313
  if (operation.startsWith('skill-')) return this.selectedLocalLibraryItem('skill');
426
314
  return this.selectedLocalLibraryItem('routine');
@@ -428,13 +316,19 @@ export class AgentWorkspace {
428
316
 
429
317
  private memoryApi(): MemoryApi {
430
318
  const memory = this.context?.clients?.agentKnowledgeApi?.memory;
431
- if (!memory) throw new Error('Agent Memory API is unavailable; refusing default Knowledge/Wiki or non-Agent fallback.');
319
+ if (!memory) throw new Error('Agent Memory API is unavailable; refusing default knowledge or non-Agent fallback.');
432
320
  return memory;
433
321
  }
434
322
 
323
+ private learnedBehaviorTarget(): Exclude<AgentWorkspaceLocalEditorKind, 'memory' | 'note' | 'profile'> {
324
+ const target = this.editorField('target').trim().toLowerCase();
325
+ if (target === 'persona' || target === 'skill' || target === 'routine') return target;
326
+ throw new Error('Behavior type must be skill, routine, or persona.');
327
+ }
328
+
435
329
  private finishLocalOperation(kind: AgentWorkspaceLocalEditorKind, title: string, detail: string): void {
436
330
  this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
437
- this.clampLocalLibrarySelection(kind);
331
+ clampAgentWorkspaceLocalLibrarySelection(this.runtimeSnapshot, this.selectedLibraryItemIndexes, kind);
438
332
  this.status = title;
439
333
  this.lastActionResult = {
440
334
  kind: 'refreshed',
@@ -515,7 +409,7 @@ export class AgentWorkspace {
515
409
  const shellPaths = this.context?.workspace?.shellPaths;
516
410
  if (!shellPaths) {
517
411
  this.localEditor = { ...editor, message: 'Cannot save because Agent shell paths are unavailable.' };
518
- this.status = 'Cannot save local Agent registry item without shell paths.';
412
+ this.status = 'Cannot save Agent-local registry item without shell paths.';
519
413
  this.lastActionResult = {
520
414
  kind: 'error',
521
415
  title: 'Local registry unavailable',
@@ -528,13 +422,46 @@ export class AgentWorkspace {
528
422
  this.submitLocalDeleteEditor(shellPaths, editor);
529
423
  return;
530
424
  }
531
- if (editor.kind === 'profile') {
425
+ if (editor.kind === 'learned-behavior') {
426
+ const created = createAgentWorkspaceLearnedBehavior(shellPaths, {
427
+ target: this.learnedBehaviorTarget(),
428
+ name: this.editorField('name'),
429
+ description: this.editorField('description'),
430
+ notes: this.editorField('notes'),
431
+ tags: splitList(this.editorField('tags')),
432
+ triggers: splitList(this.editorField('triggers')),
433
+ enable: isAffirmative(this.editorField('enable')),
434
+ });
435
+ this.finishLocalEditor(created.kind, created.id, created.name, 'Created');
436
+ } else if (editor.kind === 'profile') {
532
437
  const template = this.editorField('template');
533
438
  const templateId = template && template.toLowerCase() !== 'none' ? template : undefined;
534
439
  const profile = createAgentRuntimeProfile(shellPaths.homeDirectory, this.editorField('name'), {
535
440
  ...(templateId ? { templateId } : {}),
536
441
  });
537
442
  this.finishProfileEditor(profile);
443
+ } else if (editor.kind === 'note') {
444
+ const registry = AgentNoteRegistry.fromShellPaths(shellPaths);
445
+ if (editor.mode === 'update' && editor.recordId) {
446
+ const updated = registry.update(editor.recordId, {
447
+ title: this.editorField('title'),
448
+ body: this.editorField('body'),
449
+ sourceUrl: this.editorField('sourceUrl'),
450
+ tags: splitList(this.editorField('tags')),
451
+ provenance: 'Workspace',
452
+ });
453
+ this.finishLocalEditor(editor.kind, updated.id, updated.title, 'Updated');
454
+ return;
455
+ }
456
+ const created = registry.create({
457
+ title: this.editorField('title'),
458
+ body: this.editorField('body'),
459
+ sourceUrl: this.editorField('sourceUrl'),
460
+ tags: splitList(this.editorField('tags')),
461
+ source: 'user',
462
+ provenance: 'Workspace',
463
+ });
464
+ this.finishLocalEditor(editor.kind, created.id, created.title, 'Created');
538
465
  } else if (editor.kind === 'persona') {
539
466
  const registry = AgentPersonaRegistry.fromShellPaths(shellPaths);
540
467
  if (editor.mode === 'update' && editor.recordId) {
@@ -545,7 +472,7 @@ export class AgentWorkspace {
545
472
  body: this.editorField('body'),
546
473
  tags: splitList(this.editorField('tags')),
547
474
  triggers: splitList(this.editorField('triggers')),
548
- provenance: 'agent-workspace',
475
+ provenance: 'Workspace',
549
476
  });
550
477
  if (isAffirmative(this.editorField('activate'))) registry.setActive(updated.id);
551
478
  else if (wasActive) registry.clearActive();
@@ -559,7 +486,7 @@ export class AgentWorkspace {
559
486
  tags: splitList(this.editorField('tags')),
560
487
  triggers: splitList(this.editorField('triggers')),
561
488
  source: 'user',
562
- provenance: 'agent-workspace',
489
+ provenance: 'Workspace',
563
490
  });
564
491
  if (isAffirmative(this.editorField('activate'))) registry.setActive(created.id);
565
492
  this.finishLocalEditor(editor.kind, created.id, created.name, 'Created');
@@ -572,7 +499,8 @@ export class AgentWorkspace {
572
499
  procedure: this.editorField('procedure'),
573
500
  triggers: splitList(this.editorField('triggers')),
574
501
  tags: splitList(this.editorField('tags')),
575
- provenance: 'agent-workspace',
502
+ requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
503
+ provenance: 'Workspace',
576
504
  });
577
505
  registry.setEnabled(updated.id, isAffirmative(this.editorField('enabled')));
578
506
  this.finishLocalEditor(editor.kind, updated.id, updated.name, 'Updated');
@@ -584,9 +512,10 @@ export class AgentWorkspace {
584
512
  procedure: this.editorField('procedure'),
585
513
  triggers: splitList(this.editorField('triggers')),
586
514
  tags: splitList(this.editorField('tags')),
515
+ requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
587
516
  enabled: isAffirmative(this.editorField('enabled')),
588
517
  source: 'user',
589
- provenance: 'agent-workspace',
518
+ provenance: 'Workspace',
590
519
  });
591
520
  this.finishLocalEditor(editor.kind, created.id, created.name, 'Created');
592
521
  } else {
@@ -598,7 +527,8 @@ export class AgentWorkspace {
598
527
  steps: this.editorField('steps'),
599
528
  triggers: splitList(this.editorField('triggers')),
600
529
  tags: splitList(this.editorField('tags')),
601
- provenance: 'agent-workspace',
530
+ requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
531
+ provenance: 'Workspace',
602
532
  });
603
533
  registry.setEnabled(updated.id, isAffirmative(this.editorField('enabled')));
604
534
  this.finishLocalEditor(editor.kind, updated.id, updated.name, 'Updated');
@@ -610,9 +540,10 @@ export class AgentWorkspace {
610
540
  steps: this.editorField('steps'),
611
541
  triggers: splitList(this.editorField('triggers')),
612
542
  tags: splitList(this.editorField('tags')),
543
+ requirements: buildAgentWorkspaceRequirements((id) => this.editorField(id)),
613
544
  enabled: isAffirmative(this.editorField('enabled')),
614
545
  source: 'user',
615
- provenance: 'agent-workspace',
546
+ provenance: 'Workspace',
616
547
  });
617
548
  this.finishLocalEditor(editor.kind, created.id, created.name, 'Created');
618
549
  }
@@ -629,7 +560,7 @@ export class AgentWorkspace {
629
560
  }
630
561
 
631
562
  private submitCommandEditor(editor: AgentWorkspaceLocalEditor): void {
632
- const result = buildAgentWorkspaceCommandEditorSubmission(editor, (fieldId) => this.editorField(fieldId), this.hasCommandDispatch());
563
+ const result = buildAgentWorkspaceCommandEditorSubmission(editor, (fieldId) => this.editorField(fieldId), this.hasCommandDispatch(), this.hasPromptDispatch());
633
564
  if (result.kind === 'editor') {
634
565
  this.localEditor = result.editor;
635
566
  this.status = result.status;
@@ -640,6 +571,10 @@ export class AgentWorkspace {
640
571
  this.localEditor = null;
641
572
  this.status = result.status;
642
573
  this.lastActionResult = result.actionResult;
574
+ if (result.kind === 'prompt') {
575
+ this.dispatchWorkspacePrompt(result.prompt);
576
+ return;
577
+ }
643
578
  this.dispatchWorkspaceCommand(result.command);
644
579
  }
645
580
 
@@ -656,11 +591,14 @@ export class AgentWorkspace {
656
591
  }
657
592
  if (editor.kind === 'memory') {
658
593
  const removed = this.memoryApi().delete(expectedId);
659
- if (!removed) throw new Error(`Unknown Agent memory: ${expectedId}`);
594
+ if (!removed) throw new Error(`Unknown Agent memory ${expectedId}`);
660
595
  this.finishLocalDelete(editor.kind, expectedId, expectedId);
661
596
  } else if (editor.kind === 'persona') {
662
597
  const removed = AgentPersonaRegistry.fromShellPaths(shellPaths).deletePersona(expectedId);
663
598
  this.finishLocalDelete(editor.kind, removed.id, removed.name);
599
+ } else if (editor.kind === 'note') {
600
+ const removed = AgentNoteRegistry.fromShellPaths(shellPaths).deleteNote(expectedId);
601
+ this.finishLocalDelete(editor.kind, removed.id, removed.title);
664
602
  } else if (editor.kind === 'skill') {
665
603
  const removed = AgentSkillRegistry.fromShellPaths(shellPaths).deleteSkill(expectedId);
666
604
  this.finishLocalDelete(editor.kind, removed.id, removed.name);
@@ -668,7 +606,7 @@ export class AgentWorkspace {
668
606
  const removed = AgentRoutineRegistry.fromShellPaths(shellPaths).deleteRoutine(expectedId);
669
607
  this.finishLocalDelete(editor.kind, removed.id, removed.name);
670
608
  } else {
671
- throw new Error(`Unsupported delete editor kind: ${editor.kind}`);
609
+ throw new Error(`Unsupported delete editor kind ${editor.kind}`);
672
610
  }
673
611
  }
674
612
 
@@ -712,7 +650,7 @@ export class AgentWorkspace {
712
650
  this.selectedCategoryIndex = categoryIndex;
713
651
  this.selectedActionIndex = 0;
714
652
  }
715
- this.status = `${verb} memory: ${record.summary}.`;
653
+ this.status = `${verb} memory ${record.summary}.`;
716
654
  this.lastActionResult = {
717
655
  kind: 'refreshed',
718
656
  title: `${verb} memory`,
@@ -731,7 +669,7 @@ export class AgentWorkspace {
731
669
  this.selectedActionIndex = 0;
732
670
  }
733
671
  this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
734
- this.status = `${verb} ${kind}: ${name}.`;
672
+ this.status = `${verb} ${kind} ${name}.`;
735
673
  this.lastActionResult = {
736
674
  kind: 'refreshed',
737
675
  title: `${verb} ${kind}`,
@@ -751,11 +689,11 @@ export class AgentWorkspace {
751
689
  }
752
690
  this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
753
691
  const starter = profile.starterTemplateId ? ` from ${profile.starterTemplateId}` : '';
754
- this.status = `Created Agent profile: ${profile.id}.`;
692
+ this.status = `Created Agent profile ${profile.id}.`;
755
693
  this.lastActionResult = {
756
694
  kind: 'refreshed',
757
695
  title: 'Created Agent profile',
758
- detail: `Created isolated Agent profile ${profile.id}${starter}. Launch it with goodvibes-agent --agent-profile ${profile.id}. The current TUI session was not switched.`,
696
+ detail: `Created isolated Agent profile ${profile.id}${starter}. Launch it with goodvibes-agent --agent-profile ${profile.id}. The current Agent session was not switched.`,
759
697
  safety: 'safe',
760
698
  };
761
699
  this.clampSelection();
@@ -770,7 +708,7 @@ export class AgentWorkspace {
770
708
  this.selectedActionIndex = 0;
771
709
  }
772
710
  this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
773
- this.status = `Deleted ${kind}: ${name}.`;
711
+ this.status = `Deleted ${kind} ${name}.`;
774
712
  this.lastActionResult = {
775
713
  kind: 'refreshed',
776
714
  title: `Deleted ${kind}`,