@agents-at-scale/ark 0.1.35 → 0.1.36-rc1

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 (223) hide show
  1. package/dist/arkServices.d.ts +42 -0
  2. package/dist/arkServices.js +138 -0
  3. package/dist/arkServices.spec.d.ts +1 -0
  4. package/dist/arkServices.spec.js +24 -0
  5. package/dist/charts/charts.d.ts +5 -0
  6. package/dist/charts/charts.js +6 -0
  7. package/dist/charts/dependencies.d.ts +6 -0
  8. package/dist/charts/dependencies.js +50 -0
  9. package/dist/charts/types.d.ts +40 -0
  10. package/dist/charts/types.js +1 -0
  11. package/dist/commands/agents/index.d.ts +3 -0
  12. package/dist/commands/agents/index.js +65 -0
  13. package/dist/commands/agents/index.spec.d.ts +1 -0
  14. package/dist/commands/agents/index.spec.js +67 -0
  15. package/dist/commands/agents/selector.d.ts +8 -0
  16. package/dist/commands/agents/selector.js +53 -0
  17. package/dist/commands/agents.d.ts +2 -0
  18. package/dist/commands/agents.js +53 -0
  19. package/dist/commands/chat/index.d.ts +3 -0
  20. package/dist/commands/chat/index.js +29 -0
  21. package/dist/commands/chat.d.ts +2 -0
  22. package/dist/commands/chat.js +45 -0
  23. package/dist/commands/cluster/get.d.ts +2 -0
  24. package/dist/commands/cluster/get.js +39 -0
  25. package/dist/commands/cluster/get.spec.d.ts +1 -0
  26. package/dist/commands/cluster/get.spec.js +92 -0
  27. package/dist/commands/cluster/index.d.ts +2 -1
  28. package/dist/commands/cluster/index.js +3 -5
  29. package/dist/commands/cluster/index.spec.d.ts +1 -0
  30. package/dist/commands/cluster/index.spec.js +24 -0
  31. package/dist/commands/completion/index.d.ts +3 -0
  32. package/dist/commands/completion/index.js +230 -0
  33. package/dist/commands/completion/index.spec.d.ts +1 -0
  34. package/dist/commands/completion/index.spec.js +34 -0
  35. package/dist/commands/completion.js +159 -2
  36. package/dist/commands/config/index.d.ts +3 -0
  37. package/dist/commands/config/index.js +42 -0
  38. package/dist/commands/config/index.spec.d.ts +1 -0
  39. package/dist/commands/config/index.spec.js +78 -0
  40. package/dist/commands/config.d.ts +0 -3
  41. package/dist/commands/config.js +38 -321
  42. package/dist/commands/dashboard/index.d.ts +4 -0
  43. package/dist/commands/dashboard/index.js +39 -0
  44. package/dist/commands/dashboard.d.ts +3 -0
  45. package/dist/commands/dashboard.js +39 -0
  46. package/dist/commands/dev/index.d.ts +3 -0
  47. package/dist/commands/dev/index.js +9 -0
  48. package/dist/commands/dev/tool/check.d.ts +2 -0
  49. package/dist/commands/dev/tool/check.js +142 -0
  50. package/dist/commands/dev/tool/clean.d.ts +2 -0
  51. package/dist/commands/dev/tool/clean.js +153 -0
  52. package/dist/commands/dev/tool/generate.d.ts +2 -0
  53. package/dist/commands/dev/tool/generate.js +28 -0
  54. package/dist/commands/dev/tool/index.d.ts +2 -0
  55. package/dist/commands/dev/tool/index.js +14 -0
  56. package/dist/commands/dev/tool/init.d.ts +2 -0
  57. package/dist/commands/dev/tool/init.js +320 -0
  58. package/dist/commands/dev/tool/shared.d.ts +5 -0
  59. package/dist/commands/dev/tool/shared.js +258 -0
  60. package/dist/commands/dev/tool/status.d.ts +2 -0
  61. package/dist/commands/dev/tool/status.js +136 -0
  62. package/dist/commands/dev/tool-generate.spec.d.ts +1 -0
  63. package/dist/commands/dev/tool-generate.spec.js +163 -0
  64. package/dist/commands/dev/tool.d.ts +2 -0
  65. package/dist/commands/dev/tool.js +559 -0
  66. package/dist/commands/dev/tool.spec.d.ts +1 -0
  67. package/dist/commands/dev/tool.spec.js +48 -0
  68. package/dist/commands/docs/index.d.ts +4 -0
  69. package/dist/commands/docs/index.js +18 -0
  70. package/dist/commands/generate/config.js +5 -24
  71. package/dist/commands/generate/generators/mcpserver.d.ts +2 -1
  72. package/dist/commands/generate/generators/mcpserver.js +26 -5
  73. package/dist/commands/generate/generators/project.js +22 -41
  74. package/dist/commands/generate/index.d.ts +2 -1
  75. package/dist/commands/generate/index.js +1 -1
  76. package/dist/commands/install/index.d.ts +8 -0
  77. package/dist/commands/install/index.js +295 -0
  78. package/dist/commands/install/index.spec.d.ts +1 -0
  79. package/dist/commands/install/index.spec.js +143 -0
  80. package/dist/commands/install.d.ts +3 -0
  81. package/dist/commands/install.js +147 -0
  82. package/dist/commands/models/create.d.ts +1 -0
  83. package/dist/commands/models/create.js +213 -0
  84. package/dist/commands/models/create.spec.d.ts +1 -0
  85. package/dist/commands/models/create.spec.js +125 -0
  86. package/dist/commands/models/index.d.ts +3 -0
  87. package/dist/commands/models/index.js +75 -0
  88. package/dist/commands/models/index.spec.d.ts +1 -0
  89. package/dist/commands/models/index.spec.js +96 -0
  90. package/dist/commands/models/selector.d.ts +8 -0
  91. package/dist/commands/models/selector.js +53 -0
  92. package/dist/commands/query/index.d.ts +3 -0
  93. package/dist/commands/query/index.js +24 -0
  94. package/dist/commands/query/index.spec.d.ts +1 -0
  95. package/dist/commands/query/index.spec.js +53 -0
  96. package/dist/commands/routes/index.d.ts +3 -0
  97. package/dist/commands/routes/index.js +93 -0
  98. package/dist/commands/routes.d.ts +2 -0
  99. package/dist/commands/routes.js +101 -0
  100. package/dist/commands/status/index.d.ts +3 -0
  101. package/dist/commands/status/index.js +281 -0
  102. package/dist/commands/status.d.ts +3 -0
  103. package/dist/commands/status.js +33 -0
  104. package/dist/commands/targets/index.d.ts +3 -0
  105. package/dist/commands/targets/index.js +72 -0
  106. package/dist/commands/targets/index.spec.d.ts +1 -0
  107. package/dist/commands/targets/index.spec.js +154 -0
  108. package/dist/commands/targets.d.ts +2 -0
  109. package/dist/commands/targets.js +65 -0
  110. package/dist/commands/teams/index.d.ts +3 -0
  111. package/dist/commands/teams/index.js +64 -0
  112. package/dist/commands/teams/index.spec.d.ts +1 -0
  113. package/dist/commands/teams/index.spec.js +70 -0
  114. package/dist/commands/teams/selector.d.ts +8 -0
  115. package/dist/commands/teams/selector.js +55 -0
  116. package/dist/commands/tools/index.d.ts +3 -0
  117. package/dist/commands/tools/index.js +49 -0
  118. package/dist/commands/tools/index.spec.d.ts +1 -0
  119. package/dist/commands/tools/index.spec.js +70 -0
  120. package/dist/commands/tools/selector.d.ts +8 -0
  121. package/dist/commands/tools/selector.js +53 -0
  122. package/dist/commands/uninstall/index.d.ts +3 -0
  123. package/dist/commands/uninstall/index.js +101 -0
  124. package/dist/commands/uninstall/index.spec.d.ts +1 -0
  125. package/dist/commands/uninstall/index.spec.js +125 -0
  126. package/dist/commands/uninstall.d.ts +2 -0
  127. package/dist/commands/uninstall.js +83 -0
  128. package/dist/components/ChatUI.d.ts +16 -0
  129. package/dist/components/ChatUI.js +801 -0
  130. package/dist/components/StatusView.d.ts +10 -0
  131. package/dist/components/StatusView.js +39 -0
  132. package/dist/components/statusChecker.d.ts +14 -24
  133. package/dist/components/statusChecker.js +295 -129
  134. package/dist/config.d.ts +3 -22
  135. package/dist/config.js +10 -161
  136. package/dist/index.d.ts +1 -1
  137. package/dist/index.js +42 -42
  138. package/dist/lib/arkApiClient.d.ts +53 -0
  139. package/dist/lib/arkApiClient.js +102 -0
  140. package/dist/lib/arkApiProxy.d.ts +9 -0
  141. package/dist/lib/arkApiProxy.js +22 -0
  142. package/dist/lib/arkServiceProxy.d.ts +14 -0
  143. package/dist/lib/arkServiceProxy.js +95 -0
  144. package/dist/lib/arkStatus.d.ts +10 -0
  145. package/dist/lib/arkStatus.js +79 -0
  146. package/dist/lib/arkStatus.spec.d.ts +1 -0
  147. package/dist/lib/arkStatus.spec.js +49 -0
  148. package/dist/lib/chatClient.d.ts +33 -0
  149. package/dist/lib/chatClient.js +93 -0
  150. package/dist/lib/cluster.d.ts +2 -1
  151. package/dist/lib/cluster.js +37 -16
  152. package/dist/lib/cluster.spec.d.ts +1 -0
  153. package/dist/lib/cluster.spec.js +338 -0
  154. package/dist/lib/commandUtils.d.ts +4 -0
  155. package/dist/lib/commandUtils.js +18 -0
  156. package/dist/lib/commandUtils.test.d.ts +1 -0
  157. package/dist/lib/commandUtils.test.js +44 -0
  158. package/dist/lib/commands.d.ts +16 -0
  159. package/dist/lib/commands.js +29 -0
  160. package/dist/lib/commands.spec.d.ts +1 -0
  161. package/dist/lib/commands.spec.js +146 -0
  162. package/dist/lib/config.d.ts +26 -80
  163. package/dist/lib/config.js +70 -205
  164. package/dist/lib/config.spec.d.ts +1 -0
  165. package/dist/lib/config.spec.js +99 -0
  166. package/dist/lib/config.test.d.ts +1 -0
  167. package/dist/lib/config.test.js +93 -0
  168. package/dist/lib/consts.d.ts +0 -1
  169. package/dist/lib/consts.js +0 -2
  170. package/dist/lib/consts.spec.d.ts +1 -0
  171. package/dist/lib/consts.spec.js +15 -0
  172. package/dist/lib/dev/tools/analyzer.d.ts +30 -0
  173. package/dist/lib/dev/tools/analyzer.js +190 -0
  174. package/dist/lib/dev/tools/discover_tools.py +392 -0
  175. package/dist/lib/dev/tools/mcp-types.d.ts +28 -0
  176. package/dist/lib/dev/tools/mcp-types.js +86 -0
  177. package/dist/lib/dev/tools/types.d.ts +50 -0
  178. package/dist/lib/dev/tools/types.js +1 -0
  179. package/dist/lib/errors.js +1 -1
  180. package/dist/lib/errors.spec.d.ts +1 -0
  181. package/dist/lib/errors.spec.js +221 -0
  182. package/dist/lib/exec.d.ts +0 -4
  183. package/dist/lib/exec.js +0 -11
  184. package/dist/lib/executeQuery.d.ts +20 -0
  185. package/dist/lib/executeQuery.js +135 -0
  186. package/dist/lib/executeQuery.spec.d.ts +1 -0
  187. package/dist/lib/executeQuery.spec.js +170 -0
  188. package/dist/lib/nextSteps.d.ts +4 -0
  189. package/dist/lib/nextSteps.js +20 -0
  190. package/dist/lib/nextSteps.spec.d.ts +1 -0
  191. package/dist/lib/nextSteps.spec.js +59 -0
  192. package/dist/lib/output.d.ts +36 -0
  193. package/dist/lib/output.js +89 -0
  194. package/dist/lib/output.spec.d.ts +1 -0
  195. package/dist/lib/output.spec.js +123 -0
  196. package/dist/lib/portUtils.d.ts +8 -0
  197. package/dist/lib/portUtils.js +39 -0
  198. package/dist/lib/queryRunner.d.ts +22 -0
  199. package/dist/lib/queryRunner.js +142 -0
  200. package/dist/lib/startup.d.ts +9 -0
  201. package/dist/lib/startup.js +87 -0
  202. package/dist/lib/startup.spec.d.ts +1 -0
  203. package/dist/lib/startup.spec.js +152 -0
  204. package/dist/lib/types.d.ts +87 -3
  205. package/dist/lib/versions.d.ts +23 -0
  206. package/dist/lib/versions.js +51 -0
  207. package/dist/types/types.d.ts +40 -0
  208. package/dist/types/types.js +1 -0
  209. package/dist/ui/AgentSelector.d.ts +8 -0
  210. package/dist/ui/AgentSelector.js +53 -0
  211. package/dist/ui/MainMenu.d.ts +5 -1
  212. package/dist/ui/MainMenu.js +226 -91
  213. package/dist/ui/ModelSelector.d.ts +8 -0
  214. package/dist/ui/ModelSelector.js +53 -0
  215. package/dist/ui/TeamSelector.d.ts +8 -0
  216. package/dist/ui/TeamSelector.js +55 -0
  217. package/dist/ui/ToolSelector.d.ts +8 -0
  218. package/dist/ui/ToolSelector.js +53 -0
  219. package/dist/ui/statusFormatter.d.ts +22 -7
  220. package/dist/ui/statusFormatter.js +39 -39
  221. package/dist/ui/statusFormatter.spec.d.ts +1 -0
  222. package/dist/ui/statusFormatter.spec.js +58 -0
  223. package/package.json +16 -5
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Command } from 'commander';
3
+ import { render } from 'ink';
4
+ import ChatUI from '../components/ChatUI.js';
5
+ import { ArkApiProxy } from '../lib/arkApiProxy.js';
6
+ import { loadConfig } from '../lib/config.js';
7
+ import output from '../lib/output.js';
8
+ export function createChatCommand() {
9
+ const chatCommand = new Command('chat');
10
+ chatCommand
11
+ .description('Start an interactive chat session with ARK agents or models')
12
+ .argument('[target]', 'Target to connect to (e.g., agent/sample-agent, model/default)')
13
+ .option('-a, --agent <name>', 'Connect directly to a specific agent')
14
+ .option('-m, --model <name>', 'Connect directly to a specific model')
15
+ .action(async (targetArg, options) => {
16
+ // Determine initial target from argument or options
17
+ let initialTargetId;
18
+ if (targetArg) {
19
+ // Direct target argument (e.g., "agent/sample-agent")
20
+ initialTargetId = targetArg;
21
+ }
22
+ else if (options.agent) {
23
+ // Agent option
24
+ initialTargetId = `agent/${options.agent}`;
25
+ }
26
+ else if (options.model) {
27
+ // Model option
28
+ initialTargetId = `model/${options.model}`;
29
+ }
30
+ // Load config
31
+ const config = loadConfig();
32
+ // Initialize proxy first - no spinner, just let ChatUI handle loading state
33
+ try {
34
+ const proxy = new ArkApiProxy();
35
+ const arkApiClient = await proxy.start();
36
+ // Pass the initialized client and config to ChatUI
37
+ render(_jsx(ChatUI, { initialTargetId: initialTargetId, arkApiClient: arkApiClient, arkApiProxy: proxy, config: config }));
38
+ }
39
+ catch (error) {
40
+ output.error(error instanceof Error ? error.message : 'ARK API connection failed');
41
+ process.exit(1);
42
+ }
43
+ });
44
+ return chatCommand;
45
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createGetCommand(): Command;
@@ -0,0 +1,39 @@
1
+ import { Command } from 'commander';
2
+ import output from '../../lib/output.js';
3
+ import { getClusterInfo } from '../../lib/cluster.js';
4
+ export function createGetCommand() {
5
+ const get = new Command('get');
6
+ get
7
+ .description('get current kubernetes cluster information')
8
+ .option('-c, --context <context>', 'kubernetes context to use')
9
+ .option('-o, --output <format>', 'output format (text|json)', 'text')
10
+ .action(async (options) => {
11
+ try {
12
+ const clusterInfo = await getClusterInfo(options.context);
13
+ if (clusterInfo.error) {
14
+ output.error('getting cluster info:', clusterInfo.error);
15
+ process.exit(1);
16
+ }
17
+ if (options.output === 'json') {
18
+ console.log(JSON.stringify({
19
+ context: clusterInfo.context,
20
+ namespace: clusterInfo.namespace,
21
+ type: clusterInfo.type,
22
+ ip: clusterInfo.ip,
23
+ }, null, 2));
24
+ }
25
+ else {
26
+ // Text format (default)
27
+ console.log(`context: ${clusterInfo.context}`);
28
+ console.log(`namespace: ${clusterInfo.namespace}`);
29
+ console.log(`type: ${clusterInfo.type}`);
30
+ console.log(`ip: ${clusterInfo.ip || 'unknown'}`);
31
+ }
32
+ }
33
+ catch (error) {
34
+ output.error('failed to get cluster info:', error instanceof Error ? error.message : 'Unknown error');
35
+ process.exit(1);
36
+ }
37
+ });
38
+ return get;
39
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,92 @@
1
+ import { jest } from '@jest/globals';
2
+ import { Command } from 'commander';
3
+ const mockGetClusterInfo = jest.fn();
4
+ jest.unstable_mockModule('../../lib/cluster.js', () => ({
5
+ getClusterInfo: mockGetClusterInfo,
6
+ }));
7
+ const mockOutput = {
8
+ error: jest.fn(),
9
+ };
10
+ jest.unstable_mockModule('../../lib/output.js', () => ({
11
+ default: mockOutput,
12
+ }));
13
+ const mockExit = jest.spyOn(process, 'exit').mockImplementation((() => {
14
+ throw new Error('process.exit called');
15
+ }));
16
+ const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
17
+ const { createGetCommand } = await import('./get.js');
18
+ describe('cluster get command', () => {
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ });
22
+ it('creates command with correct structure', () => {
23
+ const command = createGetCommand();
24
+ expect(command).toBeInstanceOf(Command);
25
+ expect(command.name()).toBe('get');
26
+ });
27
+ it('displays cluster info in text format by default', async () => {
28
+ mockGetClusterInfo.mockResolvedValue({
29
+ context: 'test-cluster',
30
+ namespace: 'default',
31
+ type: 'minikube',
32
+ ip: '192.168.1.1',
33
+ });
34
+ const command = createGetCommand();
35
+ await command.parseAsync(['node', 'test']);
36
+ expect(mockGetClusterInfo).toHaveBeenCalledWith(undefined);
37
+ expect(mockConsoleLog).toHaveBeenCalledWith('context: test-cluster');
38
+ expect(mockConsoleLog).toHaveBeenCalledWith('namespace: default');
39
+ expect(mockConsoleLog).toHaveBeenCalledWith('type: minikube');
40
+ expect(mockConsoleLog).toHaveBeenCalledWith('ip: 192.168.1.1');
41
+ });
42
+ it('displays cluster info in json format when requested', async () => {
43
+ const clusterInfo = {
44
+ context: 'prod-cluster',
45
+ namespace: 'production',
46
+ type: 'eks',
47
+ ip: '10.0.0.1',
48
+ };
49
+ mockGetClusterInfo.mockResolvedValue(clusterInfo);
50
+ const command = createGetCommand();
51
+ await command.parseAsync(['node', 'test', '-o', 'json']);
52
+ expect(mockConsoleLog).toHaveBeenCalledWith(JSON.stringify(clusterInfo, null, 2));
53
+ });
54
+ it('uses specified context when provided', async () => {
55
+ mockGetClusterInfo.mockResolvedValue({
56
+ context: 'custom-context',
57
+ namespace: 'custom',
58
+ type: 'kind',
59
+ ip: '127.0.0.1',
60
+ });
61
+ const command = createGetCommand();
62
+ await command.parseAsync(['node', 'test', '-c', 'custom-context']);
63
+ expect(mockGetClusterInfo).toHaveBeenCalledWith('custom-context');
64
+ });
65
+ it('handles missing ip gracefully', async () => {
66
+ mockGetClusterInfo.mockResolvedValue({
67
+ context: 'test-cluster',
68
+ namespace: 'default',
69
+ type: 'unknown',
70
+ ip: undefined,
71
+ });
72
+ const command = createGetCommand();
73
+ await command.parseAsync(['node', 'test']);
74
+ expect(mockConsoleLog).toHaveBeenCalledWith('ip: unknown');
75
+ });
76
+ it('exits with error when cluster info has error', async () => {
77
+ mockGetClusterInfo.mockResolvedValue({
78
+ error: 'No cluster found',
79
+ });
80
+ const command = createGetCommand();
81
+ await expect(command.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
82
+ expect(mockOutput.error).toHaveBeenCalledWith('getting cluster info:', 'No cluster found');
83
+ expect(mockExit).toHaveBeenCalledWith(1);
84
+ });
85
+ it('handles exceptions gracefully', async () => {
86
+ mockGetClusterInfo.mockRejectedValue(new Error('Connection failed'));
87
+ const command = createGetCommand();
88
+ await expect(command.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
89
+ expect(mockOutput.error).toHaveBeenCalledWith('failed to get cluster info:', 'Connection failed');
90
+ expect(mockExit).toHaveBeenCalledWith(1);
91
+ });
92
+ });
@@ -1,2 +1,3 @@
1
1
  import { Command } from 'commander';
2
- export declare function createClusterCommand(): Command;
2
+ import type { ArkConfig } from '../../lib/config.js';
3
+ export declare function createClusterCommand(_: ArkConfig): Command;
@@ -1,10 +1,8 @@
1
1
  import { Command } from 'commander';
2
- import { createGetIpCommand } from './get-ip.js';
3
- import { createGetTypeCommand } from './get-type.js';
4
- export function createClusterCommand() {
2
+ import { createGetCommand } from './get.js';
3
+ export function createClusterCommand(_) {
5
4
  const cluster = new Command('cluster');
6
5
  cluster.description('Cluster management commands');
7
- cluster.addCommand(createGetTypeCommand());
8
- cluster.addCommand(createGetIpCommand());
6
+ cluster.addCommand(createGetCommand());
9
7
  return cluster;
10
8
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jest } from '@jest/globals';
2
+ import { Command } from 'commander';
3
+ const mockCreateGetCommand = jest.fn();
4
+ jest.unstable_mockModule('./get.js', () => ({
5
+ createGetCommand: mockCreateGetCommand,
6
+ }));
7
+ const { createClusterCommand } = await import('./index.js');
8
+ describe('cluster command', () => {
9
+ beforeEach(() => {
10
+ jest.clearAllMocks();
11
+ mockCreateGetCommand.mockReturnValue(new Command('get'));
12
+ });
13
+ it('creates command with correct structure', () => {
14
+ const command = createClusterCommand({});
15
+ expect(command).toBeInstanceOf(Command);
16
+ expect(command.name()).toBe('cluster');
17
+ });
18
+ it('adds get subcommand', () => {
19
+ const command = createClusterCommand({});
20
+ expect(mockCreateGetCommand).toHaveBeenCalled();
21
+ const getCommand = command.commands.find((cmd) => cmd.name() === 'get');
22
+ expect(getCommand).toBeDefined();
23
+ });
24
+ });
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ import type { ArkConfig } from '../../lib/config.js';
3
+ export declare function createCompletionCommand(_: ArkConfig): Command;
@@ -0,0 +1,230 @@
1
+ import chalk from 'chalk';
2
+ import { Command } from 'commander';
3
+ export function createCompletionCommand(_) {
4
+ const completion = new Command('completion');
5
+ completion.description('Generate shell completion scripts').action(() => {
6
+ console.log(chalk.cyan('Shell completion for ARK CLI'));
7
+ console.log('');
8
+ console.log('Usage:');
9
+ console.log(' ark completion bash Generate bash completion script');
10
+ console.log(' ark completion zsh Generate zsh completion script');
11
+ console.log('');
12
+ console.log('To enable completion, add this to your shell profile:');
13
+ console.log(chalk.grey(' # For bash:'));
14
+ console.log(chalk.grey(' eval "$(ark completion bash)"'));
15
+ console.log(chalk.grey(' # For zsh:'));
16
+ console.log(chalk.grey(' eval "$(ark completion zsh)"'));
17
+ });
18
+ completion
19
+ .command('bash')
20
+ .description('Generate bash completion script')
21
+ .action(() => {
22
+ console.log(`
23
+ _ark_completion() {
24
+ local cur prev opts
25
+ COMPREPLY=()
26
+ cur="\${COMP_WORDS[COMP_CWORD]}"
27
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
28
+
29
+ case \${COMP_CWORD} in
30
+ 1)
31
+ opts="agents chat cluster completion config dashboard docs generate install models query routes status targets teams tools uninstall help"
32
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
33
+ return 0
34
+ ;;
35
+ 2)
36
+ case \${prev} in
37
+ cluster)
38
+ opts="get-ip get-type"
39
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
40
+ return 0
41
+ ;;
42
+ completion)
43
+ opts="bash zsh"
44
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
45
+ return 0
46
+ ;;
47
+ check)
48
+ opts="status"
49
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
50
+ return 0
51
+ ;;
52
+ targets)
53
+ opts="list ls"
54
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
55
+ return 0
56
+ ;;
57
+ agents)
58
+ opts="list ls"
59
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
60
+ return 0
61
+ ;;
62
+ models)
63
+ opts="list ls create"
64
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
65
+ return 0
66
+ ;;
67
+ teams)
68
+ opts="list ls"
69
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
70
+ return 0
71
+ ;;
72
+ tools)
73
+ opts="list ls"
74
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
75
+ return 0
76
+ ;;
77
+ generate)
78
+ opts="agent marketplace mcp-server project query team"
79
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
80
+ return 0
81
+ ;;
82
+ chat)
83
+ # Dynamically fetch available targets using ark targets list
84
+ local targets
85
+ targets=$(ark targets list 2>/dev/null)
86
+ if [ -z "$targets" ]; then
87
+ # Fallback to common targets if API is not available
88
+ targets="agent/sample-agent agent/math agent/weather model/default"
89
+ fi
90
+ COMPREPLY=( $(compgen -W "\${targets}" -- \${cur}) )
91
+ return 0
92
+ ;;
93
+ query)
94
+ # Dynamically fetch available targets for query command
95
+ local targets
96
+ targets=$(ark targets list 2>/dev/null)
97
+ if [ -z "$targets" ]; then
98
+ # Fallback to common targets if API is not available
99
+ targets="model/default agent/sample-agent"
100
+ fi
101
+ COMPREPLY=( $(compgen -W "\${targets}" -- \${cur}) )
102
+ return 0
103
+ ;;
104
+ esac
105
+ ;;
106
+ esac
107
+ }
108
+
109
+ complete -F _ark_completion ark
110
+ `.trim());
111
+ });
112
+ completion
113
+ .command('zsh')
114
+ .description('Generate zsh completion script')
115
+ .action(() => {
116
+ // Shell script requires escaped $ characters
117
+ /* eslint-disable no-useless-escape */
118
+ console.log(`
119
+ #compdef ark
120
+
121
+ _ark() {
122
+ local context state line
123
+
124
+ _arguments -C \\
125
+ '1:command:->command' \\
126
+ '2:subcommand:->subcommand' \\
127
+ '*::arg:->args'
128
+
129
+ case $state in
130
+ command)
131
+ _values 'ark commands' \\
132
+ 'agents[List available agents]' \\
133
+ 'chat[Interactive chat with agents and models]' \\
134
+ 'cluster[Cluster management commands]' \\
135
+ 'completion[Generate shell completion scripts]' \\
136
+ 'config[Configuration management]' \\
137
+ 'dashboard[Open ARK dashboard]' \\
138
+ 'docs[Open ARK documentation]' \\
139
+ 'generate[Generate ARK resources]' \\
140
+ 'install[Install ARK services]' \\
141
+ 'models[List available models]' \\
142
+ 'query[Execute a single query]' \\
143
+ 'routes[List available routes]' \\
144
+ 'status[Check system status]' \\
145
+ 'targets[List available query targets]' \\
146
+ 'teams[List available teams]' \\
147
+ 'tools[List available tools]' \\
148
+ 'uninstall[Uninstall ARK services]' \\
149
+ 'help[Show help information]'
150
+ ;;
151
+ subcommand)
152
+ case $words[2] in
153
+ cluster)
154
+ _values 'cluster commands' \\
155
+ 'get-ip[Get cluster IP address]' \\
156
+ 'get-type[Get cluster type]'
157
+ ;;
158
+ completion)
159
+ _values 'completion shells' \\
160
+ 'bash[Generate bash completion]' \\
161
+ 'zsh[Generate zsh completion]'
162
+ ;;
163
+ check)
164
+ _values 'check commands' \\
165
+ 'status[Check system status]'
166
+ ;;
167
+ targets)
168
+ _values 'targets commands' \\
169
+ 'list[List all available targets]' \\
170
+ 'ls[List all available targets]'
171
+ ;;
172
+ agents)
173
+ _values 'agents commands' \\
174
+ 'list[List all available agents]' \\
175
+ 'ls[List all available agents]'
176
+ ;;
177
+ models)
178
+ _values 'models commands' \\
179
+ 'list[List all available models]' \\
180
+ 'ls[List all available models]' \\
181
+ 'create[Create a new model]'
182
+ ;;
183
+ teams)
184
+ _values 'teams commands' \\
185
+ 'list[List all available teams]' \\
186
+ 'ls[List all available teams]'
187
+ ;;
188
+ tools)
189
+ _values 'tools commands' \\
190
+ 'list[List all available tools]' \\
191
+ 'ls[List all available tools]'
192
+ ;;
193
+ generate)
194
+ _values 'generate types' \\
195
+ 'agent[Generate a new agent]' \\
196
+ 'marketplace[Generate marketplace content]' \\
197
+ 'mcp-server[Generate MCP server]' \\
198
+ 'project[Generate a new project]' \\
199
+ 'query[Generate a query]' \\
200
+ 'team[Generate a team]'
201
+ ;;
202
+ chat)
203
+ # Get available targets dynamically
204
+ local -a targets
205
+ targets=($(ark targets list 2>/dev/null))
206
+ if [ \${#targets[@]} -eq 0 ]; then
207
+ targets=('agent/sample-agent' 'agent/math' 'agent/weather' 'model/default')
208
+ fi
209
+ _values 'available targets' \${targets[@]}
210
+ ;;
211
+ query)
212
+ # Get available targets dynamically for query
213
+ local -a targets
214
+ targets=($(ark targets list 2>/dev/null))
215
+ if [ \${#targets[@]} -eq 0 ]; then
216
+ targets=('model/default' 'agent/sample-agent')
217
+ fi
218
+ _values 'available targets' \${targets[@]}
219
+ ;;
220
+ esac
221
+ ;;
222
+ esac
223
+ }
224
+
225
+ _ark
226
+ `.trim());
227
+ /* eslint-enable no-useless-escape */
228
+ });
229
+ return completion;
230
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ import { jest } from '@jest/globals';
2
+ import { Command } from 'commander';
3
+ const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
4
+ const { createCompletionCommand } = await import('./index.js');
5
+ describe('completion command', () => {
6
+ beforeEach(() => {
7
+ jest.clearAllMocks();
8
+ });
9
+ it('creates command with correct structure', () => {
10
+ const command = createCompletionCommand({});
11
+ expect(command).toBeInstanceOf(Command);
12
+ expect(command.name()).toBe('completion');
13
+ });
14
+ it('shows help when called without subcommand', async () => {
15
+ const command = createCompletionCommand({});
16
+ await command.parseAsync(['node', 'test']);
17
+ // Check first call contains the title (strip ANSI color codes)
18
+ expect(mockConsoleLog.mock.calls[0][0]).toContain('Shell completion for ARK CLI');
19
+ // Check that bash completion instructions are shown
20
+ expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('ark completion bash'));
21
+ });
22
+ it('outputs bash completion script', async () => {
23
+ const command = createCompletionCommand({});
24
+ await command.parseAsync(['node', 'test', 'bash']);
25
+ expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('_ark_completion()'));
26
+ expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('COMPREPLY'));
27
+ });
28
+ it('outputs zsh completion script', async () => {
29
+ const command = createCompletionCommand({});
30
+ await command.parseAsync(['node', 'test', 'zsh']);
31
+ expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('#compdef ark'));
32
+ expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('_ark()'));
33
+ });
34
+ });