@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
@@ -8,11 +8,13 @@ import {
8
8
  type MemoryScope,
9
9
  } from '@pellux/goodvibes-sdk/platform/state';
10
10
  import { AgentPersonaRegistry, type AgentPersonaRecord } from '../agent/persona-registry.ts';
11
+ import { AgentNoteRegistry, type AgentNoteRecord } from '../agent/note-registry.ts';
11
12
  import { AgentRoutineRegistry, type AgentRoutineRecord } from '../agent/routine-registry.ts';
12
13
  import { AgentSkillRegistry, type AgentSkillBundleRecord, type AgentSkillRecord } from '../agent/skill-registry.ts';
13
14
  import { assertNoSecretLikeMemoryText } from '../agent/memory-safety.ts';
15
+ import { formatAgentRecordOrigin, formatAgentRecordReference, formatAgentRecordReviewState } from '../agent/record-labels.ts';
14
16
 
15
- export type AgentLocalRegistryDomain = 'memory' | 'persona' | 'skill' | 'skill_bundle' | 'routine';
17
+ export type AgentLocalRegistryDomain = 'memory' | 'note' | 'persona' | 'skill' | 'skill_bundle' | 'routine';
16
18
  export type AgentLocalRegistryAction =
17
19
  | 'list'
18
20
  | 'search'
