@agents-at-scale/ark 0.1.53 → 0.1.55

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 (115) hide show
  1. package/dist/commands/export/index.js +6 -4
  2. package/dist/commands/generate/generators/agent.js +2 -0
  3. package/dist/commands/generate/generators/marketplace.js +2 -0
  4. package/dist/commands/generate/generators/mcpserver.js +2 -0
  5. package/dist/commands/generate/generators/project.js +9 -2
  6. package/dist/commands/generate/generators/query.js +2 -0
  7. package/dist/commands/generate/generators/team.js +2 -0
  8. package/dist/commands/generate/templateDiscovery.js +1 -0
  9. package/dist/commands/generate/templateEngine.js +1 -3
  10. package/dist/commands/import/index.js +1 -1
  11. package/dist/commands/install/index.js +2 -1
  12. package/dist/commands/models/kubernetes/manifest-builder.js +27 -10
  13. package/dist/commands/models/providers/azure.d.ts +10 -7
  14. package/dist/commands/models/providers/azure.js +83 -21
  15. package/dist/commands/uninstall/index.js +1 -1
  16. package/dist/components/ChatUI.js +17 -16
  17. package/dist/components/statusChecker.js +3 -3
  18. package/dist/lib/arkApiClient.js +11 -9
  19. package/dist/lib/arkApiProxy.js +1 -0
  20. package/dist/lib/arkServiceProxy.js +5 -1
  21. package/dist/lib/chatClient.js +9 -0
  22. package/dist/lib/config.js +8 -3
  23. package/dist/lib/errors.js +3 -0
  24. package/dist/ui/asyncOperations/connectingToArk.js +2 -2
  25. package/package.json +16 -12
  26. package/dist/arkServices.spec.d.ts +0 -1
  27. package/dist/arkServices.spec.js +0 -138
  28. package/dist/commands/agents/index.spec.d.ts +0 -1
  29. package/dist/commands/agents/index.spec.js +0 -67
  30. package/dist/commands/cluster/get.spec.d.ts +0 -1
  31. package/dist/commands/cluster/get.spec.js +0 -92
  32. package/dist/commands/cluster/index.spec.d.ts +0 -1
  33. package/dist/commands/cluster/index.spec.js +0 -24
  34. package/dist/commands/completion/index.spec.d.ts +0 -1
  35. package/dist/commands/completion/index.spec.js +0 -34
  36. package/dist/commands/config/index.spec.d.ts +0 -1
  37. package/dist/commands/config/index.spec.js +0 -78
  38. package/dist/commands/evaluation/index.spec.d.ts +0 -1
  39. package/dist/commands/evaluation/index.spec.js +0 -161
  40. package/dist/commands/export/index.spec.d.ts +0 -1
  41. package/dist/commands/export/index.spec.js +0 -145
  42. package/dist/commands/import/index.spec.d.ts +0 -1
  43. package/dist/commands/import/index.spec.js +0 -46
  44. package/dist/commands/install/index.spec.d.ts +0 -1
  45. package/dist/commands/install/index.spec.js +0 -286
  46. package/dist/commands/marketplace/index.spec.d.ts +0 -1
  47. package/dist/commands/marketplace/index.spec.js +0 -88
  48. package/dist/commands/memory/index.spec.d.ts +0 -1
  49. package/dist/commands/memory/index.spec.js +0 -124
  50. package/dist/commands/models/create.spec.d.ts +0 -1
  51. package/dist/commands/models/create.spec.js +0 -167
  52. package/dist/commands/models/index.spec.d.ts +0 -1
  53. package/dist/commands/models/index.spec.js +0 -96
  54. package/dist/commands/models/providers/azure.spec.d.ts +0 -1
  55. package/dist/commands/models/providers/azure.spec.js +0 -232
  56. package/dist/commands/models/providers/bedrock.spec.d.ts +0 -1
  57. package/dist/commands/models/providers/bedrock.spec.js +0 -241
  58. package/dist/commands/models/providers/openai.spec.d.ts +0 -1
  59. package/dist/commands/models/providers/openai.spec.js +0 -180
  60. package/dist/commands/queries/delete.spec.d.ts +0 -1
  61. package/dist/commands/queries/delete.spec.js +0 -74
  62. package/dist/commands/queries/index.spec.d.ts +0 -1
  63. package/dist/commands/queries/index.spec.js +0 -167
  64. package/dist/commands/queries/list.spec.d.ts +0 -1
  65. package/dist/commands/queries/list.spec.js +0 -170
  66. package/dist/commands/queries/validation.spec.d.ts +0 -1
  67. package/dist/commands/queries/validation.spec.js +0 -27
  68. package/dist/commands/query/index.spec.d.ts +0 -1
  69. package/dist/commands/query/index.spec.js +0 -104
  70. package/dist/commands/targets/index.spec.d.ts +0 -1
  71. package/dist/commands/targets/index.spec.js +0 -154
  72. package/dist/commands/teams/index.spec.d.ts +0 -1
  73. package/dist/commands/teams/index.spec.js +0 -70
  74. package/dist/commands/tools/index.spec.d.ts +0 -1
  75. package/dist/commands/tools/index.spec.js +0 -70
  76. package/dist/commands/uninstall/index.spec.d.ts +0 -1
  77. package/dist/commands/uninstall/index.spec.js +0 -125
  78. package/dist/lib/arkServiceProxy.spec.d.ts +0 -1
  79. package/dist/lib/arkServiceProxy.spec.js +0 -100
  80. package/dist/lib/arkStatus.spec.d.ts +0 -1
  81. package/dist/lib/arkStatus.spec.js +0 -49
  82. package/dist/lib/chatClient.spec.d.ts +0 -1
  83. package/dist/lib/chatClient.spec.js +0 -108
  84. package/dist/lib/cluster.spec.d.ts +0 -1
  85. package/dist/lib/cluster.spec.js +0 -338
  86. package/dist/lib/commands.spec.d.ts +0 -1
  87. package/dist/lib/commands.spec.js +0 -146
  88. package/dist/lib/config.spec.d.ts +0 -1
  89. package/dist/lib/config.spec.js +0 -202
  90. package/dist/lib/duration.spec.d.ts +0 -1
  91. package/dist/lib/duration.spec.js +0 -13
  92. package/dist/lib/errors.spec.d.ts +0 -1
  93. package/dist/lib/errors.spec.js +0 -221
  94. package/dist/lib/executeQuery.spec.d.ts +0 -1
  95. package/dist/lib/executeQuery.spec.js +0 -325
  96. package/dist/lib/kubectl.spec.d.ts +0 -1
  97. package/dist/lib/kubectl.spec.js +0 -192
  98. package/dist/lib/marketplaceFetcher.spec.d.ts +0 -1
  99. package/dist/lib/marketplaceFetcher.spec.js +0 -225
  100. package/dist/lib/nextSteps.spec.d.ts +0 -1
  101. package/dist/lib/nextSteps.spec.js +0 -59
  102. package/dist/lib/output.spec.d.ts +0 -1
  103. package/dist/lib/output.spec.js +0 -123
  104. package/dist/lib/startup.spec.d.ts +0 -1
  105. package/dist/lib/startup.spec.js +0 -152
  106. package/dist/lib/stdin.spec.d.ts +0 -1
  107. package/dist/lib/stdin.spec.js +0 -82
  108. package/dist/lib/timeout.spec.d.ts +0 -1
  109. package/dist/lib/timeout.spec.js +0 -14
  110. package/dist/lib/waitForReady.spec.d.ts +0 -1
  111. package/dist/lib/waitForReady.spec.js +0 -104
  112. package/dist/marketplaceServices.spec.d.ts +0 -1
  113. package/dist/marketplaceServices.spec.js +0 -74
  114. package/dist/ui/statusFormatter.spec.d.ts +0 -1
  115. package/dist/ui/statusFormatter.spec.js +0 -58
