@robota-sdk/agent-command 3.0.0-beta.79 → 3.0.0-beta.82

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 (201) hide show
  1. package/README.md +11 -2
  2. package/dist/node/index.cjs +77 -38
  3. package/dist/node/index.d.cts +946 -0
  4. package/dist/node/index.d.cts.map +1 -0
  5. package/dist/node/index.d.ts +564 -51
  6. package/dist/node/index.d.ts.map +1 -1
  7. package/dist/node/index.js +77 -38
  8. package/dist/node/index.js.map +1 -1
  9. package/package.json +39 -16
  10. package/src/advisor/advisor-command-module.ts +47 -0
  11. package/src/advisor/advisor-command.test.ts +102 -0
  12. package/src/advisor/advisor-command.ts +55 -0
  13. package/src/advisor/advisor-cost-functional.test.ts +92 -0
  14. package/src/advisor/index.ts +6 -0
  15. package/src/agent/__tests__/agent-command.test.ts +39 -8
  16. package/src/agent/agent-command-module.ts +14 -7
  17. package/src/agent/agent-command-parser.ts +1 -1
  18. package/src/agent/agent-command.ts +3 -3
  19. package/src/background/__tests__/background-command-module.test.ts +59 -52
  20. package/src/background/background-command-module.ts +2 -1
  21. package/src/background/background-command.ts +3 -3
  22. package/src/command-module-utils.ts +33 -0
  23. package/src/compact/__tests__/compact-command-module.test.ts +31 -23
  24. package/src/compact/compact-command-module.ts +10 -1
  25. package/src/compact/compact-command.ts +6 -3
  26. package/src/context/__tests__/context-command-module.test.ts +214 -63
  27. package/src/context/auto-compact-format.ts +25 -0
  28. package/src/context/context-breakdown.ts +295 -0
  29. package/src/context/context-command-module.ts +45 -14
  30. package/src/context/context-command.ts +34 -257
  31. package/src/default/__tests__/__snapshots__/model-exposure.test.ts.snap +110 -0
  32. package/src/default/__tests__/default-command-modules.test.ts +59 -7
  33. package/src/default/__tests__/model-exposure.test.ts +241 -0
  34. package/src/default/__tests__/org-policy-forwarding.test.ts +98 -0
  35. package/src/default/default-command-modules.ts +130 -18
  36. package/src/default/index.ts +4 -1
  37. package/src/devices/__tests__/devices-command-module.test.ts +212 -0
  38. package/src/devices/devices-command-module.ts +224 -0
  39. package/src/devices/devices-command-port.ts +82 -0
  40. package/src/devices/index.ts +11 -0
  41. package/src/doctor/__tests__/doctor-command-module.test.ts +145 -0
  42. package/src/doctor/__tests__/doctor-display-vocabulary.test.ts +38 -0
  43. package/src/doctor/__tests__/doctor-fixture.ts +145 -0
  44. package/src/doctor/__tests__/doctor-redaction.test.ts +29 -0
  45. package/src/doctor/__tests__/doctor-runner.test.ts +464 -0
  46. package/src/doctor/doctor-command-module.ts +132 -0
  47. package/src/doctor/doctor-extensions-probe.ts +299 -0
  48. package/src/doctor/doctor-node-deps.ts +89 -0
  49. package/src/doctor/doctor-redaction.ts +99 -0
  50. package/src/doctor/doctor-render.ts +70 -0
  51. package/src/doctor/doctor-repair.ts +136 -0
  52. package/src/doctor/doctor-runner.ts +122 -0
  53. package/src/doctor/doctor-settings-probe.ts +239 -0
  54. package/src/doctor/doctor-storage-probe.ts +187 -0
  55. package/src/doctor/doctor-types.ts +109 -0
  56. package/src/doctor/index.ts +32 -0
  57. package/src/editor/__tests__/editor-command-functional.test.ts +49 -16
  58. package/src/editor/editor-command-module.ts +6 -5
  59. package/src/editor/editor-command.ts +10 -5
  60. package/src/effort/effort-command-module.ts +51 -0
  61. package/src/effort/effort-command.test.ts +140 -0
  62. package/src/effort/effort-command.ts +122 -0
  63. package/src/effort/index.ts +6 -0
  64. package/src/exit/__tests__/exit-command-module.test.ts +16 -9
  65. package/src/exit/exit-command-module.ts +2 -1
  66. package/src/exit/exit-command.ts +6 -6
  67. package/src/fork/__tests__/fork-command.test.ts +184 -0
  68. package/src/fork/fork-command-module.ts +61 -0
  69. package/src/fork/fork-command.ts +162 -0
  70. package/src/fork/index.ts +8 -0
  71. package/src/git/__tests__/fake-git-port.ts +28 -0
  72. package/src/git/__tests__/git-command-module.test.ts +103 -0
  73. package/src/git/__tests__/git-commit.test.ts +185 -0
  74. package/src/git/__tests__/git-diff.test.ts +125 -0
  75. package/src/git/__tests__/git-process.test.ts +221 -0
  76. package/src/git/__tests__/git-status.test.ts +117 -0
  77. package/src/git/git-command-module.ts +139 -0
  78. package/src/git/git-commit.ts +251 -0
  79. package/src/git/git-diff.ts +129 -0
  80. package/src/git/git-process.ts +169 -0
  81. package/src/git/git-status.ts +134 -0
  82. package/src/git/index.ts +17 -0
  83. package/src/goal/__tests__/goal-command.test.ts +9 -4
  84. package/src/goal/goal-command-module.ts +2 -1
  85. package/src/goal/goal-command.ts +6 -9
  86. package/src/handoff/__tests__/handoff-command-module.test.ts +24 -0
  87. package/src/handoff/__tests__/handoff-command.test.ts +218 -0
  88. package/src/handoff/handoff-command-module.ts +49 -0
  89. package/src/handoff/handoff-command.ts +187 -0
  90. package/src/handoff/index.ts +6 -0
  91. package/src/help/__tests__/help-command-module.test.ts +63 -40
  92. package/src/help/__tests__/help-command.test.ts +46 -37
  93. package/src/help/help-command-module.ts +2 -1
  94. package/src/help/help-command.ts +3 -3
  95. package/src/index.ts +124 -2
  96. package/src/keybindings/__tests__/keybindings-command-module.test.ts +57 -0
  97. package/src/keybindings/index.ts +6 -0
  98. package/src/keybindings/keybindings-command-module.ts +74 -0
  99. package/src/language/__tests__/language-command-module.test.ts +33 -28
  100. package/src/language/language-command-module.ts +2 -1
  101. package/src/language/language-command.ts +8 -6
  102. package/src/mcp-activation/__tests__/mcp-activation-command.test.ts +630 -0
  103. package/src/mcp-activation/__tests__/mcp-model-view.test.ts +211 -0
  104. package/src/mcp-activation/index.ts +12 -0
  105. package/src/mcp-activation/mcp-activation-command-module.ts +92 -0
  106. package/src/mcp-activation/mcp-activation-command.ts +448 -0
  107. package/src/mcp-activation/mcp-model-notice.ts +85 -0
  108. package/src/mcp-activation/mcp-model-status.ts +99 -0
  109. package/src/memory/__tests__/memory-command-module.test.ts +167 -74
  110. package/src/memory/memory-command-module.ts +18 -1
  111. package/src/memory/memory-command.ts +38 -38
  112. package/src/mode/__tests__/mode-command-module.test.ts +51 -38
  113. package/src/mode/mode-command-module.ts +2 -1
  114. package/src/mode/mode-command.ts +15 -7
  115. package/src/output-style/__tests__/output-style-command.test.ts +96 -0
  116. package/src/output-style/index.ts +6 -0
  117. package/src/output-style/output-style-command-module.ts +143 -0
  118. package/src/peers/__tests__/peers-command.test.ts +321 -0
  119. package/src/peers/index.ts +9 -0
  120. package/src/peers/peers-command-module.ts +49 -0
  121. package/src/peers/peers-command.ts +191 -0
  122. package/src/permissions/__tests__/permissions-command-module.test.ts +149 -37
  123. package/src/permissions/permissions-command-module.ts +2 -1
  124. package/src/permissions/permissions-command.ts +46 -4
  125. package/src/plan/__tests__/plan-command.test.ts +129 -0
  126. package/src/plan/index.ts +9 -0
  127. package/src/plan/plan-command-module.ts +49 -0
  128. package/src/plan/plan-command.ts +92 -0
  129. package/src/plugin/__tests__/plugin-command-module.test.ts +46 -40
  130. package/src/plugin/__tests__/plugin-host-boundary.test.ts +11 -0
  131. package/src/plugin/plugin-command-module.ts +3 -1
  132. package/src/plugin/plugin-command.ts +17 -16
  133. package/src/preset/__tests__/host-supplied-preset-registry.test.ts +98 -0
  134. package/src/preset/__tests__/preset-command-module.test.ts +102 -56
  135. package/src/preset/preset-command-module.ts +26 -8
  136. package/src/preset/preset-command.ts +85 -27
  137. package/src/provider/__tests__/org-policy.test.ts +4 -5
  138. package/src/provider/__tests__/provider-command-module.test.ts +11 -14
  139. package/src/provider/__tests__/provider-startup-host-settings.test.ts +16 -0
  140. package/src/provider/__tests__/scripted-interaction.ts +7 -5
  141. package/src/provider/provider-command-execution.ts +4 -4
  142. package/src/provider/provider-command-module.ts +2 -1
  143. package/src/provider/provider-command-profile-lifecycle.ts +4 -4
  144. package/src/provider/provider-command-profile-operations.ts +3 -3
  145. package/src/provider/provider-command-profile.ts +1 -1
  146. package/src/provider/provider-command-setup.ts +4 -4
  147. package/src/provider/provider-startup.ts +62 -35
  148. package/src/remote-control/__tests__/remote-control-command-module.test.ts +36 -0
  149. package/src/remote-control/__tests__/remote-control-command.test.ts +216 -0
  150. package/src/remote-control/index.ts +8 -0
  151. package/src/remote-control/remote-control-command-module.ts +61 -0
  152. package/src/remote-control/remote-control-command.ts +138 -0
  153. package/src/reset/__tests__/reset-command-module.test.ts +5 -5
  154. package/src/reset/reset-command-module.ts +2 -1
  155. package/src/reset/reset-command.ts +3 -4
  156. package/src/rewind/__tests__/rewind-command-module.test.ts +40 -0
  157. package/src/rewind/rewind-command-module.ts +2 -1
  158. package/src/rewind/rewind-command.ts +73 -6
  159. package/src/sandbox/__tests__/sandbox-command.test.ts +80 -0
  160. package/src/sandbox/index.ts +2 -0
  161. package/src/sandbox/sandbox-command-module.ts +56 -0
  162. package/src/sandbox/sandbox-command.ts +94 -0
  163. package/src/schedule/__tests__/loop-command-functional.test.ts +386 -0
  164. package/src/schedule/__tests__/loop-command.test.ts +360 -0
  165. package/src/schedule/__tests__/loop-jitter.test.ts +25 -0
  166. package/src/schedule/__tests__/monitor-model-permission-functional.test.ts +126 -0
  167. package/src/schedule/__tests__/schedule-command.test.ts +143 -3
  168. package/src/schedule/__tests__/schedule-redos.test.ts +81 -0
  169. package/src/schedule/index.ts +3 -0
  170. package/src/schedule/loop-command.ts +333 -0
  171. package/src/schedule/loop-jitter.ts +41 -0
  172. package/src/schedule/schedule-command-module.ts +92 -14
  173. package/src/schedule/schedule-command.ts +98 -9
  174. package/src/schedule/schedule-spec-parser.ts +5 -1
  175. package/src/session/__tests__/rename-host-persistence.test.ts +72 -0
  176. package/src/session/__tests__/session-command-module.test.ts +210 -45
  177. package/src/session/session-command-module.ts +68 -37
  178. package/src/session/session-command.ts +147 -80
  179. package/src/settings/settings-command-module.ts +3 -2
  180. package/src/shell/__tests__/resolve-shell-host.test.ts +11 -0
  181. package/src/shell/__tests__/shell-command-functional.test.ts +23 -1
  182. package/src/shell/resolve-shell.ts +2 -2
  183. package/src/shell/shell-command-module.ts +6 -5
  184. package/src/shell/shell-command.ts +9 -5
  185. package/src/skills/__tests__/skills-command-module.test.ts +69 -28
  186. package/src/skills/index.ts +1 -0
  187. package/src/skills/skills-command-module.ts +22 -5
  188. package/src/skills/skills-command.ts +14 -13
  189. package/src/statusline/__tests__/statusline-command-module.test.ts +5 -4
  190. package/src/statusline/statusline-command-module.ts +2 -1
  191. package/src/statusline/statusline-command.ts +4 -4
  192. package/src/theme/__tests__/theme-command.test.ts +204 -0
  193. package/src/theme/index.ts +12 -0
  194. package/src/theme/theme-command-module.ts +211 -0
  195. package/src/user-local/__tests__/user-local-command.test.ts +145 -110
  196. package/src/user-local/user-local-command-constants.ts +1 -1
  197. package/src/user-local/user-local-command-module.ts +6 -5
  198. package/src/user-local/user-local-command.ts +12 -6
  199. package/src/user-local/user-local-memory-command.ts +17 -7
  200. package/src/plugins/default-plugin-command-adapter.ts +0 -164
  201. package/src/plugins/default-plugin-command-source-loader.ts +0 -31
