@robota-sdk/agent-command 3.0.0-beta.100

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 (251) hide show
  1. package/CHANGELOG.md +1351 -0
  2. package/LICENSE +661 -0
  3. package/README.md +100 -0
  4. package/dist/node/index.cjs +121 -0
  5. package/dist/node/index.d.cts +1053 -0
  6. package/dist/node/index.d.cts.map +1 -0
  7. package/dist/node/index.d.ts +1053 -0
  8. package/dist/node/index.d.ts.map +1 -0
  9. package/dist/node/index.js +122 -0
  10. package/dist/node/index.js.map +1 -0
  11. package/package.json +83 -0
  12. package/src/advisor/advisor-command-module.ts +47 -0
  13. package/src/advisor/advisor-command.test.ts +102 -0
  14. package/src/advisor/advisor-command.ts +55 -0
  15. package/src/advisor/advisor-cost-functional.test.ts +92 -0
  16. package/src/advisor/index.ts +6 -0
  17. package/src/agent/__tests__/agent-command.test.ts +597 -0
  18. package/src/agent/agent-command-module.ts +89 -0
  19. package/src/agent/agent-command-parser.ts +180 -0
  20. package/src/agent/agent-command.ts +255 -0
  21. package/src/agent/index.ts +7 -0
  22. package/src/background/__tests__/background-command-module.test.ts +261 -0
  23. package/src/background/background-command-module.ts +52 -0
  24. package/src/background/background-command.ts +65 -0
  25. package/src/background/index.ts +6 -0
  26. package/src/command-module-utils.test.ts +37 -0
  27. package/src/command-module-utils.ts +35 -0
  28. package/src/compact/__tests__/compact-command-module.test.ts +181 -0
  29. package/src/compact/compact-command-module.ts +59 -0
  30. package/src/compact/compact-command.ts +33 -0
  31. package/src/compact/index.ts +6 -0
  32. package/src/context/__tests__/context-command-module.test.ts +502 -0
  33. package/src/context/auto-compact-format.ts +25 -0
  34. package/src/context/context-breakdown.ts +295 -0
  35. package/src/context/context-command-module.ts +82 -0
  36. package/src/context/context-command.ts +291 -0
  37. package/src/context/index.ts +6 -0
  38. package/src/default/__tests__/__snapshots__/model-exposure.test.ts.snap +121 -0
  39. package/src/default/__tests__/default-command-modules.test.ts +192 -0
  40. package/src/default/__tests__/model-exposure.test.ts +269 -0
  41. package/src/default/__tests__/org-policy-forwarding.test.ts +106 -0
  42. package/src/default/__tests__/provider-environment-forwarding.test.ts +98 -0
  43. package/src/default/default-command-modules.ts +247 -0
  44. package/src/default/index.ts +5 -0
  45. package/src/devices/__tests__/devices-command-module.test.ts +299 -0
  46. package/src/devices/devices-command-module.ts +308 -0
  47. package/src/devices/devices-command-port.ts +143 -0
  48. package/src/devices/index.ts +14 -0
  49. package/src/doctor/__tests__/doctor-command-module.test.ts +145 -0
  50. package/src/doctor/__tests__/doctor-display-vocabulary.test.ts +38 -0
  51. package/src/doctor/__tests__/doctor-fixture.ts +146 -0
  52. package/src/doctor/__tests__/doctor-redaction.test.ts +29 -0
  53. package/src/doctor/__tests__/doctor-runner.test.ts +484 -0
  54. package/src/doctor/doctor-command-module.ts +132 -0
  55. package/src/doctor/doctor-extensions-probe.ts +323 -0
  56. package/src/doctor/doctor-node-deps.ts +88 -0
  57. package/src/doctor/doctor-redaction.ts +99 -0
  58. package/src/doctor/doctor-render.ts +70 -0
  59. package/src/doctor/doctor-repair.ts +136 -0
  60. package/src/doctor/doctor-runner.ts +122 -0
  61. package/src/doctor/doctor-settings-probe.ts +239 -0
  62. package/src/doctor/doctor-storage-probe.ts +187 -0
  63. package/src/doctor/doctor-types.ts +109 -0
  64. package/src/doctor/index.ts +32 -0
  65. package/src/editor/__tests__/editor-command-functional.test.ts +124 -0
  66. package/src/editor/editor-command-module.ts +53 -0
  67. package/src/editor/editor-command.ts +58 -0
  68. package/src/editor/index.ts +7 -0
  69. package/src/editor/resolve-editor.ts +21 -0
  70. package/src/effort/effort-command-module.ts +51 -0
  71. package/src/effort/effort-command.test.ts +203 -0
  72. package/src/effort/effort-command.ts +136 -0
  73. package/src/effort/index.ts +6 -0
  74. package/src/events/__tests__/events-command.test.ts +73 -0
  75. package/src/events/events-command-module.ts +49 -0
  76. package/src/events/events-command.ts +69 -0
  77. package/src/events/index.ts +2 -0
  78. package/src/exit/__tests__/exit-command-module.test.ts +61 -0
  79. package/src/exit/exit-command-module.ts +47 -0
  80. package/src/exit/exit-command.ts +26 -0
  81. package/src/exit/index.ts +6 -0
  82. package/src/fork/__tests__/fork-command.test.ts +184 -0
  83. package/src/fork/fork-command-module.ts +61 -0
  84. package/src/fork/fork-command.ts +162 -0
  85. package/src/fork/index.ts +8 -0
  86. package/src/git/__tests__/fake-git-port.ts +35 -0
  87. package/src/git/__tests__/git-command-module.test.ts +111 -0
  88. package/src/git/__tests__/git-commit.test.ts +185 -0
  89. package/src/git/git-command-module.ts +138 -0
  90. package/src/git/git-commit.ts +254 -0
  91. package/src/git/index.ts +20 -0
  92. package/src/goal/__tests__/goal-command.test.ts +80 -0
  93. package/src/goal/goal-command-module.ts +49 -0
  94. package/src/goal/goal-command.ts +69 -0
  95. package/src/goal/index.ts +6 -0
  96. package/src/handoff/__tests__/handoff-command-module.test.ts +25 -0
  97. package/src/handoff/__tests__/handoff-command.test.ts +218 -0
  98. package/src/handoff/handoff-command-module.ts +49 -0
  99. package/src/handoff/handoff-command.ts +187 -0
  100. package/src/handoff/index.ts +6 -0
  101. package/src/help/__tests__/help-command-module.test.ts +134 -0
  102. package/src/help/__tests__/help-command.test.ts +130 -0
  103. package/src/help/help-command-module.ts +47 -0
  104. package/src/help/help-command.ts +11 -0
  105. package/src/help/index.ts +6 -0
  106. package/src/index.ts +163 -0
  107. package/src/keybindings/__tests__/keybindings-command-module.test.ts +57 -0
  108. package/src/keybindings/index.ts +6 -0
  109. package/src/keybindings/keybindings-command-module.ts +88 -0
  110. package/src/language/__tests__/language-command-module.test.ts +126 -0
  111. package/src/language/index.ts +6 -0
  112. package/src/language/language-command-module.ts +55 -0
  113. package/src/language/language-command.ts +52 -0
  114. package/src/mcp-activation/__tests__/mcp-activation-command.test.ts +895 -0
  115. package/src/mcp-activation/__tests__/mcp-model-view.test.ts +242 -0
  116. package/src/mcp-activation/__tests__/mcp-skill-command.test.ts +141 -0
  117. package/src/mcp-activation/index.ts +12 -0
  118. package/src/mcp-activation/mcp-activation-command-module.ts +123 -0
  119. package/src/mcp-activation/mcp-activation-command.ts +662 -0
  120. package/src/mcp-activation/mcp-model-notice.ts +99 -0
  121. package/src/mcp-activation/mcp-model-status.ts +104 -0
  122. package/src/memory/__tests__/memory-command-module.test.ts +476 -0
  123. package/src/memory/__tests__/memory-command-unavailable.test.ts +63 -0
  124. package/src/memory/index.ts +6 -0
  125. package/src/memory/memory-command-module.ts +77 -0
  126. package/src/memory/memory-command.ts +326 -0
  127. package/src/mode/__tests__/mode-command-module.test.ts +230 -0
  128. package/src/mode/index.ts +6 -0
  129. package/src/mode/mode-command-module.ts +55 -0
  130. package/src/mode/mode-command.ts +67 -0
  131. package/src/model/__tests__/model-command-module.test.ts +80 -0
  132. package/src/model/__tests__/model-command.test.ts +265 -0
  133. package/src/model/index.ts +6 -0
  134. package/src/model/model-command-module.ts +56 -0
  135. package/src/model/model-command.ts +249 -0
  136. package/src/output-style/__tests__/output-style-command.test.ts +96 -0
  137. package/src/output-style/index.ts +6 -0
  138. package/src/output-style/output-style-command-module.ts +143 -0
  139. package/src/peers/__tests__/peers-command-module.test.ts +24 -0
  140. package/src/peers/__tests__/peers-command.test.ts +399 -0
  141. package/src/peers/index.ts +9 -0
  142. package/src/peers/peers-command-module.ts +49 -0
  143. package/src/peers/peers-command.ts +220 -0
  144. package/src/permissions/__tests__/permissions-command-module.test.ts +276 -0
  145. package/src/permissions/index.ts +6 -0
  146. package/src/permissions/permissions-command-module.ts +55 -0
  147. package/src/permissions/permissions-command.ts +89 -0
  148. package/src/plan/__tests__/plan-command.test.ts +129 -0
  149. package/src/plan/index.ts +9 -0
  150. package/src/plan/plan-command-module.ts +49 -0
  151. package/src/plan/plan-command.ts +92 -0
  152. package/src/plugin/__tests__/plugin-active-turn.test.ts +100 -0
  153. package/src/plugin/__tests__/plugin-command-module.test.ts +300 -0
  154. package/src/plugin/__tests__/plugin-host-boundary.test.ts +11 -0
  155. package/src/plugin/index.ts +7 -0
  156. package/src/plugin/plugin-command-module.ts +85 -0
  157. package/src/plugin/plugin-command.ts +271 -0
  158. package/src/preset/__tests__/host-supplied-preset-registry.test.ts +98 -0
  159. package/src/preset/__tests__/preset-command-module.test.ts +220 -0
  160. package/src/preset/index.ts +6 -0
  161. package/src/preset/preset-command-module.ts +80 -0
  162. package/src/preset/preset-command.ts +148 -0
  163. package/src/provider/__tests__/optional-provider-credentials.test.ts +130 -0
  164. package/src/provider/__tests__/org-policy.test.ts +174 -0
  165. package/src/provider/__tests__/provider-command-module.test.ts +884 -0
  166. package/src/provider/__tests__/provider-connection-setup.test.ts +567 -0
  167. package/src/provider/__tests__/provider-reference-switch.test.ts +113 -0
  168. package/src/provider/__tests__/provider-setup-flow.test.ts +244 -0
  169. package/src/provider/__tests__/provider-startup-host-settings.test.ts +16 -0
  170. package/src/provider/__tests__/scripted-interaction.ts +40 -0
  171. package/src/provider/index.ts +32 -0
  172. package/src/provider/provider-command-execution.ts +235 -0
  173. package/src/provider/provider-command-module.ts +82 -0
  174. package/src/provider/provider-command-profile-lifecycle.ts +239 -0
  175. package/src/provider/provider-command-profile-operations.ts +218 -0
  176. package/src/provider/provider-command-profile.ts +116 -0
  177. package/src/provider/provider-command-setup.ts +79 -0
  178. package/src/provider/provider-connection-setup.ts +287 -0
  179. package/src/provider/provider-connection-validation.ts +38 -0
  180. package/src/provider/provider-onboarding.ts +73 -0
  181. package/src/provider/provider-prompt-interaction.ts +28 -0
  182. package/src/provider/provider-setup-ask.ts +67 -0
  183. package/src/provider/provider-setup-flow.ts +326 -0
  184. package/src/provider/provider-startup.ts +225 -0
  185. package/src/remote-control/__tests__/remote-control-command-module.test.ts +36 -0
  186. package/src/remote-control/__tests__/remote-control-command.test.ts +216 -0
  187. package/src/remote-control/index.ts +8 -0
  188. package/src/remote-control/remote-control-command-module.ts +61 -0
  189. package/src/remote-control/remote-control-command.ts +138 -0
  190. package/src/reset/__tests__/reset-command-module.test.ts +63 -0
  191. package/src/reset/index.ts +2 -0
  192. package/src/reset/reset-command-module.ts +47 -0
  193. package/src/reset/reset-command.ts +10 -0
  194. package/src/rewind/__tests__/rewind-command-module.test.ts +287 -0
  195. package/src/rewind/index.ts +2 -0
  196. package/src/rewind/rewind-command-module.ts +56 -0
  197. package/src/rewind/rewind-command.ts +279 -0
  198. package/src/sandbox/__tests__/sandbox-command.test.ts +80 -0
  199. package/src/sandbox/index.ts +2 -0
  200. package/src/sandbox/sandbox-command-module.ts +56 -0
  201. package/src/sandbox/sandbox-command.ts +94 -0
  202. package/src/schedule/__tests__/loop-command-functional.test.ts +399 -0
  203. package/src/schedule/__tests__/loop-command.test.ts +594 -0
  204. package/src/schedule/__tests__/loop-jitter.test.ts +25 -0
  205. package/src/schedule/__tests__/monitor-model-permission-functional.test.ts +126 -0
  206. package/src/schedule/__tests__/schedule-command.test.ts +247 -0
  207. package/src/schedule/__tests__/schedule-redos.test.ts +114 -0
  208. package/src/schedule/index.ts +12 -0
  209. package/src/schedule/loop-command.ts +427 -0
  210. package/src/schedule/loop-jitter.ts +41 -0
  211. package/src/schedule/schedule-command-module.ts +184 -0
  212. package/src/schedule/schedule-command.ts +161 -0
  213. package/src/schedule/schedule-spec-parser.ts +70 -0
  214. package/src/session/__tests__/model-pricing.test.ts +66 -0
  215. package/src/session/__tests__/rename-host-persistence.test.ts +72 -0
  216. package/src/session/__tests__/session-command-module.test.ts +589 -0
  217. package/src/session/index.ts +17 -0
  218. package/src/session/model-pricing.ts +26 -0
  219. package/src/session/session-command-module.ts +197 -0
  220. package/src/session/session-command.ts +272 -0
  221. package/src/settings/index.ts +7 -0
  222. package/src/settings/settings-command-module.ts +47 -0
  223. package/src/shell/__tests__/resolve-shell-host.test.ts +11 -0
  224. package/src/shell/__tests__/shell-command-functional.test.ts +118 -0
  225. package/src/shell/index.ts +8 -0
  226. package/src/shell/resolve-shell.ts +25 -0
  227. package/src/shell/shell-command-module.ts +53 -0
  228. package/src/shell/shell-command.ts +48 -0
  229. package/src/shell/spawn-inherited.ts +32 -0
  230. package/src/skills/__tests__/skill-read-command.test.ts +64 -0
  231. package/src/skills/__tests__/skills-command-module.test.ts +200 -0
  232. package/src/skills/index.ts +7 -0
  233. package/src/skills/skill-read-command.ts +60 -0
  234. package/src/skills/skills-command-module.ts +76 -0
  235. package/src/skills/skills-command.ts +108 -0
  236. package/src/statusline/__tests__/statusline-command-module.test.ts +96 -0
  237. package/src/statusline/index.ts +6 -0
  238. package/src/statusline/statusline-command-module.ts +55 -0
  239. package/src/statusline/statusline-command.ts +80 -0
  240. package/src/terminal-client/__tests__/terminal-client-commands.test.ts +216 -0
  241. package/src/terminal-client/index.ts +5 -0
  242. package/src/terminal-client/terminal-client-commands.ts +109 -0
  243. package/src/theme/__tests__/theme-command.test.ts +204 -0
  244. package/src/theme/index.ts +12 -0
  245. package/src/theme/theme-command-module.ts +221 -0
  246. package/src/user-local/__tests__/user-local-command.test.ts +180 -0
  247. package/src/user-local/index.ts +13 -0
  248. package/src/user-local/user-local-command-constants.ts +5 -0
  249. package/src/user-local/user-local-command-module.ts +65 -0
  250. package/src/user-local/user-local-command.ts +214 -0
  251. package/src/user-local/user-local-memory-command.ts +160 -0