@@ -5,8 +5,8 @@ export function createConnectingToArkOperation(params) {
5
5
  operation: async (_signal) => {
6
6
  const client = new ChatClient(params.arkApiClient);
7
7
  const targets = await client.getQueryTargets();
8
- let selectedTarget = null;
9
- let selectedIndex = 0;
8
+ let selectedTarget;
9
+ let selectedIndex;
10
10
  if (params.initialTargetId) {
11
11
  const matchedTarget = targets.find((t) => t.id === params.initialTargetId);
12
12
  const matchedIndex = targets.findIndex((t) => t.id === params.initialTargetId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-at-scale/ark",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "description": "Ark CLI - Interactive terminal interface for ARK agents",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -20,7 +20,7 @@
20
20
  "clean": "rm -rf dist",
21
21
  "lint": "eslint src/ --fix && prettier --write src/",
22
22
  "lint:check": "eslint src/ && prettier --check src/",
23
- "test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --coverageDirectory=./artifacts/coverage --coverageReporters=text --coverageReporters=lcov --coverageReporters=text-summary",
23
+ "test": "vitest run --coverage",
24
24
  "postinstall": "echo \"Ark CLI installed. Run 'ark' to try it out.\""
25
25
  },
26
26
  "keywords": [
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@kubernetes/client-node": "^1.3.0",
46
- "@modelcontextprotocol/sdk": "^1.18.0",
46
+ "@modelcontextprotocol/sdk": "^1.27.1",
47
47
  "axios": "^1.13.5",
48
48
  "chalk": "^4.1.2",
49
49
  "commander": "^12.1.0",
@@ -64,25 +64,29 @@
64
64
  "yaml": "^2.6.1"
65
65
  },
66
66
  "devDependencies": {
67
- "@eslint/js": "^9.17.0",
68
- "@jest/globals": "^30.1.2",
67
+ "@eslint/js": "^10.0.1",
69
68
  "@types/debug": "^4.1.12",
70
69
  "@types/inquirer": "^9.0.7",
71
- "@types/jest": "^30.0.0",
72
70
  "@types/marked-terminal": "^6.1.1",
73
71
  "@types/node": "^22.10.2",
74
72
  "@types/react": "^19.1.13",
75
- "@typescript-eslint/eslint-plugin": "^8.20.0",
76
- "@typescript-eslint/parser": "^8.20.0",
77
- "eslint": "^9.17.0",
78
- "jest": "^30.1.3",
73
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
74
+ "@typescript-eslint/parser": "^8.56.0",
75
+ "@vitest/coverage-v8": "^3.2.4",
76
+ "eslint": "^10.0.0",
77
+ "globals": "^16.2.0",
79
78
  "prettier": "^3.6.2",
80
- "ts-jest": "^29.4.1",
81
79
  "ts-node": "^10.9.2",
82
80
  "tsx": "^4.20.5",
83
- "typescript": "^5.7.2"
81
+ "typescript": "^5.7.2",
82
+ "vitest": "^3.2.4"
84
83
  },
85
84
  "engines": {
86
85
  "node": ">=18.0.0"
86
+ },
87
+ "overrides": {
88
+ "minimatch": "^10.2.3",
89
+ "rollup": "4.59.0",
90
+ "hono": "^4.12.2"
87
91
  }
88
92
  }
@@ -1 +0,0 @@
1
- export {};
@@ -1,138 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- const mockLoadConfig = jest.fn();
3
- const mockGetMarketplaceRegistry = jest.fn();
4
- jest.unstable_mockModule('./lib/config.js', () => ({
5
- loadConfig: mockLoadConfig,
6
- getMarketplaceRegistry: mockGetMarketplaceRegistry,
7
- }));
8
- mockLoadConfig.mockReturnValue({});
9
- mockGetMarketplaceRegistry.mockReturnValue('oci://test-registry/charts');
10
- const { arkDependencies, arkServices: originalArkServices, getInstallableServices, } = await import('./arkServices.js');
11
- describe('arkServices', () => {
12
- beforeEach(() => {
13
- jest.clearAllMocks();
14
- mockLoadConfig.mockReturnValue({});
15
- mockGetMarketplaceRegistry.mockReturnValue('oci://test-registry/charts');
16
- });
17
- it('exports arkDependencies with expected structure', () => {
18
- expect(arkDependencies).toBeDefined();
19
- expect(arkDependencies['cert-manager']).toBeDefined();
20
- expect(arkDependencies['cert-manager'].command).toBe('helm');
21
- });
22
- it('exports arkServices with expected structure', () => {
23
- expect(originalArkServices).toBeDefined();
24
- expect(originalArkServices['ark-controller']).toBeDefined();
25
- expect(originalArkServices['ark-controller'].namespace).toBe('ark-system');
26
- expect(originalArkServices['ark-api'].namespace).toBeUndefined();
27
- expect(originalArkServices['ark-dashboard'].namespace).toBeUndefined();
28
- expect(originalArkServices['localhost-gateway'].namespace).toBe('ark-system');
29
- });
30
- it('getInstallableServices returns services with chartPath', () => {
31
- const installable = getInstallableServices();
32
- expect(installable['ark-controller']).toBeDefined();
33
- expect(installable['ark-api']).toBeDefined();
34
- expect(installable['ark-api-a2a']).toBeUndefined();
35
- });
36
- describe('applyConfigOverrides', () => {
37
- it('applies no overrides when config has no services section', async () => {
38
- mockLoadConfig.mockReturnValue({});
39
- jest.resetModules();
40
- const { arkServices } = await import('./arkServices.js');
41
- expect(arkServices['ark-controller'].enabled).toBe(true);
42
- expect(arkServices['ark-api'].enabled).toBe(true);
43
- });
44
- it('applies overrides to enable a disabled service', async () => {
45
- mockLoadConfig.mockReturnValue({
46
- services: {
47
- 'localhost-gateway': { enabled: true },
48
- },
49
- });
50
- jest.resetModules();
51
- const { arkServices } = await import('./arkServices.js');
52
- expect(arkServices['localhost-gateway'].enabled).toBe(true);
53
- });
54
- it('applies overrides to disable an enabled service', async () => {
55
- mockLoadConfig.mockReturnValue({
56
- services: {
57
- 'ark-controller': { enabled: false },
58
- },
59
- });
60
- jest.resetModules();
61
- const { arkServices } = await import('./arkServices.js');
62
- expect(arkServices['ark-controller'].enabled).toBe(false);
63
- });
64
- it('applies overrides to multiple services', async () => {
65
- mockLoadConfig.mockReturnValue({
66
- services: {
67
- 'ark-controller': { enabled: false },
68
- 'ark-api': { enabled: false },
69
- 'localhost-gateway': { enabled: true },
70
- },
71
- });
72
- jest.resetModules();
73
- const { arkServices } = await import('./arkServices.js');
74
- expect(arkServices['ark-controller'].enabled).toBe(false);
75
- expect(arkServices['ark-api'].enabled).toBe(false);
76
- expect(arkServices['localhost-gateway'].enabled).toBe(true);
77
- });
78
- it('applies overrides to namespace', async () => {
79
- mockLoadConfig.mockReturnValue({
80
- services: {
81
- 'ark-api': { namespace: 'custom-namespace' },
82
- },
83
- });
84
- jest.resetModules();
85
- const { arkServices } = await import('./arkServices.js');
86
- expect(arkServices['ark-api'].namespace).toBe('custom-namespace');
87
- });
88
- it('applies overrides to chartPath', async () => {
89
- mockLoadConfig.mockReturnValue({
90
- services: {
91
- 'ark-controller': {
92
- chartPath: 'oci://custom-registry/charts/ark-controller',
93
- },
94
- },
95
- });
96
- jest.resetModules();
97
- const { arkServices } = await import('./arkServices.js');
98
- expect(arkServices['ark-controller'].chartPath).toBe('oci://custom-registry/charts/ark-controller');
99
- });
100
- it('applies partial overrides without affecting other properties', async () => {
101
- mockLoadConfig.mockReturnValue({
102
- services: {
103
- 'ark-controller': { enabled: false },
104
- },
105
- });
106
- jest.resetModules();
107
- const { arkServices } = await import('./arkServices.js');
108
- expect(arkServices['ark-controller'].enabled).toBe(false);
109
- expect(arkServices['ark-controller'].namespace).toBe('ark-system');
110
- expect(arkServices['ark-controller'].category).toBe('core');
111
- expect(arkServices['ark-controller'].description).toBe('Core Ark controller for managing AI resources');
112
- });
113
- it('applies overrides to installArgs', async () => {
114
- mockLoadConfig.mockReturnValue({
115
- services: {
116
- 'ark-controller': { installArgs: ['--set', 'custom.value=true'] },
117
- },
118
- });
119
- jest.resetModules();
120
- const { arkServices } = await import('./arkServices.js');
121
- expect(arkServices['ark-controller'].installArgs).toEqual([
122
- '--set',
123
- 'custom.value=true',
124
- ]);
125
- });
126
- it('does not affect services without overrides', async () => {
127
- mockLoadConfig.mockReturnValue({
128
- services: {
129
- 'ark-controller': { enabled: false },
130
- },
131
- });
132
- jest.resetModules();
133
- const { arkServices } = await import('./arkServices.js');
134
- expect(arkServices['ark-api'].enabled).toBe(true);
135
- expect(arkServices['ark-dashboard'].enabled).toBe(true);
136
- });
137
- });
138
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,67 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { Command } from 'commander';
3
- const mockExeca = jest.fn();
4
- jest.unstable_mockModule('execa', () => ({
5
- execa: mockExeca,
6
- }));
7
- const mockOutput = {
8
- warning: jest.fn(),
9
- error: jest.fn(),
10
- };
11
- jest.unstable_mockModule('../../lib/output.js', () => ({
12
- default: mockOutput,
13
- }));
14
- const mockExit = jest.spyOn(process, 'exit').mockImplementation((() => {
15
- throw new Error('process.exit called');
16
- }));
17
- const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
18
- const { createAgentsCommand } = await import('./index.js');
19
- describe('agents command', () => {
20
- beforeEach(() => {
21
- jest.clearAllMocks();
22
- });
23
- it('creates command with correct structure', () => {
24
- const command = createAgentsCommand({});
25
- expect(command).toBeInstanceOf(Command);
26
- expect(command.name()).toBe('agents');
27
- });
28
- it('lists agents in text format', async () => {
29
- const mockAgents = {
30
- items: [{ metadata: { name: 'agent1' } }, { metadata: { name: 'agent2' } }],
31
- };
32
- mockExeca.mockResolvedValue({ stdout: JSON.stringify(mockAgents) });
33
- const command = createAgentsCommand({});
34
- await command.parseAsync(['node', 'test']);
35
- expect(mockExeca).toHaveBeenCalledWith('kubectl', ['get', 'agents', '-o', 'json'], { stdio: 'pipe' });
36
- expect(mockConsoleLog).toHaveBeenCalledWith('agent1');
37
- expect(mockConsoleLog).toHaveBeenCalledWith('agent2');
38
- });
39
- it('lists agents in json format', async () => {
40
- const mockAgents = {
41
- items: [{ metadata: { name: 'agent1' } }],
42
- };
43
- mockExeca.mockResolvedValue({ stdout: JSON.stringify(mockAgents) });
44
- const command = createAgentsCommand({});
45
- await command.parseAsync(['node', 'test', '-o', 'json']);
46
- expect(mockConsoleLog).toHaveBeenCalledWith(JSON.stringify(mockAgents.items, null, 2));
47
- });
48
- it('shows warning when no agents', async () => {
49
- mockExeca.mockResolvedValue({ stdout: JSON.stringify({ items: [] }) });
50
- const command = createAgentsCommand({});
51
- await command.parseAsync(['node', 'test']);
52
- expect(mockOutput.warning).toHaveBeenCalledWith('no agents available');
53
- });
54
- it('handles errors', async () => {
55
- mockExeca.mockRejectedValue(new Error('kubectl failed'));
56
- const command = createAgentsCommand({});
57
- await expect(command.parseAsync(['node', 'test'])).rejects.toThrow('process.exit called');
58
- expect(mockOutput.error).toHaveBeenCalledWith('fetching agents:', 'kubectl failed');
59
- expect(mockExit).toHaveBeenCalledWith(1);
60
- });
61
- it('list subcommand works', async () => {
62
- mockExeca.mockResolvedValue({ stdout: JSON.stringify({ items: [] }) });
63
- const command = createAgentsCommand({});
64
- await command.parseAsync(['node', 'test', 'list']);
65
- expect(mockExeca).toHaveBeenCalled();
66
- });
67
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,92 +0,0 @@
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 +0,0 @@
1
- export {};
@@ -1,24 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,34 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,78 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { Command } from 'commander';
3
- const mockLoadConfig = jest.fn();
4
- const mockGetConfigPaths = jest.fn();
5
- const mockFormatConfig = jest.fn();
6
- jest.unstable_mockModule('../../lib/config.js', () => ({
7
- loadConfig: mockLoadConfig,
8
- getConfigPaths: mockGetConfigPaths,
9
- formatConfig: mockFormatConfig,
10
- }));
11
- const mockExistsSync = jest.fn();
12
- jest.unstable_mockModule('fs', () => ({
13
- default: {
14
- existsSync: mockExistsSync,
15
- },
16
- existsSync: mockExistsSync,
17
- }));
18
- const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
19
- const { createConfigCommand } = await import('./index.js');
20
- describe('config command', () => {
21
- beforeEach(() => {
22
- jest.clearAllMocks();
23
- // Reset environment variables
24
- delete process.env.ARK_CHAT_STREAMING;
25
- delete process.env.ARK_CHAT_OUTPUT_FORMAT;
26
- });
27
- it('creates command with correct structure', () => {
28
- const command = createConfigCommand({});
29
- expect(command).toBeInstanceOf(Command);
30
- expect(command.name()).toBe('config');
31
- });
32
- it('displays config paths and environment variables', async () => {
33
- const mockConfig = { defaultModel: 'test-model' };
34
- const mockPaths = {
35
- user: '/home/user/.arkrc.yaml',
36
- project: '/project/.arkrc.yaml',
37
- };
38
- mockLoadConfig.mockReturnValue(mockConfig);
39
- mockGetConfigPaths.mockReturnValue(mockPaths);
40
- mockFormatConfig.mockReturnValue('formatted config');
41
- mockExistsSync.mockReturnValue(true);
42
- const command = createConfigCommand({});
43
- await command.parseAsync(['node', 'test']);
44
- expect(mockLoadConfig).toHaveBeenCalled();
45
- expect(mockGetConfigPaths).toHaveBeenCalled();
46
- expect(mockFormatConfig).toHaveBeenCalledWith(mockConfig);
47
- expect(mockExistsSync).toHaveBeenCalledWith(mockPaths.user);
48
- expect(mockExistsSync).toHaveBeenCalledWith(mockPaths.project);
49
- });
50
- it('shows when config files do not exist', async () => {
51
- const mockPaths = {
52
- user: '/home/user/.arkrc.yaml',
53
- project: '/project/.arkrc.yaml',
54
- };
55
- mockLoadConfig.mockReturnValue({});
56
- mockGetConfigPaths.mockReturnValue(mockPaths);
57
- mockFormatConfig.mockReturnValue('');
58
- mockExistsSync.mockReturnValue(false);
59
- const command = createConfigCommand({});
60
- await command.parseAsync(['node', 'test']);
61
- expect(mockExistsSync).toHaveBeenCalledWith(mockPaths.user);
62
- expect(mockExistsSync).toHaveBeenCalledWith(mockPaths.project);
63
- // Should show that files don't exist
64
- expect(mockConsoleLog).toHaveBeenCalled();
65
- });
66
- it('displays environment variables when set', async () => {
67
- process.env.ARK_CHAT_STREAMING = 'true';
68
- process.env.ARK_CHAT_OUTPUT_FORMAT = 'json';
69
- mockLoadConfig.mockReturnValue({});
70
- mockGetConfigPaths.mockReturnValue({ user: '', project: '' });
71
- mockFormatConfig.mockReturnValue('');
72
- mockExistsSync.mockReturnValue(false);
73
- const command = createConfigCommand({});
74
- await command.parseAsync(['node', 'test']);
75
- // Should display the environment variables
76
- expect(mockConsoleLog).toHaveBeenCalled();
77
- });
78
- });
@@ -1 +0,0 @@
1
- export {};