@@ -0,0 +1,57 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+
3
+ import { scriptedSession } from '@robota-sdk/agent-framework/testing';
4
+
5
+ import { createKeybindingsCommandModule } from '../keybindings-command-module.js';
6
+
7
+ import type { ITerminalHandoff } from '@robota-sdk/agent-interface-session';
8
+
9
+ function handoff(enabled: boolean): ITerminalHandoff {
10
+ return {
11
+ canHandoffTerminal: enabled,
12
+ runWithTerminal: async (operation) => operation(),
13
+ };
14
+ }
15
+
16
+ describe('/keybindings command', () => {
17
+ it('ensures and opens the exact capability-owned path', async () => {
18
+ const ensureFile = vi.fn().mockResolvedValue('/tmp/keybindings.json');
19
+ const previous = process.env.EDITOR;
20
+ process.env.EDITOR = 'true';
21
+ const session = scriptedSession({
22
+ turns: [{ text: 'unused' }],
23
+ terminalHandoff: handoff(true),
24
+ commandModules: [createKeybindingsCommandModule({ ensureFile })],
25
+ });
26
+ try {
27
+ const result = await session.command('keybindings', '');
28
+ expect(result).toMatchObject({
29
+ success: true,
30
+ message: 'Opened keybindings: /tmp/keybindings.json',
31
+ data: { path: '/tmp/keybindings.json' },
32
+ });
33
+ expect(ensureFile).toHaveBeenCalledTimes(1);
34
+ } finally {
35
+ await session.dispose();
36
+ if (previous === undefined) delete process.env.EDITOR;
37
+ else process.env.EDITOR = previous;
38
+ }
39
+ });
40
+
41
+ it('reports an unavailable terminal without creating a file', async () => {
42
+ const ensureFile = vi.fn().mockResolvedValue('/tmp/keybindings.json');
43
+ const session = scriptedSession({
44
+ turns: [{ text: 'unused' }],
45
+ terminalHandoff: handoff(false),
46
+ commandModules: [createKeybindingsCommandModule({ ensureFile })],
47
+ });
48
+ try {
49
+ const result = await session.command('keybindings', '');
50
+ expect(result?.success).toBe(false);
51
+ expect(result?.message).toMatch(/unavailable/i);
52
+ expect(ensureFile).not.toHaveBeenCalled();
53
+ } finally {
54
+ await session.dispose();
55
+ }
56
+ });
57
+ });
@@ -0,0 +1,6 @@
1
+ export {
2
+ createKeybindingsCommandEntry,
3
+ createKeybindingsCommandModule,
4
+ KeybindingsCommandSource,
5
+ type IKeybindingsFilePort,
6
+ } from './keybindings-command-module.js';
@@ -0,0 +1,74 @@
1
+ import { resolveEditor } from '../editor/resolve-editor.js';
2
+ import { spawnInherited } from '../shell/spawn-inherited.js';
3
+
4
+ import type {
5
+ ICommandHostTerminalHandoff,
6
+ ICommandHostWorkspace,
7
+ ICommandModule,
8
+ ISystemCommand,
9
+ } from '@robota-sdk/agent-framework';
10
+ import type { ICommand, ICommandResult, ICommandSource } from '@robota-sdk/agent-interface-command';
11
+
12
+ export interface IKeybindingsFilePort {
13
+ ensureFile(): Promise<string>;
14
+ }
15
+
16
+ export function createKeybindingsCommandEntry(): ICommand {
17
+ return {
18
+ name: 'keybindings',
19
+ displayName: 'Keybindings',
20
+ description: 'Open the contextual terminal keybindings file in $EDITOR',
21
+ source: 'keybindings',
22
+ // User-only: UI preference.
23
+ modelInvocable: false,
24
+ };
25
+ }
26
+
27
+ async function executeKeybindingsCommand(
28
+ file: IKeybindingsFilePort,
29
+ context: ICommandHostTerminalHandoff & ICommandHostWorkspace,
30
+ ): Promise<ICommandResult> {
31
+ if (!context.canHandoffTerminal()) {
32
+ return { success: false, message: 'Keybindings editor is unavailable here.' };
33
+ }
34
+ const path = await file.ensureFile();
35
+ const editor = resolveEditor();
36
+ const exitCode = await context.runWithTerminal(() =>
37
+ spawnInherited(editor.command, [...editor.args, path], context.getCwd()),
38
+ );
39
+ if (exitCode !== 0) {
40
+ return {
41
+ success: false,
42
+ message: `Keybindings editor exited with code ${exitCode}.`,
43
+ data: { path, exitCode },
44
+ };
45
+ }
46
+ return { success: true, message: `Opened keybindings: ${path}`, data: { path } };
47
+ }
48
+
49
+ export class KeybindingsCommandSource implements ICommandSource {
50
+ readonly name = 'keybindings';
51
+
52
+ getCommands(): ICommand[] {
53
+ return [createKeybindingsCommandEntry()];
54
+ }
55
+ }
56
+
57
+ export function createKeybindingsCommandModule(file: IKeybindingsFilePort): ICommandModule {
58
+ const entry = createKeybindingsCommandEntry();
59
+ const command: ISystemCommand = {
60
+ name: entry.name,
61
+ displayName: entry.displayName,
62
+ description: entry.description,
63
+ requiresPermission: false,
64
+ userInvocable: true,
65
+ modelInvocable: false,
66
+ lifecycle: 'inline',
67
+ execute: (context) => executeKeybindingsCommand(file, context),
68
+ };
69
+ return {
70
+ name: 'agent-command-keybindings',
71
+ commandSources: [new KeybindingsCommandSource()],
72
+ systemCommands: [command],
73
+ };
74
+ }
@@ -5,6 +5,7 @@ import type {
5
5
  } from '@robota-sdk/agent-framework';