@@ -0,0 +1,65 @@
1
+ import {
2
+ USER_LOCAL_COMMAND_ARGUMENT_HINT,
3
+ USER_LOCAL_COMMAND_DESCRIPTION,
4
+ executeUserLocalCommand,
5
+ } from './user-local-command.js';
6
+
7
+ import type { ICommandModule, ISystemCommand } from '@robota-sdk/agent-framework';
8
+ import type { ICommand, ICommandSource } from '@robota-sdk/agent-interface-command';
9
+
10
+ export function createUserLocalCommandEntry(): ICommand {
11
+ return {
12
+ name: 'user-local',
13
+ displayName: 'User Config',
14
+ description: USER_LOCAL_COMMAND_DESCRIPTION,
15
+ source: 'user-local',
16
+ argumentHint: USER_LOCAL_COMMAND_ARGUMENT_HINT,
17
+ // User-only: the user's private cross-project storage.
18
+ modelInvocable: false,
19
+ safety: 'read-only',
20
+ subcommands: [
21
+ {
22
+ name: 'storage',
23
+ description: 'Inspect user-local storage categories',
24
+ source: 'user-local',
25
+ },
26
+ {
27
+ name: 'memory',
28
+ description: 'Inspect and manage user-local memory items',
29
+ source: 'user-local',
30
+ },
31
+ ],
32
+ };
33
+ }
34
+
35
+ function createUserLocalSystemCommand(storageRoot: string): ISystemCommand {
36
+ const entry = createUserLocalCommandEntry();
37
+ return {
38
+ name: entry.name,
39
+ displayName: entry.displayName,
40
+ description: entry.description,
41
+ requiresPermission: false,
42
+ userInvocable: true,
43
+ modelInvocable: false,
44
+ argumentHint: entry.argumentHint,
45
+ safety: entry.safety,
46
+ subcommands: entry.subcommands,
47
+ execute: (context, rawArgs) => executeUserLocalCommand(context, rawArgs, storageRoot),
48
+ };
49
+ }
50
+
51
+ export class UserLocalCommandSource implements ICommandSource {
52
+ readonly name = 'user-local';
53
+
54
+ getCommands(): ICommand[] {
55
+ return [createUserLocalCommandEntry()];
56
+ }
57
+ }
58
+
59
+ export function createUserLocalCommandModule(storageRoot: string): ICommandModule {
60
+ return {
61
+ name: 'agent-command-user-local',
62
+ commandSources: [new UserLocalCommandSource()],
63
+ systemCommands: [createUserLocalSystemCommand(storageRoot)],
64
+ };
65
+ }
@@ -0,0 +1,214 @@
1
+ import { inspectUserLocalStorage } from '@robota-sdk/agent-framework';
2
+
3
+ import { USER_LOCAL_COMMAND_USAGE } from './user-local-command-constants.js';
4
+ import { executeMemoryCommand } from './user-local-memory-command.js';
5
+
6
+ import type { ICommandHostWorkspace } from '@robota-sdk/agent-framework';
7
+ import type { ICommandResult } from '@robota-sdk/agent-interface-command';
8
+ export {
9
+ USER_LOCAL_COMMAND_ARGUMENT_HINT,
10
+ USER_LOCAL_COMMAND_DESCRIPTION,
11
+ USER_LOCAL_COMMAND_USAGE,
12
+ } from './user-local-command-constants.js';
13
+
14
+ type TUserLocalOutputFormat = 'text' | 'json';
15
+
16
+ export interface IUserLocalDirectCommandOptions {
17
+ readonly cwd: string;
18
+ readonly storageRoot: string;
19
+ readonly argv: readonly string[];
20
+ readonly format?: string;
21
+ readonly summary?: string;
22
+ readonly source?: string;
23
+ }
24
+
25
+ interface IParsedUserLocalCommand {
26
+ readonly target?: string;
27
+ readonly action?: string;
28
+ readonly positional: readonly string[];
29
+ readonly format: TUserLocalOutputFormat;
30
+ readonly summary?: string;
31
+ readonly source?: string;
32
+ }
33
+
34
+ interface IParsedUserLocalOption {
35
+ readonly format?: string;
36
+ readonly summary?: string;
37
+ readonly source?: string;
38
+ readonly nextIndex: number;
39
+ }
40
+
41
+ function parseOutputFormat(value: string | undefined): TUserLocalOutputFormat {
42
+ if (value === undefined || value === 'text') {
43
+ return 'text';
44
+ }
45
+ if (value === 'json') {
46
+ return 'json';
47
+ }
48
+ throw new Error(`Unsupported user-local output format: ${value}`);
49
+ }
50
+
51
+ function parseUserLocalOption(
52
+ arg: string,
53
+ argv: readonly string[],
54
+ index: number,
55
+ ): IParsedUserLocalOption | null {
56
+ if (arg === '--format') {
57
+ return { format: argv[index + 1], nextIndex: index + 1 };
58
+ }
59
+ if (arg.startsWith('--format=')) {
60
+ return { format: arg.slice('--format='.length), nextIndex: index };
61
+ }
62
+ if (arg === '--summary') {
63
+ return { summary: argv[index + 1], nextIndex: index + 1 };
64
+ }
65
+ if (arg.startsWith('--summary=')) {
66
+ return { summary: arg.slice('--summary='.length), nextIndex: index };
67
+ }
68
+ if (arg === '--source') {
69
+ return { source: argv[index + 1], nextIndex: index + 1 };
70
+ }
71
+ if (arg.startsWith('--source=')) {
72
+ return { source: arg.slice('--source='.length), nextIndex: index };
73
+ }
74
+ return null;
75
+ }
76
+
77
+ function parseUserLocalArgs(
78
+ argv: readonly string[],
79
+ directOptions: {
80
+ readonly format?: string;
81
+ readonly summary?: string;
82
+ readonly source?: string;
83
+ } = {},
84
+ ): IParsedUserLocalCommand {
85
+ let format = directOptions.format;
86
+ let summary = directOptions.summary;
87
+ let source = directOptions.source;
88
+ const positional: string[] = [];
89
+
90
+ for (let index = 0; index < argv.length; index += 1) {
91
+ const arg = argv[index];
92
+ const option = parseUserLocalOption(arg, argv, index);
93
+ if (option !== null) {
94
+ format = option.format ?? format;
95
+ summary = option.summary ?? summary;
96
+ source = option.source ?? source;
97
+ index = option.nextIndex;
98
+ continue;
99
+ }
100
+ positional.push(arg);
101
+ }
102
+
103
+ return {
104
+ target: positional[0],
105
+ action: positional[1],
106
+ positional: positional.slice(2),
107
+ format: parseOutputFormat(format),
108
+ summary,
109
+ source,
110
+ };
111
+ }
112
+
113
+ function splitRawArgs(rawArgs: string): readonly string[] {
114
+ return rawArgs.trim().split(/\s+/).filter(Boolean);
115
+ }
116
+
117
+ function formatStorageInspectionText(
118
+ root: string,
119
+ categories: readonly { category: string }[],
120
+ ): string {
121
+ const categoryLines = categories.map((item) => `- ${item.category}`);
122
+ return [`User-local storage root: ${root}`, 'Categories:', ...categoryLines].join('\n');
123
+ }
124
+
125
+ async function executeStorageCommand(
126
+ cwd: string,
127
+ storageRoot: string,
128
+ parsed: IParsedUserLocalCommand,
129
+ ): Promise<ICommandResult> {
130
+ if ((parsed.action ?? 'list') !== 'list') {
131
+ return {
132
+ message: USER_LOCAL_COMMAND_USAGE,
133
+ success: false,
134
+ };
135
+ }
136
+
137
+ const inspection = await inspectUserLocalStorage({ activeRepositoryRoot: cwd, storageRoot });
138
+ return {
139
+ message:
140
+ parsed.format === 'json'
141
+ ? JSON.stringify(inspection, null, 2)
142
+ : formatStorageInspectionText(inspection.root, inspection.categories),
143
+ success: true,
144
+ data: {
145
+ root: inspection.root,
146
+ categories: inspection.categories,
147
+ inspection,
148
+ },
149
+ };
150
+ }
151
+
152
+ async function executeParsedUserLocalCommand(
153
+ cwd: string,
154
+ storageRoot: string,
155
+ parsed: IParsedUserLocalCommand,
156
+ ): Promise<ICommandResult> {
157
+ if (parsed.target === 'storage') {
158
+ return executeStorageCommand(cwd, storageRoot, parsed);
159
+ }
160
+ if (parsed.target === 'memory') {
161
+ return executeMemoryCommand(cwd, storageRoot, parsed);
162
+ }
163
+ return {
164
+ message: USER_LOCAL_COMMAND_USAGE,
165
+ success: false,
166
+ };
167
+ }
168
+
169
+ function formatCommandErrorMessage(errorMessage: string): string {
170
+ if (errorMessage.includes('ENOENT')) {
171
+ return 'User-local memory item not found.';
172
+ }
173
+ return errorMessage;
174
+ }
175
+
176
+ export async function executeUserLocalDirectCommand(
177
+ options: IUserLocalDirectCommandOptions,
178
+ ): Promise<ICommandResult> {
179
+ try {
180
+ return await executeParsedUserLocalCommand(
181
+ options.cwd,
182
+ options.storageRoot,
183
+ parseUserLocalArgs(options.argv, {
184
+ format: options.format,
185
+ summary: options.summary,
186
+ source: options.source,
187
+ }),
188
+ );
189
+ } catch (error) {
190
+ return {
191
+ message: formatCommandErrorMessage(error instanceof Error ? error.message : String(error)),
192
+ success: false,
193
+ };
194
+ }
195
+ }
196
+
197
+ export async function executeUserLocalCommand(
198
+ context: ICommandHostWorkspace,
199
+ rawArgs: string,
200
+ storageRoot: string,
201
+ ): Promise<ICommandResult> {
202
+ try {
203
+ return await executeParsedUserLocalCommand(
204
+ context.getCwd(),
205
+ storageRoot,
206
+ parseUserLocalArgs(splitRawArgs(rawArgs)),
207
+ );
208
+ } catch (error) {
209
+ return {
210
+ message: formatCommandErrorMessage(error instanceof Error ? error.message : String(error)),
211
+ success: false,
212
+ };
213
+ }
214
+ }
@@ -0,0 +1,160 @@
1
+ import {
2
+ deleteUserLocalMemoryItem,
3
+ disableUserLocalMemoryItem,
4
+ inspectUserLocalMemoryItem,
5
+ listUserLocalMemoryItems,
6
+ setUserLocalMemoryItem,
7
+ } from '@robota-sdk/agent-framework';
8
+
9
+ import { USER_LOCAL_COMMAND_USAGE } from './user-local-command-constants.js';
10
+
11
+ import type { TUserLocalMemoryCategory } from '@robota-sdk/agent-framework';
12
+ import type { ICommandResult } from '@robota-sdk/agent-interface-command';
13
+
14
+ export interface IUserLocalMemoryCommandArgs {
15
+ readonly action?: string;
16
+ readonly positional: readonly string[];
17
+ readonly format: 'text' | 'json';
18
+ readonly summary?: string;
19
+ readonly source?: string;
20
+ }
21
+
22
+ function formatMemoryListText(
23
+ items: readonly { category: string; key: string; enabled: boolean }[],
24
+ ): string {
25
+ if (items.length === 0) {
26
+ return 'No user-local memory items.';
27
+ }
28
+ return items
29
+ .map((item) => `- ${item.category}/${item.key} (${item.enabled ? 'enabled' : 'disabled'})`)
30
+ .join('\n');
31
+ }
32
+
33
+ function parseMemoryCategory(value: string | undefined): TUserLocalMemoryCategory {
34
+ if (value === undefined) {
35
+ throw new Error('User-local memory category is required.');
36
+ }
37
+ return value as TUserLocalMemoryCategory;
38
+ }
39
+
40
+ async function executeMemoryListCommand(
41
+ activeRepositoryRoot: string,
42
+ storageRoot: string,
43
+ parsed: IUserLocalMemoryCommandArgs,
44
+ ): Promise<ICommandResult> {
45
+ const list = await listUserLocalMemoryItems({ activeRepositoryRoot, storageRoot });
46
+ return {
47
+ message:
48
+ parsed.format === 'json' ? JSON.stringify(list, null, 2) : formatMemoryListText(list.items),
49
+ success: true,
50
+ data: { list },
51
+ };
52
+ }
53
+
54
+ async function executeMemorySetCommand(
55
+ activeRepositoryRoot: string,
56
+ storageRoot: string,
57
+ parsed: IUserLocalMemoryCommandArgs,
58
+ ): Promise<ICommandResult> {
59
+ const [category, key, value] = parsed.positional;
60
+ const item = await setUserLocalMemoryItem({
61
+ activeRepositoryRoot,
62
+ storageRoot,
63
+ category: parseMemoryCategory(category),
64
+ key: key ?? '',
65
+ value: value ?? '',
66
+ summary: parsed.summary ?? '',
67
+ source: parsed.source ?? '',
68
+ });
69
+ return {
70
+ message: `Stored user-local memory item ${item.category}/${item.key} at ${item.storageLocation}`,
71
+ success: true,
72
+ data: { item },
73
+ };
74
+ }
75
+
76
+ async function executeMemoryInspectCommand(
77
+ activeRepositoryRoot: string,
78
+ storageRoot: string,
79
+ parsed: IUserLocalMemoryCommandArgs,
80
+ ): Promise<ICommandResult> {
81
+ const [category, key] = parsed.positional;
82
+ const item = await inspectUserLocalMemoryItem({
83
+ activeRepositoryRoot,
84
+ storageRoot,
85
+ category: parseMemoryCategory(category),
86
+ key: key ?? '',
87
+ });
88
+ return {
89
+ message:
90
+ parsed.format === 'json'
91
+ ? JSON.stringify(item, null, 2)
92
+ : `${item.category}/${item.key}: ${item.summary}`,
93
+ success: true,
94
+ data: { item },
95
+ };
96
+ }
97
+
98
+ async function executeMemoryDisableCommand(
99
+ activeRepositoryRoot: string,
100
+ storageRoot: string,
101
+ parsed: IUserLocalMemoryCommandArgs,
102
+ ): Promise<ICommandResult> {
103
+ const [category, key] = parsed.positional;
104
+ const item = await disableUserLocalMemoryItem({
105
+ activeRepositoryRoot,
106
+ storageRoot,
107
+ category: parseMemoryCategory(category),
108
+ key: key ?? '',
109
+ });
110
+ return {
111
+ message: `Disabled user-local memory item ${item.category}/${item.key}`,
112
+ success: true,
113
+ data: { item },
114
+ };
115
+ }
116
+
117
+ async function executeMemoryDeleteCommand(
118
+ activeRepositoryRoot: string,
119
+ storageRoot: string,
120
+ parsed: IUserLocalMemoryCommandArgs,
121
+ ): Promise<ICommandResult> {
122
+ const [category, key] = parsed.positional;
123
+ const result = await deleteUserLocalMemoryItem({
124
+ activeRepositoryRoot,
125
+ storageRoot,
126
+ category: parseMemoryCategory(category),
127
+ key: key ?? '',
128
+ });
129
+ return {
130
+ message: `Deleted user-local memory item ${result.category}/${result.key}`,
131
+ success: true,
132
+ data: { result },
133
+ };
134
+ }
135
+
136
+ export async function executeMemoryCommand(
137
+ cwd: string,
138
+ storageRoot: string,
139
+ parsed: IUserLocalMemoryCommandArgs,
140
+ ): Promise<ICommandResult> {
141
+ if ((parsed.action ?? 'list') === 'list') {
142
+ return executeMemoryListCommand(cwd, storageRoot, parsed);
143
+ }
144
+ if (parsed.action === 'set') {
145
+ return executeMemorySetCommand(cwd, storageRoot, parsed);
146
+ }
147
+ if (parsed.action === 'inspect') {
148
+ return executeMemoryInspectCommand(cwd, storageRoot, parsed);
149
+ }
150
+ if (parsed.action === 'disable') {
151
+ return executeMemoryDisableCommand(cwd, storageRoot, parsed);
152
+ }
153
+ if (parsed.action === 'delete') {
154
+ return executeMemoryDeleteCommand(cwd, storageRoot, parsed);
155
+ }
156
+ return {
157
+ message: USER_LOCAL_COMMAND_USAGE,
158
+ success: false,
159
+ };
160
+ }