@@ -37,9 +39,11 @@ export interface AgentLocalRegistryToolArgs {
37
39
  readonly summary?: unknown;
38
40
  readonly detail?: unknown;
39
41
  readonly confidence?: unknown;
42
+ readonly title?: unknown;
40
43
  readonly name?: unknown;
41
44
  readonly description?: unknown;
42
45
  readonly body?: unknown;
46
+ readonly sourceUrl?: unknown;
43
47
  readonly procedure?: unknown;
44
48
  readonly steps?: unknown;
45
49
  readonly skills?: unknown;
@@ -51,7 +55,7 @@ export interface AgentLocalRegistryToolArgs {
51
55
  readonly provenance?: unknown;
52
56
  }
53
57
 
54
- const DOMAINS: readonly AgentLocalRegistryDomain[] = ['memory', 'persona', 'skill', 'skill_bundle', 'routine'];
58
+ const DOMAINS: readonly AgentLocalRegistryDomain[] = ['memory', 'note', 'persona', 'skill', 'skill_bundle', 'routine'];
55
59
  const ACTIONS: readonly AgentLocalRegistryAction[] = [
56
60
  'list',
57
61
  'search',
@@ -68,6 +72,7 @@ const ACTIONS: readonly AgentLocalRegistryAction[] = [
68
72
  ];
69
73
  const MEMORY_CLASSES: readonly MemoryClass[] = ['decision', 'constraint', 'incident', 'pattern', 'fact', 'risk', 'runbook', 'architecture', 'ownership'];
70
74
  const MEMORY_SCOPES: readonly MemoryScope[] = ['session', 'project', 'team'];
75
+ const AGENT_TOOL_PROVENANCE = 'agent-local-registry-tool';
71
76
 
72
77
  function isDomain(value: unknown): value is AgentLocalRegistryDomain {
73
78
  return typeof value === 'string' && DOMAINS.includes(value as AgentLocalRegistryDomain);
@@ -137,6 +142,12 @@ function requireDescription(args: AgentLocalRegistryToolArgs): string {
137
142
  return description;
138
143
  }
139
144
 
145
+ function requireTextField(value: unknown, fieldName: string): string {
146
+ const text = readString(value);
147
+ if (!text) throw new Error(`${fieldName} is required.`);
148
+ return text;
149
+ }
150
+
140
151
  function requireSummary(args: AgentLocalRegistryToolArgs): string {
141
152
  const summary = readString(args.summary || args.description);
142
153
  if (!summary) throw new Error('summary is required.');
@@ -145,19 +156,19 @@ function requireSummary(args: AgentLocalRegistryToolArgs): string {
145
156
 
146
157
  function requireMemoryClass(args: AgentLocalRegistryToolArgs): MemoryClass {
147
158
  const cls = args.cls || 'fact';
148
- if (!isMemoryClass(cls)) throw new Error(`Invalid memory class. Valid: ${MEMORY_CLASSES.join(', ')}.`);
159
+ if (!isMemoryClass(cls)) throw new Error(`Invalid memory class. Valid values ${MEMORY_CLASSES.join(', ')}.`);
149
160
  return cls;
150
161
  }
151
162
 
152
163
  function readMemoryScope(args: AgentLocalRegistryToolArgs): MemoryScope {
153
164
  const scope = args.scope || 'project';
154
- if (!isMemoryScope(scope)) throw new Error(`Invalid memory scope. Valid: ${MEMORY_SCOPES.join(', ')}.`);
165
+ if (!isMemoryScope(scope)) throw new Error(`Invalid memory scope. Valid values ${MEMORY_SCOPES.join(', ')}.`);
155
166
  return scope;
156
167
  }
157
168
 
158
169
  function formatMemory(record: MemoryRecord): string {
159
- const tags = record.tags.length > 0 ? ` tags=${record.tags.join(',')}` : '';
160
- return `${record.id} ${record.scope}/${record.cls} ${record.reviewState} ${record.confidence}%${tags} ${record.summary}`;
170
+ const tags = record.tags.length > 0 ? ` tags ${record.tags.join(', ')}` : '';
171
+ return `${record.id} ${record.scope}/${record.cls} ${formatAgentRecordReviewState(record.reviewState)} ${record.confidence}%${tags} ${record.summary}`;
161
172
  }
162
173
 
163
174
  async function handleMemory(registry: MemoryRegistry, action: AgentLocalRegistryAction, args: AgentLocalRegistryToolArgs): Promise<string> {
@@ -172,16 +183,17 @@ async function handleMemory(registry: MemoryRegistry, action: AgentLocalRegistry
172
183
  const records = registry.search({ query, limit: 10 });
173
184
  return records.length === 0
174
185
  ? `Agent-local memory search\nNo Agent-local memory records matched "${query}".`
175
- : [`Agent-local memory search: ${query || '(all)'}`, ...records.map(formatMemory)].join('\n');
186
+ : ['Agent-local memory search', `query ${query || '(all)'}`, ...records.map(formatMemory)].join('\n');
176
187
  }
177
188
  if (action === 'get') {
178
189
  const record = registry.get(requireId(args));
179
- if (!record) return `Unknown Agent-local memory: ${readString(args.id)}`;
190
+ if (!record) return `Unknown Agent-local memory ${readString(args.id)}`;
180
191
  return [
181
192
  formatMemory(record),
182
- `created: ${new Date(record.createdAt).toISOString()}`,
183
- `updated: ${new Date(record.updatedAt).toISOString()}`,
184
- `provenance: ${record.provenance.map((entry) => `${entry.kind}:${entry.ref}`).join(', ') || '(none)'}`,
193
+ `created ${new Date(record.createdAt).toISOString()}`,
194
+ `updated ${new Date(record.updatedAt).toISOString()}`,
195
+ `origin ${record.provenance.map((entry) => formatAgentRecordReference({ kind: String(entry.kind), ref: String(entry.ref) })).join(', ') || '(none)'}`,
196
+ `provenance: ${record.provenance.map((entry) => `${String(entry.kind)}:${String(entry.ref)}`).join(',') || '(none)'}`,
185
197
  '',
186
198
  record.detail || '(no detail)',
187
199
  ].join('\n');
@@ -197,9 +209,13 @@ async function handleMemory(registry: MemoryRegistry, action: AgentLocalRegistry
197
209
  summary,
198
210
  detail,
199
211
  tags: [...tags],
200
- provenance: [{ kind: 'event', ref: readString(args.provenance) || 'agent-local-registry-tool' }],
212
+ provenance: [{ kind: 'event', ref: readString(args.provenance) || AGENT_TOOL_PROVENANCE }],
201
213
  });
202
- return `Created Agent-local memory ${record.id}: ${record.summary}`;
214
+ return [
215
+ 'Created Agent-local memory',
216
+ ` id ${record.id}`,
217
+ ` summary ${record.summary}`,
218
+ ].join('\n');
203
219
  }
204
220
  if (action === 'update') {
205
221
  const summary = readString(args.summary || args.description);
@@ -212,8 +228,12 @@ async function handleMemory(registry: MemoryRegistry, action: AgentLocalRegistry
212
228
  tags,
213
229
  scope: args.scope === undefined ? undefined : readMemoryScope(args),
214
230
  });
215
- if (!record) return `Unknown Agent-local memory: ${readString(args.id)}`;
216
- return `Updated Agent-local memory ${record.id}: ${record.summary}`;
231
+ if (!record) return `Unknown Agent-local memory ${readString(args.id)}`;
232
+ return [
233
+ 'Updated Agent-local memory',
234
+ ` id ${record.id}`,
235
+ ` summary ${record.summary}`,
236
+ ].join('\n');
217
237
  }
218
238
  if (action === 'review') {
219
239
  const record = registry.review(requireId(args), {
@@ -221,38 +241,118 @@ async function handleMemory(registry: MemoryRegistry, action: AgentLocalRegistry
221
241
  confidence: readOptionalConfidence(args.confidence),
222
242
  reviewedBy: 'agent',
223
243
  });
224
- if (!record) return `Unknown Agent-local memory: ${readString(args.id)}`;
225
- return `Reviewed Agent-local memory ${record.id}.`;
244
+ if (!record) return `Unknown Agent-local memory ${readString(args.id)}`;
245
+ return [
246
+ 'Reviewed Agent-local memory',
247
+ ` id ${record.id}`,
248
+ ].join('\n');
226
249
  }
227
250
  if (action === 'stale') {
228
251
  const record = registry.review(requireId(args), {
229
252
  state: 'stale',
230
253
  staleReason: readString(args.reason) || 'Marked stale by Agent.',
231
254
  });
232
- if (!record) return `Unknown Agent-local memory: ${readString(args.id)}`;
233
- return `Marked Agent-local memory ${record.id} stale.`;
255
+ if (!record) return `Unknown Agent-local memory ${readString(args.id)}`;
256
+ return [
257
+ 'Marked Agent-local memory stale',
258
+ ` id ${record.id}`,
259
+ ].join('\n');
234
260
  }
235
261
  throw new Error(`Action ${action} is not valid for memory.`);
236
262
  }
237
263
 
264
+ function formatNote(note: AgentNoteRecord): string {
265
+ const tags = note.tags.length > 0 ? ` tags ${note.tags.join(', ')}` : '';
266
+ const sourceUrl = note.sourceUrl ? ` source ${note.sourceUrl}` : '';
267
+ return `${note.id} ${formatAgentRecordReviewState(note.reviewState)} ${formatAgentRecordOrigin(note.source, note.provenance)}${tags}${sourceUrl} ${note.title}`;
268
+ }
269
+
270
+ function listNotes(records: readonly AgentNoteRecord[], title: string): string {
271
+ return records.length === 0
272
+ ? `${title}\nNo Agent-local notes.`
273
+ : [title, ...records.map(formatNote)].join('\n');
274
+ }
275
+
276
+ function handleNote(shellPaths: ShellPathService, action: AgentLocalRegistryAction, args: AgentLocalRegistryToolArgs): string {
277
+ const registry = AgentNoteRegistry.fromShellPaths(shellPaths);
278
+ if (action === 'list') return listNotes(registry.list(), 'Agent-local notes');
279
+ if (action === 'search') return listNotes(registry.search(readString(args.query)), 'Agent-local notes search');
280
+ if (action === 'get') {
281
+ const note = registry.get(requireId(args));
282
+ if (!note) return `Unknown Agent-local note ${readString(args.id)}`;
283
+ return [
284
+ formatNote(note),
285
+ `created ${note.createdAt}`,
286
+ `updated ${note.updatedAt}`,
287
+ `origin ${formatAgentRecordOrigin(note.source, note.provenance)}`,
288
+ '',
289
+ note.body,
290
+ ].join('\n');
291
+ }
292
+ if (action === 'create') {
293
+ const note = registry.create({
294
+ title: requireTextField(args.title ?? args.name ?? args.summary, 'title'),
295
+ body: requireTextField(args.body ?? args.detail ?? args.description, 'body'),
296
+ tags: readStringList(args.tags),
297
+ sourceUrl: readString(args.sourceUrl) || undefined,
298
+ source: 'agent',
299
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
300
+ });
301
+ return [
302
+ 'Created Agent-local note',
303
+ ` id ${note.id}`,
304
+ ` title ${note.title}`,
305
+ ].join('\n');
306
+ }
307
+ if (action === 'update') {
308
+ const note = registry.update(requireId(args), {
309
+ title: readString(args.title ?? args.name ?? args.summary) || undefined,
310
+ body: readString(args.body ?? args.detail ?? args.description) || undefined,
311
+ tags: args.tags === undefined ? undefined : readStringList(args.tags),
312
+ sourceUrl: args.sourceUrl === undefined ? undefined : readString(args.sourceUrl),
313
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
314
+ });
315
+ return [
316
+ 'Updated Agent-local note',
317
+ ` id ${note.id}`,
318
+ ` title ${note.title}`,
319
+ ].join('\n');
320
+ }
321
+ if (action === 'review') {
322
+ const note = registry.markReviewed(requireId(args));
323
+ return [
324
+ 'Reviewed Agent-local note',
325
+ ` id ${note.id}`,
326
+ ].join('\n');
327
+ }
328
+ if (action === 'stale') {
329
+ const note = registry.markStale(requireId(args), readString(args.reason));
330
+ return [
331
+ 'Marked Agent-local note stale',
332
+ ` id ${note.id}`,
333
+ ].join('\n');
334
+ }
335
+ throw new Error(`Action ${action} is not valid for notes.`);
336
+ }
337
+
238
338
  function formatPersona(persona: AgentPersonaRecord, activeId: string | null): string {
239
339
  const active = persona.id === activeId ? 'active' : 'inactive';
240
- return `${persona.id} ${active} ${persona.reviewState} ${persona.name} - ${persona.description}`;
340
+ return `${persona.id} ${active} ${formatAgentRecordReviewState(persona.reviewState)} ${persona.name} - ${persona.description}`;
241
341
  }
242
342
 
243
343
  function formatSkill(skill: AgentSkillRecord): string {
244
344
  const enabled = skill.enabled ? 'enabled' : 'disabled';
245
- return `${skill.id} ${enabled} ${skill.reviewState} ${skill.name} - ${skill.description}`;
345
+ return `${skill.id} ${enabled} ${formatAgentRecordReviewState(skill.reviewState)} ${skill.name} - ${skill.description}`;
246
346
  }
247
347
 
248
348
  function formatSkillBundle(bundle: AgentSkillBundleRecord): string {
249
349
  const enabled = bundle.enabled ? 'enabled' : 'disabled';
250
- return `${bundle.id} ${enabled} ${bundle.reviewState} ${bundle.name} - ${bundle.description} skills=${bundle.skillIds.join(',')}`;
350
+ return `${bundle.id} ${enabled} ${formatAgentRecordReviewState(bundle.reviewState)} ${bundle.name} - ${bundle.description} skills ${bundle.skillIds.join(', ')}`;
251
351
  }
252
352
 
253
353
  function formatRoutine(routine: AgentRoutineRecord): string {
254
354
  const enabled = routine.enabled ? 'enabled' : 'disabled';
255
- return `${routine.id} ${enabled} ${routine.reviewState} starts=${routine.startCount} ${routine.name} - ${routine.description}`;
355
+ return `${routine.id} ${enabled} ${formatAgentRecordReviewState(routine.reviewState)} starts ${routine.startCount} ${routine.name} - ${routine.description}`;
256
356
  }
257
357
 
258
358
  function listPersonas(registry: AgentPersonaRegistry, records: readonly AgentPersonaRecord[], title: string): string {
@@ -286,11 +386,12 @@ function handlePersona(shellPaths: ShellPathService, action: AgentLocalRegistryA
286
386
  if (action === 'search') return listPersonas(registry, registry.search(readString(args.query)), 'Agent-local personas search');
287
387
  if (action === 'get') {
288
388
  const persona = registry.get(requireId(args));
289
- if (!persona) return `Unknown Agent-local persona: ${readString(args.id)}`;
389
+ if (!persona) return `Unknown Agent-local persona ${readString(args.id)}`;
290
390
  return [
291
391
  formatPersona(persona, registry.snapshot().activePersonaId),
292
- `triggers: ${persona.triggers.join(', ') || '(manual)'}`,
293
- `tags: ${persona.tags.join(', ') || '(none)'}`,
392
+ `origin ${formatAgentRecordOrigin(persona.source, persona.provenance)}`,
393
+ `triggers ${persona.triggers.join(', ') || '(manual)'}`,
394
+ `tags ${persona.tags.join(', ') || '(none)'}`,
294
395
  '',
295
396
  persona.body,
296
397
  ].join('\n');
@@ -299,13 +400,17 @@ function handlePersona(shellPaths: ShellPathService, action: AgentLocalRegistryA
299
400
  const persona = registry.create({
300
401
  name: requireName(args),
301
402
  description: requireDescription(args),
302
- body: readString(args.body),
403
+ body: requireTextField(args.body, 'body'),
303
404
  tags: readStringList(args.tags),
304
405
  triggers: readStringList(args.triggers),
305
406
  source: 'agent',
306
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
407
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
307
408
  });
308
- return `Created Agent-local persona ${persona.id}: ${persona.name}`;
409
+ return [
410
+ 'Created Agent-local persona',
411
+ ` id ${persona.id}`,
412
+ ` name ${persona.name}`,
413
+ ].join('\n');
309
414
  }
310
415
  if (action === 'update') {
311
416
  const persona = registry.update(requireId(args), {
@@ -314,20 +419,40 @@ function handlePersona(shellPaths: ShellPathService, action: AgentLocalRegistryA
314
419
  body: readString(args.body) || undefined,
315
420
  tags: args.tags === undefined ? undefined : readStringList(args.tags),
316
421
  triggers: args.triggers === undefined ? undefined : readStringList(args.triggers),
317
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
422
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
318
423
  });
319
- return `Updated Agent-local persona ${persona.id}: ${persona.name}`;
424
+ return [
425
+ 'Updated Agent-local persona',
426
+ ` id ${persona.id}`,
427
+ ` name ${persona.name}`,
428
+ ].join('\n');
320
429
  }
321
430
  if (action === 'use') {
322
431
  const persona = registry.setActive(requireId(args));
323
- return `Active Agent-local persona set to ${persona.id}: ${persona.name}`;
432
+ return [
433
+ 'Active Agent-local persona set',
434
+ ` id ${persona.id}`,
435
+ ` name ${persona.name}`,
436
+ ].join('\n');
324
437
  }
325
438
  if (action === 'clear_active') {
326
439
  registry.clearActive();
327
440
  return 'Cleared active Agent-local persona.';
328
441
  }
329
- if (action === 'review') return `Reviewed Agent-local persona ${registry.markReviewed(requireId(args)).id}.`;
330
- if (action === 'stale') return `Marked Agent-local persona ${registry.markStale(requireId(args), readString(args.reason)).id} stale.`;
442
+ if (action === 'review') {
443
+ const persona = registry.markReviewed(requireId(args));
444
+ return [
445
+ 'Reviewed Agent-local persona',
446
+ ` id ${persona.id}`,
447
+ ].join('\n');
448
+ }
449
+ if (action === 'stale') {
450
+ const persona = registry.markStale(requireId(args), readString(args.reason));
451
+ return [
452
+ 'Marked Agent-local persona stale',
453
+ ` id ${persona.id}`,
454
+ ].join('\n');
455
+ }
331
456
  throw new Error(`Action ${action} is not valid for personas.`);
332
457
  }
333
458
 
@@ -337,11 +462,13 @@ function handleSkill(shellPaths: ShellPathService, action: AgentLocalRegistryAct
337
462
  if (action === 'search') return listSkills(registry.search(readString(args.query)), 'Agent-local skills search');
338
463
  if (action === 'get') {
339
464
  const skill = registry.get(requireId(args));
340
- if (!skill) return `Unknown Agent-local skill: ${readString(args.id)}`;
465
+ if (!skill) return `Unknown Agent-local skill ${readString(args.id)}`;
341
466
  return [
342
467
  formatSkill(skill),
343
- `triggers: ${skill.triggers.join(', ') || '(manual)'}`,
344
- `tags: ${skill.tags.join(', ') || '(none)'}`,
468
+ `origin ${formatAgentRecordOrigin(skill.source, skill.provenance)}`,
469
+ `provenance: ${skill.provenance}`,
470
+ `triggers ${skill.triggers.join(', ') || '(manual)'}`,
471
+ `tags ${skill.tags.join(', ') || '(none)'}`,
345
472
  '',
346
473
  skill.procedure,
347
474
  ].join('\n');
@@ -350,14 +477,18 @@ function handleSkill(shellPaths: ShellPathService, action: AgentLocalRegistryAct
350
477
  const skill = registry.create({
351
478
  name: requireName(args),
352
479
  description: requireDescription(args),
353
- procedure: readString(args.procedure),
480
+ procedure: requireTextField(args.procedure, 'procedure'),
354
481
  triggers: readStringList(args.triggers),
355
482
  tags: readStringList(args.tags),
356
483
  enabled: args.enabled === true,
357
484
  source: 'agent',
358
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
485
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
359
486
  });
360
- return `Created Agent-local skill ${skill.id}: ${skill.name}`;
487
+ return [
488
+ `Created Agent-local skill ${skill.id}`,
489
+ ` id ${skill.id}`,
490
+ ` name ${skill.name}`,
491
+ ].join('\n');
361
492
  }
362
493
  if (action === 'update') {
363
494
  const skill = registry.update(requireId(args), {
@@ -366,16 +497,36 @@ function handleSkill(shellPaths: ShellPathService, action: AgentLocalRegistryAct
366
497
  procedure: readString(args.procedure) || undefined,
367
498
  triggers: args.triggers === undefined ? undefined : readStringList(args.triggers),
368
499
  tags: args.tags === undefined ? undefined : readStringList(args.tags),
369
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
500
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
370
501
  });
371
- return `Updated Agent-local skill ${skill.id}: ${skill.name}`;
502
+ return [
503
+ 'Updated Agent-local skill',
504
+ ` id ${skill.id}`,
505
+ ` name ${skill.name}`,
506
+ ].join('\n');
372
507
  }
373
508
  if (action === 'enable' || action === 'disable') {
374
509
  const skill = registry.setEnabled(requireId(args), action === 'enable');
375
- return `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local skill ${skill.id}: ${skill.name}`;
510
+ return [
511
+ `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local skill`,
512
+ ` id ${skill.id}`,
513
+ ` name ${skill.name}`,
514
+ ].join('\n');
515
+ }
516
+ if (action === 'review') {
517
+ const skill = registry.markReviewed(requireId(args));
518
+ return [
519
+ 'Reviewed Agent-local skill',
520
+ ` id ${skill.id}`,
521
+ ].join('\n');
522
+ }
523
+ if (action === 'stale') {
524
+ const skill = registry.markStale(requireId(args), readString(args.reason));
525
+ return [
526
+ 'Marked Agent-local skill stale',
527
+ ` id ${skill.id}`,
528
+ ].join('\n');
376
529
  }
377
- if (action === 'review') return `Reviewed Agent-local skill ${registry.markReviewed(requireId(args)).id}.`;
378
- if (action === 'stale') return `Marked Agent-local skill ${registry.markStale(requireId(args), readString(args.reason)).id} stale.`;
379
530
  throw new Error(`Action ${action} is not valid for skills.`);
380
531
  }
381
532
 
@@ -385,10 +536,11 @@ function handleSkillBundle(shellPaths: ShellPathService, action: AgentLocalRegis
385
536
  if (action === 'search') return listSkillBundles(registry.searchBundles(readString(args.query)), 'Agent-local skill bundles search');
386
537
  if (action === 'get') {
387
538
  const bundle = registry.getBundle(requireId(args));
388
- if (!bundle) return `Unknown Agent-local skill bundle: ${readString(args.id)}`;
539
+ if (!bundle) return `Unknown Agent-local skill bundle ${readString(args.id)}`;
389
540
  return [
390
541
  formatSkillBundle(bundle),
391
- `skills: ${bundle.skillIds.join(', ')}`,
542
+ `origin ${formatAgentRecordOrigin(bundle.source, bundle.provenance)}`,
543
+ `skills ${bundle.skillIds.join(', ')}`,
392
544
  '',
393
545
  bundle.description,
394
546
  ].join('\n');
@@ -400,25 +552,49 @@ function handleSkillBundle(shellPaths: ShellPathService, action: AgentLocalRegis
400
552
  skillIds: readStringList(args.skillIds ?? args.skills),
401
553
  enabled: args.enabled === true,
402
554
  source: 'agent',
403
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
555
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
404
556
  });
405
- return `Created Agent-local skill bundle ${bundle.id}: ${bundle.name}`;
557
+ return [
558
+ `Created Agent-local skill bundle ${bundle.id}`,
559
+ ` id ${bundle.id}`,
560
+ ` name ${bundle.name}`,
561
+ ].join('\n');
406
562
  }
407
563
  if (action === 'update') {
408
564
  const bundle = registry.updateBundle(requireId(args), {
409
565
  name: readString(args.name) || undefined,
410
566
  description: readString(args.description) || undefined,
411
567
  skillIds: args.skillIds === undefined && args.skills === undefined ? undefined : readStringList(args.skillIds ?? args.skills),
412
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
568
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
413
569
  });
414
- return `Updated Agent-local skill bundle ${bundle.id}: ${bundle.name}`;
570
+ return [
571
+ 'Updated Agent-local skill bundle',
572
+ ` id ${bundle.id}`,
573
+ ` name ${bundle.name}`,
574
+ ].join('\n');
415
575
  }
416
576
  if (action === 'enable' || action === 'disable') {
417
577
  const bundle = registry.setBundleEnabled(requireId(args), action === 'enable');
418
- return `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local skill bundle ${bundle.id}: ${bundle.name}`;
578
+ return [
579
+ `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local skill bundle`,
580
+ ` id ${bundle.id}`,
581
+ ` name ${bundle.name}`,
582
+ ].join('\n');
583
+ }
584
+ if (action === 'review') {
585
+ const bundle = registry.markBundleReviewed(requireId(args));
586
+ return [
587
+ 'Reviewed Agent-local skill bundle',
588
+ ` id ${bundle.id}`,
589
+ ].join('\n');
590
+ }
591
+ if (action === 'stale') {
592
+ const bundle = registry.markBundleStale(requireId(args), readString(args.reason));
593
+ return [
594
+ 'Marked Agent-local skill bundle stale',
595
+ ` id ${bundle.id}`,
596
+ ].join('\n');
419
597
  }
420
- if (action === 'review') return `Reviewed Agent-local skill bundle ${registry.markBundleReviewed(requireId(args)).id}.`;
421
- if (action === 'stale') return `Marked Agent-local skill bundle ${registry.markBundleStale(requireId(args), readString(args.reason)).id} stale.`;
422
598
  throw new Error(`Action ${action} is not valid for skill bundles.`);
423
599
  }
424
600
 
@@ -428,11 +604,12 @@ function handleRoutine(shellPaths: ShellPathService, action: AgentLocalRegistryA
428
604
  if (action === 'search') return listRoutines(registry.search(readString(args.query)), 'Agent-local routines search');
429
605
  if (action === 'get') {
430
606
  const routine = registry.get(requireId(args));
431
- if (!routine) return `Unknown Agent-local routine: ${readString(args.id)}`;
607
+ if (!routine) return `Unknown Agent-local routine ${readString(args.id)}`;
432
608
  return [
433
609
  formatRoutine(routine),
434
- `triggers: ${routine.triggers.join(', ') || '(manual)'}`,
435
- `tags: ${routine.tags.join(', ') || '(none)'}`,
610
+ `origin ${formatAgentRecordOrigin(routine.source, routine.provenance)}`,
611
+ `triggers ${routine.triggers.join(', ') || '(manual)'}`,
612
+ `tags ${routine.tags.join(', ') || '(none)'}`,
436
613
  '',
437
614
  routine.steps,
438
615
  ].join('\n');
@@ -441,14 +618,18 @@ function handleRoutine(shellPaths: ShellPathService, action: AgentLocalRegistryA
441
618
  const routine = registry.create({
442
619
  name: requireName(args),
443
620
  description: requireDescription(args),
444
- steps: readString(args.steps),
621
+ steps: requireTextField(args.steps, 'steps'),
445
622
  triggers: readStringList(args.triggers),
446
623
  tags: readStringList(args.tags),
447
624
  enabled: args.enabled === true,
448
625
  source: 'agent',
449
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
626
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
450
627
  });
451
- return `Created Agent-local routine ${routine.id}: ${routine.name}`;
628
+ return [
629
+ 'Created Agent-local routine',
630
+ ` id ${routine.id}`,
631
+ ` name ${routine.name}`,
632
+ ].join('\n');
452
633
  }
453
634
  if (action === 'update') {
454
635
  const routine = registry.update(requireId(args), {
@@ -457,25 +638,47 @@ function handleRoutine(shellPaths: ShellPathService, action: AgentLocalRegistryA
457
638
  steps: readString(args.steps) || undefined,
458
639
  triggers: args.triggers === undefined ? undefined : readStringList(args.triggers),
459
640
  tags: args.tags === undefined ? undefined : readStringList(args.tags),
460
- provenance: readString(args.provenance) || 'agent-local-registry-tool',
641
+ provenance: readString(args.provenance) || AGENT_TOOL_PROVENANCE,
461
642
  });
462
- return `Updated Agent-local routine ${routine.id}: ${routine.name}`;
643
+ return [
644
+ 'Updated Agent-local routine',
645
+ ` id ${routine.id}`,
646
+ ` name ${routine.name}`,
647
+ ].join('\n');
463
648
  }
464
649
  if (action === 'enable' || action === 'disable') {
465
650
  const routine = registry.setEnabled(requireId(args), action === 'enable');
466
- return `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local routine ${routine.id}: ${routine.name}`;
651
+ return [
652
+ `${action === 'enable' ? 'Enabled' : 'Disabled'} Agent-local routine`,
653
+ ` id ${routine.id}`,
654
+ ` name ${routine.name}`,
655
+ ].join('\n');
467
656
  }
468
657
  if (action === 'start') {
469
658
  const routine = registry.markStarted(requireId(args));
470
659
  return [
471
- `Started Agent-local routine ${routine.id}: ${routine.name}`,
472
- 'Policy: same main conversation; no hidden background job, daemon mutation, or external side effect was started.',
660
+ 'Started Agent-local routine',
661
+ ` id ${routine.id}`,
662
+ ` name ${routine.name}`,
663
+ 'Policy: same main conversation; no hidden background job, connected-host mutation, or external side effect was started.',
473
664
  '',
474
665
  routine.steps,
475
666
  ].join('\n');
476
667
  }
477
- if (action === 'review') return `Reviewed Agent-local routine ${registry.markReviewed(requireId(args)).id}.`;
478
- if (action === 'stale') return `Marked Agent-local routine ${registry.markStale(requireId(args), readString(args.reason)).id} stale.`;
668
+ if (action === 'review') {
669
+ const routine = registry.markReviewed(requireId(args));
670
+ return [
671
+ 'Reviewed Agent-local routine',
672
+ ` id ${routine.id}`,
673
+ ].join('\n');
674
+ }
675
+ if (action === 'stale') {
676
+ const routine = registry.markStale(requireId(args), readString(args.reason));
677
+ return [
678
+ 'Marked Agent-local routine stale',
679
+ ` id ${routine.id}`,
680
+ ].join('\n');
681
+ }
479
682
  throw new Error(`Action ${action} is not valid for routines.`);
480
683
  }
481
684
 
@@ -484,9 +687,9 @@ export function createAgentLocalRegistryTool(shellPaths: ShellPathService, memor
484
687
  definition: {
485
688
  name: 'agent_local_registry',
486
689
  description: [
487
- 'Inspect and maintain GoodVibes Agent-local memory, personas, skills, and routines from the main conversation.',
488
- 'Use this for safe self-improvement: remember durable non-secret facts, create or refine reusable behavior, bundle related skills, enable skills/routines, choose personas, review/stale records, and start routines in the same serial conversation.',
489
- 'This tool cannot delete records, create schedules, mutate connected services, send messages, run background jobs, or delegate build work.',
690
+ 'Inspect and maintain GoodVibes Agent-local notes, memory, personas, skills, and routines from the main conversation.',
691
+ 'Use this for safe self-improvement: capture scratchpad notes, remember durable non-secret facts, create or refine reusable behavior, bundle related skills, enable skills/routines, choose personas, review/stale records, and start routines in the same serial conversation.',
692
+ 'This tool cannot delete records, create schedules, mutate connected hosts, send messages, run background jobs, or delegate build work.',
490
693
  ].join(' '),
491
694
  parameters: {
492
695
  type: 'object',
@@ -500,9 +703,11 @@ export function createAgentLocalRegistryTool(shellPaths: ShellPathService, memor
500
703
  summary: { type: 'string', description: 'Memory summary when domain is memory.' },
501
704
  detail: { type: 'string', description: 'Memory detail when domain is memory.' },
502
705
  confidence: { type: 'number', description: 'Memory review confidence from 0 to 100.' },
706
+ title: { type: 'string', description: 'Note title when domain is note.' },
503
707
  name: { type: 'string' },
504
708
  description: { type: 'string' },
505
- body: { type: 'string', description: 'Persona body/instructions.' },
709
+ body: { type: 'string', description: 'Note body or persona body/instructions.' },
710
+ sourceUrl: { type: 'string', description: 'Optional source URL when domain is note.' },
506
711
  procedure: { type: 'string', description: 'Skill procedure.' },
507
712
  steps: { type: 'string', description: 'Routine steps.' },
508
713
  skills: { type: 'array', items: { type: 'string' }, description: 'Skill ids for skill_bundle create/update.' },
@@ -520,10 +725,11 @@ export function createAgentLocalRegistryTool(shellPaths: ShellPathService, memor
520
725
  },
521
726
  execute: async (rawArgs: unknown) => {
522
727
  const args = rawArgs as AgentLocalRegistryToolArgs;
523
- if (!isDomain(args.domain)) return registryError(`Unknown domain. Valid: ${DOMAINS.join(', ')}.`);
524
- if (!isAction(args.action)) return registryError(`Unknown action. Valid: ${ACTIONS.join(', ')}.`);
728
+ if (!isDomain(args.domain)) return registryError(`Unknown domain. Valid values ${DOMAINS.join(', ')}.`);
729
+ if (!isAction(args.action)) return registryError(`Unknown action. Valid values ${ACTIONS.join(', ')}.`);
525
730
  try {
526
731
  if (args.domain === 'memory') return registryOutput(await handleMemory(memoryRegistry, args.action, args));
732
+ if (args.domain === 'note') return registryOutput(handleNote(shellPaths, args.action, args));
527
733
  if (args.domain === 'persona') return registryOutput(handlePersona(shellPaths, args.action, args));
528
734
  if (args.domain === 'skill') return registryOutput(handleSkill(shellPaths, args.action, args));
529
735
  if (args.domain === 'skill_bundle') return registryOutput(handleSkillBundle(shellPaths, args.action, args));