6
6
  import { SystemCommandExecutor } from '@robota-sdk/agent-framework';
7
7
  import { createLanguageCommandModule } from '../language-command-module.js';
8
+ import { createTestCommandHost } from '@robota-sdk/agent-framework/testing';
8
9
 
9
10
  function createCheckpointResult(): IEditCheckpointRestoreResult {
10
11
  return {
@@ -22,29 +23,31 @@ function createCheckpointResult(): IEditCheckpointRestoreResult {
22
23
  };
23
24
  }
24
25
 
25
- const commandHostContext: ICommandHostContext = {
26
- getSession: () => {
27
- throw new Error('language command should not read session runtime');
26
+ const commandHostContext = createTestCommandHost({
27
+ overrides: {
28
+ getSession: () => {
29
+ throw new Error('language command should not read session runtime');
30
+ },
31
+ getContextState: () => ({
32
+ usedTokens: 0,
33
+ maxTokens: 1,
34
+ usedPercentage: 0,
35
+ remainingPercentage: 100,
36
+ }),
37
+ getAutoCompactThreshold: () => 0.835,
38
+ compactContext: async () => undefined,
39
+ getCwd: () => '/workspace',
40
+ listEditCheckpoints: () => [],
41
+ restoreEditCheckpoint: async () => createCheckpointResult(),
42
+ rollbackEditCheckpoint: async () => createCheckpointResult(),
43
+ getUsedMemoryReferences: () => [],
44
+ recordMemoryEvent: () => undefined,
45
+ listBackgroundTasks: () => [],
46
+ readBackgroundTaskLog: async () => ({ taskId: 'task_1', lines: [] }),
47
+ cancelBackgroundTask: async () => undefined,
48
+ closeBackgroundTask: async () => undefined,
28
49
  },
29
- getContextState: () => ({
30
- usedTokens: 0,
31
- maxTokens: 1,
32
- usedPercentage: 0,
33
- remainingPercentage: 100,
34
- }),
35
- getAutoCompactThreshold: () => 0.835,
36
- compactContext: async () => undefined,
37
- getCwd: () => '/workspace',
38
- listEditCheckpoints: () => [],
39
- restoreEditCheckpoint: async () => createCheckpointResult(),
40
- rollbackEditCheckpoint: async () => createCheckpointResult(),
41
- getUsedMemoryReferences: () => [],
42
- recordMemoryEvent: () => undefined,
43
- listBackgroundTasks: () => [],
44
- readBackgroundTaskLog: async () => ({ taskId: 'task_1', lines: [] }),
45
- cancelBackgroundTask: async () => undefined,
46
- closeBackgroundTask: async () => undefined,
47
- };
50
+ });
48
51
 
49
52
  describe('createLanguageCommandModule', () => {
50
53
  it('provides language metadata and executable command from one module owner', () => {
@@ -89,7 +92,7 @@ describe('createLanguageCommandModule', () => {
89
92
 
90
93
  expect(result?.success).toBe(true);
91
94
  expect(result?.data?.language).toBe('ko');
92
- expect(result?.effects).toEqual([{ type: 'language-change-requested', language: 'ko' }]);
95
+ expect(result?.hostActions).toEqual([{ type: 'language-change', language: 'ko' }]);
93
96
  });
94
97
 
95
98
  it('shows usage when no language code is provided', async () => {
@@ -107,15 +110,17 @@ describe('createLanguageCommandModule', () => {
107
110
  const executor = new SystemCommandExecutor([
108
111
  ...(createLanguageCommandModule().systemCommands ?? []),
109
112
  ]);
110
- const contextWithAsk: ICommandHostContext = {
111
- ...commandHostContext,
112
- getUserInteraction: () => ({ ask: async () => ({ type: 'answer', values: ['ko'] }) }),
113
- };
113
+ const contextWithAsk = createTestCommandHost({
114
+ overrides: {
115
+ ...commandHostContext,
116
+ getUserInteraction: () => ({ ask: async () => ({ type: 'answer', values: ['ko'] }) }),
117
+ },
118
+ });
114
119
 
115
120
  const result = await executor.execute('language', contextWithAsk, '');
116
121
 
117
122
  expect(result?.success).toBe(true);
118
123
  expect(result?.data?.language).toBe('ko');
119
- expect(result?.effects).toEqual([{ type: 'language-change-requested', language: 'ko' }]);
124
+ expect(result?.hostActions).toEqual([{ type: 'language-change', language: 'ko' }]);
120
125
  });
121
126
  });
@@ -7,7 +7,7 @@ import {
7
7
  import { executeLanguageCommand } from './language-command.js';
8
8
 
9
9
  import type { ICommandModule, ISystemCommand } from '@robota-sdk/agent-framework';
10
- import type { ICommand, ICommandSource } from '@robota-sdk/agent-interface-transport';
10
+ import type { ICommand, ICommandSource } from '@robota-sdk/agent-interface-command';
11
11
 
12
12
  export function createLanguageCommandEntry(): ICommand {
13
13
  return {
@@ -17,6 +17,7 @@ export function createLanguageCommandEntry(): ICommand {
17
17
  source: 'language',
18
18
  argumentHint: LANGUAGE_COMMAND_ARGUMENT_HINT,
19
19
  subcommands: buildLanguageCommandSubcommands('language'),
20
+ // User-only: the user's response-language preference.
20
21
  modelInvocable: false,
21
22
  };
22
23
  }
@@ -5,15 +5,17 @@ import {
5
5
  parseLanguageArgument,
6
6
  } from '@robota-sdk/agent-framework';
7
7
 
8
- import type { ICommandHostContext } from '@robota-sdk/agent-framework';
9
- import type { ICommandResult } from '@robota-sdk/agent-interface-transport';
8
+ import type { ICommandHostUserInteraction } from '@robota-sdk/agent-framework';
9
+ import type { ICommandResult } from '@robota-sdk/agent-interface-command';
10
10
 
11
11
  /**
12
12
  * Ask the user to pick a language (CMD-004 inline ask). Returns a validated language, or `undefined`
13
13
  * when no interactive renderer is attached or the user cancelled — the caller then shows usage.
14
14
  */
15
- async function resolveLanguageViaAsk(context: ICommandHostContext): Promise<string | undefined> {
16
- const ui = context.getUserInteraction?.();
15
+ async function resolveLanguageViaAsk(
16
+ context: ICommandHostUserInteraction,
17
+ ): Promise<string | undefined> {
18
+ const ui = context.getUserInteraction();
17
19
  if (!ui) return undefined;
18
20
  const options = buildLanguageCommandSubcommands().map((sub) => ({
19
21
  value: sub.name,
@@ -26,7 +28,7 @@ async function resolveLanguageViaAsk(context: ICommandHostContext): Promise<stri
26
28
  }
27
29
 
28
30
  export async function executeLanguageCommand(
29
- context: ICommandHostContext,
31
+ context: ICommandHostUserInteraction,
30
32
  args: string,
31
33
  ): Promise<ICommandResult> {
32
34
  let language = parseLanguageArgument(args);
@@ -45,6 +47,6 @@ export async function executeLanguageCommand(
45
47
  message: `Language set to "${language}".`,
46
48
  success: true,
47
49
  data: { language },
48
- effects: [{ type: 'language-change-requested', language }],
50
+ hostActions: [{ type: 'language-change', language }],
49
51
  };
50
52
  }