@agents-at-scale/ark 0.1.33 → 0.1.35-rc.1

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 (132) hide show
  1. package/dist/arkServices.d.ts +50 -0
  2. package/dist/arkServices.js +153 -0
  3. package/dist/charts/charts.d.ts +5 -0
  4. package/dist/charts/charts.js +6 -0
  5. package/dist/charts/dependencies.d.ts +6 -0
  6. package/dist/charts/dependencies.js +50 -0
  7. package/dist/charts/types.d.ts +40 -0
  8. package/dist/charts/types.js +1 -0
  9. package/dist/commands/agents/index.d.ts +2 -0
  10. package/dist/commands/agents/index.js +56 -0
  11. package/dist/commands/agents/selector.d.ts +8 -0
  12. package/dist/commands/agents/selector.js +53 -0
  13. package/dist/commands/agents.d.ts +2 -0
  14. package/dist/commands/agents.js +53 -0
  15. package/dist/commands/chat/index.d.ts +2 -0
  16. package/dist/commands/chat/index.js +45 -0
  17. package/dist/commands/chat.d.ts +2 -0
  18. package/dist/commands/chat.js +45 -0
  19. package/dist/commands/cluster/get.d.ts +2 -0
  20. package/dist/commands/cluster/get.js +39 -0
  21. package/dist/commands/cluster/index.js +2 -4
  22. package/dist/commands/completion/index.d.ts +2 -0
  23. package/dist/commands/completion/index.js +268 -0
  24. package/dist/commands/completion.js +159 -2
  25. package/dist/commands/config/index.d.ts +2 -0
  26. package/dist/commands/config/index.js +42 -0
  27. package/dist/commands/config.d.ts +0 -3
  28. package/dist/commands/config.js +38 -321
  29. package/dist/commands/dashboard/index.d.ts +3 -0
  30. package/dist/commands/dashboard/index.js +39 -0
  31. package/dist/commands/dashboard.d.ts +3 -0
  32. package/dist/commands/dashboard.js +39 -0
  33. package/dist/commands/dev/index.d.ts +2 -0
  34. package/dist/commands/dev/index.js +9 -0
  35. package/dist/commands/dev/tool/check.d.ts +2 -0
  36. package/dist/commands/dev/tool/check.js +142 -0
  37. package/dist/commands/dev/tool/clean.d.ts +2 -0
  38. package/dist/commands/dev/tool/clean.js +153 -0
  39. package/dist/commands/dev/tool/generate.d.ts +2 -0
  40. package/dist/commands/dev/tool/generate.js +28 -0
  41. package/dist/commands/dev/tool/index.d.ts +2 -0
  42. package/dist/commands/dev/tool/index.js +14 -0
  43. package/dist/commands/dev/tool/init.d.ts +2 -0
  44. package/dist/commands/dev/tool/init.js +320 -0
  45. package/dist/commands/dev/tool/shared.d.ts +5 -0
  46. package/dist/commands/dev/tool/shared.js +256 -0
  47. package/dist/commands/dev/tool/status.d.ts +2 -0
  48. package/dist/commands/dev/tool/status.js +136 -0
  49. package/dist/commands/dev/tool.d.ts +2 -0
  50. package/dist/commands/dev/tool.js +559 -0
  51. package/dist/commands/generate/config.js +5 -24
  52. package/dist/commands/generate/generators/mcpserver.d.ts +2 -1
  53. package/dist/commands/generate/generators/mcpserver.js +26 -5
  54. package/dist/commands/install/index.d.ts +6 -0
  55. package/dist/commands/install/index.js +165 -0
  56. package/dist/commands/install.d.ts +3 -0
  57. package/dist/commands/install.js +147 -0
  58. package/dist/commands/models/create.d.ts +1 -0
  59. package/dist/commands/models/create.js +213 -0
  60. package/dist/commands/models/index.d.ts +2 -0
  61. package/dist/commands/models/index.js +65 -0
  62. package/dist/commands/models/selector.d.ts +8 -0
  63. package/dist/commands/models/selector.js +53 -0
  64. package/dist/commands/routes/index.d.ts +2 -0
  65. package/dist/commands/routes/index.js +101 -0
  66. package/dist/commands/routes.d.ts +2 -0
  67. package/dist/commands/routes.js +101 -0
  68. package/dist/commands/status/index.d.ts +3 -0
  69. package/dist/commands/status/index.js +33 -0
  70. package/dist/commands/status.d.ts +3 -0
  71. package/dist/commands/status.js +33 -0
  72. package/dist/commands/targets/index.d.ts +2 -0
  73. package/dist/commands/targets/index.js +65 -0
  74. package/dist/commands/targets.d.ts +2 -0
  75. package/dist/commands/targets.js +65 -0
  76. package/dist/commands/teams/index.d.ts +2 -0
  77. package/dist/commands/teams/index.js +54 -0
  78. package/dist/commands/teams/selector.d.ts +8 -0
  79. package/dist/commands/teams/selector.js +55 -0
  80. package/dist/commands/tools/index.d.ts +2 -0
  81. package/dist/commands/tools/index.js +54 -0
  82. package/dist/commands/tools/selector.d.ts +8 -0
  83. package/dist/commands/tools/selector.js +53 -0
  84. package/dist/commands/uninstall/index.d.ts +2 -0
  85. package/dist/commands/uninstall/index.js +84 -0
  86. package/dist/commands/uninstall.d.ts +2 -0
  87. package/dist/commands/uninstall.js +83 -0
  88. package/dist/components/ChatUI.d.ts +16 -0
  89. package/dist/components/ChatUI.js +801 -0
  90. package/dist/components/StatusView.d.ts +10 -0
  91. package/dist/components/StatusView.js +39 -0
  92. package/dist/components/statusChecker.d.ts +10 -13
  93. package/dist/components/statusChecker.js +128 -65
  94. package/dist/config.js +3 -10
  95. package/dist/index.d.ts +1 -1
  96. package/dist/index.js +31 -36
  97. package/dist/lib/arkApiClient.d.ts +53 -0
  98. package/dist/lib/arkApiClient.js +102 -0
  99. package/dist/lib/arkApiProxy.d.ts +9 -0
  100. package/dist/lib/arkApiProxy.js +22 -0
  101. package/dist/lib/arkServiceProxy.d.ts +14 -0
  102. package/dist/lib/arkServiceProxy.js +93 -0
  103. package/dist/lib/arkStatus.d.ts +5 -0
  104. package/dist/lib/arkStatus.js +20 -0
  105. package/dist/lib/chatClient.d.ts +33 -0
  106. package/dist/lib/chatClient.js +101 -0
  107. package/dist/lib/cluster.d.ts +2 -1
  108. package/dist/lib/cluster.js +27 -3
  109. package/dist/lib/commandUtils.d.ts +4 -0
  110. package/dist/lib/commandUtils.js +18 -0
  111. package/dist/lib/commandUtils.test.d.ts +1 -0
  112. package/dist/lib/commandUtils.test.js +44 -0
  113. package/dist/lib/config.d.ts +24 -80
  114. package/dist/lib/config.js +68 -205
  115. package/dist/lib/config.test.d.ts +1 -0
  116. package/dist/lib/config.test.js +93 -0
  117. package/dist/lib/dev/tools/analyzer.d.ts +30 -0
  118. package/dist/lib/dev/tools/analyzer.js +190 -0
  119. package/dist/lib/dev/tools/discover_tools.py +392 -0
  120. package/dist/lib/dev/tools/mcp-types.d.ts +28 -0
  121. package/dist/lib/dev/tools/mcp-types.js +86 -0
  122. package/dist/lib/dev/tools/types.d.ts +50 -0
  123. package/dist/lib/dev/tools/types.js +1 -0
  124. package/dist/lib/output.d.ts +36 -0
  125. package/dist/lib/output.js +89 -0
  126. package/dist/lib/types.d.ts +8 -3
  127. package/dist/types/types.d.ts +40 -0
  128. package/dist/types/types.js +1 -0
  129. package/dist/ui/MainMenu.js +158 -90
  130. package/dist/ui/statusFormatter.d.ts +4 -1
  131. package/dist/ui/statusFormatter.js +91 -19
  132. package/package.json +16 -4
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { StatusData } from '../lib/types.js';
3
+ interface StatusViewProps {
4
+ statusData: StatusData | null;
5
+ isLoading: boolean;
6
+ error: string | null;
7
+ onBack: () => void;
8
+ }
9
+ declare const StatusView: React.FC<StatusViewProps>;
10
+ export default StatusView;
@@ -0,0 +1,39 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ const StatusView = ({ statusData, isLoading, error, onBack, }) => {
4
+ useInput((input, key) => {
5
+ if (key.escape || input === 'q' || key.return) {
6
+ onBack();
7
+ }
8
+ });
9
+ const renderServiceStatus = (service) => {
10
+ const statusColor = service.status === 'healthy'
11
+ ? 'green'
12
+ : service.status === 'unhealthy'
13
+ ? 'red'
14
+ : 'yellow';
15
+ const statusIcon = service.status === 'healthy'
16
+ ? '✓'
17
+ : service.status === 'unhealthy'
18
+ ? '✗'
19
+ : '?';
20
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsxs(Text, { bold: true, children: [service.name, ": "] }), _jsx(Text, { color: statusColor, children: service.status })] }), service.url && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "gray", children: ["URL: ", service.url] }) })), service.details && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: service.details }) }))] }, service.name));
21
+ };
22
+ const renderDependencyStatus = (dep) => {
23
+ const statusColor = dep.installed ? 'green' : 'red';
24
+ const statusIcon = dep.installed ? '✓' : '✗';
25
+ const statusText = dep.installed ? 'installed' : 'missing';
26
+ return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Box, { children: [_jsxs(Text, { color: statusColor, children: [statusIcon, " "] }), _jsxs(Text, { bold: true, children: [dep.name, ": "] }), _jsx(Text, { color: statusColor, children: statusText })] }), dep.version && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "gray", children: ["Version: ", dep.version] }) })), dep.details && (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: dep.details }) }))] }, dep.name));
27
+ };
28
+ if (isLoading) {
29
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDD0D Checking ARK system status..." }), _jsx(Text, { color: "gray", children: "Please wait while we verify services and dependencies." })] }));
30
+ }
31
+ if (error) {
32
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "red", children: "\u274C Error checking status:" }), _jsx(Text, { color: "red", children: error }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Press ESC, 'q', or Enter to return to menu..." }) })] }));
33
+ }
34
+ if (!statusData) {
35
+ return null;
36
+ }
37
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDD0D ARK System Status" }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCE1 ARK Services:" }) }), statusData.services.map(renderServiceStatus), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDEE0\uFE0F System Dependencies:" }) }), statusData.dependencies.map(renderDependencyStatus), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Press ESC, 'q', or Enter to return to menu..." }) })] }));
38
+ };
39
+ export default StatusView;
@@ -5,26 +5,24 @@ export declare const getNpmVersion: () => CommandVersionConfig;
5
5
  export declare const getKubectlVersion: () => CommandVersionConfig;
6
6
  export declare const getDockerVersion: () => CommandVersionConfig;
7
7
  export declare const getHelmVersion: () => CommandVersionConfig;
8
+ export declare const getMinikubeVersion: () => CommandVersionConfig;
9
+ export declare const getKindVersion: () => CommandVersionConfig;
8
10
  export declare class StatusChecker {
9
11
  private arkClient;
10
12
  private kubernetesManager;
11
13
  constructor(arkClient: ArkClient);
12
- /**
13
- * Check if a command is available in the system
14
- */
15
- private isCommandAvailable;
16
14
  /**
17
15
  * Get version of a command
18
16
  */
19
17
  private getCommandVersion;
20
18
  /**
21
- * Check health of a service by URL
19
+ * Check deployment status
22
20
  */
23
- private checkServiceHealth;
21
+ private checkDeploymentStatus;
24
22
  /**
25
- * Check if ark-api is running and healthy
23
+ * Check helm release status (fallback for services without deployments)
26
24
  */
27
- private checkArkApi;
25
+ private checkHelmStatus;
28
26
  /**
29
27
  * Return a "not installed" status for a service
30
28
  */
@@ -40,9 +38,8 @@ export declare class StatusChecker {
40
38
  /**
41
39
  * Run all checks and return results
42
40
  */
43
- checkAll(serviceUrls?: Record<string, string>, arkApiUrl?: string): Promise<StatusData>;
44
- /**
45
- * Get appropriate health check path for different service types
46
- */
47
- private getHealthPath;
41
+ checkAll(): Promise<StatusData & {
42
+ clusterAccess: boolean;
43
+ clusterInfo?: any;
44
+ }>;
48
45
  }
@@ -2,7 +2,9 @@ import { exec } from 'child_process';
2
2
  import { promisify } from 'util';
3
3
  import { KubernetesConfigManager } from '../lib/kubernetes.js';
4
4
  import * as k8s from '@kubernetes/client-node';
5
- import axios from 'axios';
5
+ import { isCommandAvailable } from '../lib/commandUtils.js';
6
+ import { arkServices } from '../arkServices.js';
7
+ import { isArkReady } from '../lib/arkStatus.js';
6
8
  const execAsync = promisify(exec);
7
9
  export const getNodeVersion = () => ({
8
10
  command: 'node',
@@ -40,6 +42,20 @@ export const getHelmVersion = () => ({
40
42
  versionArgs: 'version --short',
41
43
  versionExtract: (output) => output.trim(),
42
44
  });
45
+ export const getMinikubeVersion = () => ({
46
+ command: 'minikube',
47
+ versionArgs: 'version --short',
48
+ versionExtract: (output) => output.trim(),
49
+ });
50
+ export const getKindVersion = () => ({
51
+ command: 'kind',
52
+ versionArgs: 'version',
53
+ versionExtract: (output) => {
54
+ // kind version output is like "kind v0.20.0 go1.21.0 linux/amd64"
55
+ const match = output.match(/kind (v[\d.]+)/);
56
+ return match ? match[1] : output.trim();
57
+ },
58
+ });
43
59
  function createErrorServiceStatus(name, url, error, defaultStatus = 'unhealthy', defaultDetails) {
44
60
  const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
45
61
  return {
@@ -54,21 +70,6 @@ export class StatusChecker {
54
70
  this.arkClient = arkClient;
55
71
  this.kubernetesManager = new KubernetesConfigManager();
56
72
  }
57
- /**
58
- * Check if a command is available in the system
59
- */
60
- async isCommandAvailable(command) {
61
- try {
62
- const checkCommand = process.platform === 'win32'
63
- ? `where ${command}`
64
- : `command -v ${command}`;
65
- await execAsync(checkCommand);
66
- return true;
67
- }
68
- catch (_error) {
69
- return false;
70
- }
71
- }
72
73
  /**
73
74
  * Get version of a command
74
75
  */
@@ -83,29 +84,81 @@ export class StatusChecker {
83
84
  }
84
85
  }
85
86
  /**
86
- * Check health of a service by URL
87
+ * Check deployment status
87
88
  */
88
- async checkServiceHealth(serviceName, serviceUrl, successMessage, healthPath = '') {
89
- const fullUrl = `${serviceUrl}${healthPath}`;
89
+ async checkDeploymentStatus(serviceName, deploymentName, namespace) {
90
90
  try {
91
- await axios.get(fullUrl, { timeout: 5000 });
91
+ const cmd = `kubectl get deployment ${deploymentName} --namespace ${namespace} -o json`;
92
+ const { stdout } = await execAsync(cmd);
93
+ const deployment = JSON.parse(stdout);
94
+ const replicas = deployment.spec?.replicas || 0;
95
+ const readyReplicas = deployment.status?.readyReplicas || 0;
96
+ const availableReplicas = deployment.status?.availableReplicas || 0;
97
+ // Check Kubernetes 'Available' condition - only 'available' deployments are healthy
98
+ const availableCondition = deployment.status?.conditions?.find((condition) => condition.type === 'Available');
99
+ const isAvailable = availableCondition?.status === 'True';
100
+ const allReplicasReady = readyReplicas === replicas && availableReplicas === replicas;
101
+ // Determine status: not ready if 0 replicas, healthy if available and all ready, warning otherwise
102
+ let status;
103
+ if (replicas === 0 || readyReplicas === 0) {
104
+ status = 'not ready';
105
+ }
106
+ else if (isAvailable && allReplicasReady) {
107
+ status = 'healthy';
108
+ }
109
+ else {
110
+ status = 'warning';
111
+ }
92
112
  return {
93
113
  name: serviceName,
94
- status: 'healthy',
95
- url: serviceUrl,
96
- details: successMessage,
114
+ status,
115
+ details: `${readyReplicas}/${replicas} replicas ready`,
97
116
  };
98
117
  }
99
118
  catch (error) {
100
- return createErrorServiceStatus(serviceName, serviceUrl, error, 'unhealthy', `${serviceName} is not running or not accessible`);
119
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
120
+ if (errorMessage.includes('not found')) {
121
+ return {
122
+ name: serviceName,
123
+ status: 'not installed',
124
+ details: `Deployment '${deploymentName}' not found in namespace '${namespace}'`,
125
+ };
126
+ }
127
+ return createErrorServiceStatus(serviceName, '', error, 'unhealthy', `Failed to check deployment: ${errorMessage}`);
101
128
  }
102
129
  }
103
130
  /**
104
- * Check if ark-api is running and healthy
131
+ * Check helm release status (fallback for services without deployments)
105
132
  */
106
- async checkArkApi(customUrl) {
107
- const url = customUrl || this.arkClient.getBaseURL();
108
- return this.checkServiceHealth('ark-api', url, 'ARK API is running', '/health');
133
+ async checkHelmStatus(serviceName, helmReleaseName, namespace) {
134
+ try {
135
+ const cmd = `helm list --filter ${helmReleaseName} --namespace ${namespace} --output json`;
136
+ const { stdout } = await execAsync(cmd);
137
+ const helmList = JSON.parse(stdout);
138
+ if (helmList.length === 0) {
139
+ return {
140
+ name: serviceName,
141
+ status: 'not installed',
142
+ details: `Helm release '${helmReleaseName}' not found in namespace '${namespace}'`,
143
+ };
144
+ }
145
+ const release = helmList[0];
146
+ const status = release.status?.toLowerCase() || 'unknown';
147
+ const revision = release.revision || 'unknown';
148
+ const appVersion = release.app_version || 'unknown';
149
+ const isHealthy = status === 'deployed';
150
+ return {
151
+ name: serviceName,
152
+ status: isHealthy ? 'healthy' : 'unhealthy',
153
+ version: appVersion,
154
+ revision: revision,
155
+ details: `Status: ${status}`,
156
+ };
157
+ }
158
+ catch (error) {
159
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
160
+ return createErrorServiceStatus(serviceName, '', error, 'unhealthy', `Failed to check helm status: ${errorMessage}`);
161
+ }
109
162
  }
110
163
  /**
111
164
  * Return a "not installed" status for a service
@@ -180,10 +233,12 @@ export class StatusChecker {
180
233
  { name: 'kubectl', ...getKubectlVersion() },
181
234
  { name: 'docker', ...getDockerVersion() },
182
235
  { name: 'helm', ...getHelmVersion() },
236
+ { name: 'minikube', ...getMinikubeVersion() },
237
+ { name: 'kind', ...getKindVersion() },
183
238
  ];
184
239
  const results = [];
185
240
  for (const dep of dependencies) {
186
- const installed = await this.isCommandAvailable(dep.command);
241
+ const installed = await isCommandAvailable(dep.command);
187
242
  const version = installed
188
243
  ? await this.getCommandVersion({
189
244
  command: dep.command,
@@ -205,47 +260,55 @@ export class StatusChecker {
205
260
  /**
206
261
  * Run all checks and return results
207
262
  */
208
- async checkAll(serviceUrls = {}, arkApiUrl) {
209
- // Always check ark-api if provided
210
- const serviceChecks = [];
211
- if (arkApiUrl) {
212
- serviceChecks.push(this.checkArkApi(arkApiUrl));
263
+ async checkAll() {
264
+ // Check dependencies first
265
+ const dependencies = await this.checkDependencies();
266
+ // Test cluster access
267
+ const configManager = new (await import('../config.js')).ConfigManager();
268
+ const clusterAccess = await configManager.testClusterAccess();
269
+ // Get cluster info if accessible
270
+ let clusterInfo;
271
+ if (clusterAccess) {
272
+ const { getClusterInfo } = await import('../lib/cluster.js');
273
+ clusterInfo = await getClusterInfo();
274
+ }
275
+ let services = [];
276
+ // Only check ARK services if we have cluster access
277
+ if (clusterAccess) {
278
+ const serviceChecks = [];
279
+ for (const [serviceName, service] of Object.entries(arkServices)) {
280
+ if (service.k8sDeploymentName) {
281
+ serviceChecks.push(this.checkDeploymentStatus(serviceName, service.k8sDeploymentName, service.namespace));
282
+ }
283
+ else {
284
+ serviceChecks.push(this.checkHelmStatus(serviceName, service.helmReleaseName, service.namespace));
285
+ }
286
+ }
287
+ services = await Promise.all(serviceChecks);
213
288
  }
214
- // Dynamically check all discovered services
215
- for (const [serviceName, serviceUrl] of Object.entries(serviceUrls)) {
216
- if (serviceName === 'ark-api' && arkApiUrl) {
217
- // Skip if we already added ark-api above
218
- continue;
289
+ // Check if ARK is ready (controller is running)
290
+ let arkReady = false;
291
+ let defaultModelExists = false;
292
+ if (clusterAccess) {
293
+ arkReady = await isArkReady();
294
+ // Check for default model
295
+ if (arkReady) {
296
+ try {
297
+ await execAsync('kubectl get model default -o name');
298
+ defaultModelExists = true;
299
+ }
300
+ catch {
301
+ defaultModelExists = false;
302
+ }
219
303
  }
220
- serviceChecks.push(this.checkServiceHealth(serviceName, serviceUrl, `${serviceName} is running`, this.getHealthPath(serviceName)));
221
304
  }
222
- // Always check dependencies
223
- const dependenciesCheck = this.checkDependencies();
224
- const [dependencies, ...serviceStatuses] = await Promise.all([
225
- dependenciesCheck,
226
- ...serviceChecks,
227
- ]);
228
305
  return {
229
- services: serviceStatuses,
306
+ services,
230
307
  dependencies,
308
+ clusterAccess,
309
+ clusterInfo,
310
+ arkReady,
311
+ defaultModelExists,
231
312
  };
232
313
  }
233
- /**
234
- * Get appropriate health check path for different service types
235
- */
236
- getHealthPath(serviceName) {
237
- // Some services might need specific health check paths
238
- switch (serviceName) {
239
- case 'ark-api':
240
- return '/health';
241
- case 'ark-api-a2a':
242
- return '/health'; // ark-api-a2a has a working /health endpoint
243
- case 'ark-dashboard':
244
- return ''; // Dashboard typically responds to root
245
- case 'langfuse':
246
- return ''; // Langfuse responds to root path
247
- default:
248
- return ''; // Default to root path
249
- }
250
- }
251
314
  }
package/dist/config.js CHANGED
@@ -7,6 +7,7 @@ import { ArkClient } from './lib/arkClient.js';
7
7
  import { DEFAULT_ADDRESS_ARK_API, CONFIG_DIR_NAME, CONFIG_FILE_NAME, } from './lib/consts.js';
8
8
  import { GatewayManager } from './lib/gatewayManager.js';
9
9
  import { KubernetesConfigManager } from './lib/kubernetes.js';
10
+ import { getStatusCheckableServices } from './arkServices.js';
10
11
  const debug = Debug('ark:config');
11
12
  /**
12
13
  * ConfigManager handles ARK CLI configuration with automatic service discovery
@@ -163,16 +164,8 @@ export class ConfigManager {
163
164
  * Construct standard localhost-gateway URLs for known ARK services
164
165
  */
165
166
  getLocalhostGatewayUrls() {
166
- const port = 8080;
167
- // Known services that are typically exposed via localhost-gateway
168
- const knownServices = {
169
- 'ark-api': `http://ark-api.127.0.0.1.nip.io:${port}`,
170
- 'ark-dashboard': `http://dashboard.127.0.0.1.nip.io:${port}`,
171
- 'ark-api-a2a': `http://ark-api-a2a.127.0.0.1.nip.io:${port}`,
172
- langfuse: `http://langfuse.telemetry.127.0.0.1.nip.io:${port}`, // Fixed URL to match HTTPRoute
173
- // Add other services as they become available via gateway
174
- };
175
- return knownServices;
167
+ // Use centralized service definitions from arkServices
168
+ return getStatusCheckableServices();
176
169
  }
177
170
  async initKubernetesConfig() {
178
171
  if (!this.kubeConfig) {
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env NODE_NO_WARNINGS=1 node
2
2
  export {};
package/dist/index.js CHANGED
@@ -1,39 +1,31 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env NODE_NO_WARNINGS=1 node
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import chalk from 'chalk';
4
3
  import { Command } from 'commander';
5
4
  import { render } from 'ink';
6
5
  import { createRequire } from 'module';
7
6
  const require = createRequire(import.meta.url);
8
7
  const packageJson = require('../package.json');
8
+ import output from './lib/output.js';
9
+ import { createAgentsCommand } from './commands/agents/index.js';
10
+ import { createChatCommand } from './commands/chat/index.js';
9
11
  import { createClusterCommand } from './commands/cluster/index.js';
10
- import { createCompletionCommand } from './commands/completion.js';
12
+ import { createCompletionCommand } from './commands/completion/index.js';
13
+ import { createDashboardCommand } from './commands/dashboard/index.js';
14
+ import { createDevCommand } from './commands/dev/index.js';
11
15
  import { createGenerateCommand } from './commands/generate/index.js';
12
- import { createConfigCommand } from './commands/config.js';
13
- import { StatusChecker } from './components/statusChecker.js';
14
- import { ConfigManager } from './config.js';
15
- import { ArkClient } from './lib/arkClient.js';
16
+ import { createInstallCommand } from './commands/install/index.js';
17
+ import { createModelsCommand } from './commands/models/index.js';
18
+ import { createUninstallCommand } from './commands/uninstall/index.js';
19
+ import { createStatusCommand } from './commands/status/index.js';
20
+ import { createConfigCommand } from './commands/config/index.js';
21
+ import { createTargetsCommand } from './commands/targets/index.js';
22
+ import { createTeamsCommand } from './commands/teams/index.js';
23
+ import { createToolsCommand } from './commands/tools/index.js';
24
+ import { createRoutesCommand } from './commands/routes/index.js';
16
25
  import MainMenu from './ui/MainMenu.js';
17
- import { StatusFormatter } from './ui/statusFormatter.js';
18
26
  function showMainMenu() {
19
- console.clear();
20
- render(_jsx(MainMenu, {}));
21
- }
22
- async function handleStatusCheck() {
23
- try {
24
- const configManager = new ConfigManager();
25
- const apiBaseUrl = await configManager.getApiBaseUrl();
26
- const serviceUrls = await configManager.getServiceUrls();
27
- const arkClient = new ArkClient(apiBaseUrl);
28
- const statusChecker = new StatusChecker(arkClient);
29
- const statusData = await statusChecker.checkAll(serviceUrls, apiBaseUrl);
30
- StatusFormatter.printStatus(statusData);
31
- process.exit(0); // Exit cleanly after showing status
32
- }
33
- catch (error) {
34
- console.error(chalk.red('Failed to check status:'), error);
35
- process.exit(1);
36
- }
27
+ const app = render(_jsx(MainMenu, {}));
28
+ globalThis.inkApp = app;
37
29
  }
38
30
  async function main() {
39
31
  const program = new Command();
@@ -41,27 +33,30 @@ async function main() {
41
33
  .name(packageJson.name)
42
34
  .description(packageJson.description)
43
35
  .version(packageJson.version);
36
+ program.addCommand(createAgentsCommand());
37
+ program.addCommand(createChatCommand());
44
38
  program.addCommand(createClusterCommand());
45
39
  program.addCommand(createCompletionCommand());
40
+ program.addCommand(createDashboardCommand());
41
+ program.addCommand(createDevCommand());
46
42
  program.addCommand(createGenerateCommand());
43
+ program.addCommand(createInstallCommand());
44
+ program.addCommand(createModelsCommand());
45
+ program.addCommand(createUninstallCommand());
46
+ program.addCommand(createStatusCommand());
47
47
  program.addCommand(createConfigCommand());
48
- // Add check status command
49
- const checkCommand = new Command('check');
50
- checkCommand.description('Check various ARK system components');
51
- checkCommand
52
- .command('status')
53
- .description('Check system status')
54
- .action(handleStatusCheck);
55
- program.addCommand(checkCommand);
48
+ program.addCommand(createTargetsCommand());
49
+ program.addCommand(createTeamsCommand());
50
+ program.addCommand(createToolsCommand());
51
+ program.addCommand(createRoutesCommand());
56
52
  // If no args provided, show interactive menu
57
53
  if (process.argv.length === 2) {
58
- console.log();
59
54
  showMainMenu();
60
55
  return;
61
56
  }
62
57
  await program.parseAsync(process.argv);
63
58
  }
64
59
  main().catch((error) => {
65
- console.error(chalk.red('Failed to start ARK CLI:'), error);
60
+ output.error('failed to start ark cli: ', error);
66
61
  process.exit(1);
67
62
  });
@@ -0,0 +1,53 @@
1
+ import OpenAI from 'openai';
2
+ export interface QueryTarget {
3
+ id: string;
4
+ name: string;
5
+ type: 'agent' | 'model' | 'tool' | string;
6
+ description?: string;
7
+ }
8
+ export interface Agent {
9
+ name: string;
10
+ namespace: string;
11
+ description?: string;
12
+ model_ref?: string;
13
+ prompt?: string;
14
+ status?: string;
15
+ annotations?: Record<string, string>;
16
+ }
17
+ export interface Model {
18
+ name: string;
19
+ namespace: string;
20
+ type: string;
21
+ model: string;
22
+ status: string;
23
+ annotations?: Record<string, string>;
24
+ }
25
+ export interface Tool {
26
+ name: string;
27
+ namespace: string;
28
+ description?: string;
29
+ labels?: Record<string, string>;
30
+ annotations?: Record<string, string>;
31
+ }
32
+ export interface Team {
33
+ name: string;
34
+ namespace: string;
35
+ description?: string;
36
+ strategy?: string;
37
+ members_count?: number;
38
+ status?: string;
39
+ }
40
+ export declare class ArkApiClient {
41
+ private openai;
42
+ private baseUrl;
43
+ private namespace;
44
+ constructor(arkApiUrl: string, namespace?: string);
45
+ getBaseUrl(): string;
46
+ getQueryTargets(): Promise<QueryTarget[]>;
47
+ getAgents(): Promise<Agent[]>;
48
+ getModels(): Promise<Model[]>;
49
+ getTools(): Promise<Tool[]>;
50
+ getTeams(): Promise<Team[]>;
51
+ createChatCompletion(params: OpenAI.Chat.Completions.ChatCompletionCreateParams): Promise<OpenAI.Chat.Completions.ChatCompletion>;
52
+ createChatCompletionStream(params: OpenAI.Chat.Completions.ChatCompletionCreateParams): AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>;
53
+ }
@@ -0,0 +1,102 @@
1
+ import OpenAI from 'openai';
2
+ export class ArkApiClient {
3
+ constructor(arkApiUrl, namespace = 'default') {
4
+ this.baseUrl = arkApiUrl;
5
+ this.namespace = namespace;
6
+ this.openai = new OpenAI({
7
+ baseURL: `${arkApiUrl}/openai/v1`,
8
+ apiKey: 'dummy', // ark-api doesn't require an API key
9
+ dangerouslyAllowBrowser: false,
10
+ });
11
+ }
12
+ getBaseUrl() {
13
+ return this.baseUrl;
14
+ }
15
+ async getQueryTargets() {
16
+ try {
17
+ const models = await this.openai.models.list();
18
+ const targets = models.data.map((model) => {
19
+ const parts = model.id.split('/');
20
+ const type = parts[0] || 'model';
21
+ const name = parts.slice(1).join('/') || model.id;
22
+ return {
23
+ id: model.id,
24
+ name,
25
+ type,
26
+ description: model.id,
27
+ };
28
+ });
29
+ return targets;
30
+ }
31
+ catch (error) {
32
+ throw new Error(`Failed to get query targets: ${error instanceof Error ? error.message : 'Unknown error'}`);
33
+ }
34
+ }
35
+ async getAgents() {
36
+ try {
37
+ const response = await fetch(`${this.baseUrl}/v1/namespaces/${this.namespace}/agents`);
38
+ if (!response.ok) {
39
+ throw new Error(`HTTP error! status: ${response.status}`);
40
+ }
41
+ const data = (await response.json());
42
+ return data.items || [];
43
+ }
44
+ catch (error) {
45
+ throw new Error(`Failed to get agents: ${error instanceof Error ? error.message : 'Unknown error'}`);
46
+ }
47
+ }
48
+ async getModels() {
49
+ try {
50
+ const response = await fetch(`${this.baseUrl}/v1/namespaces/${this.namespace}/models`);
51
+ if (!response.ok) {
52
+ throw new Error(`HTTP error! status: ${response.status}`);
53
+ }
54
+ const data = (await response.json());
55
+ return data.items || [];
56
+ }
57
+ catch (error) {
58
+ throw new Error(`Failed to get models: ${error instanceof Error ? error.message : 'Unknown error'}`);
59
+ }
60
+ }
61
+ async getTools() {
62
+ try {
63
+ const response = await fetch(`${this.baseUrl}/v1/namespaces/${this.namespace}/tools`);
64
+ if (!response.ok) {
65
+ throw new Error(`HTTP error! status: ${response.status}`);
66
+ }
67
+ const data = (await response.json());
68
+ return data.items || [];
69
+ }
70
+ catch (error) {
71
+ throw new Error(`Failed to get tools: ${error instanceof Error ? error.message : 'Unknown error'}`);
72
+ }
73
+ }
74
+ async getTeams() {
75
+ try {
76
+ const response = await fetch(`${this.baseUrl}/v1/namespaces/${this.namespace}/teams`);
77
+ if (!response.ok) {
78
+ throw new Error(`HTTP error! status: ${response.status}`);
79
+ }
80
+ const data = (await response.json());
81
+ return data.items || [];
82
+ }
83
+ catch (error) {
84
+ throw new Error(`Failed to get teams: ${error instanceof Error ? error.message : 'Unknown error'}`);
85
+ }
86
+ }
87
+ async createChatCompletion(params) {
88
+ return (await this.openai.chat.completions.create({
89
+ ...params,
90
+ stream: false,
91
+ }));
92
+ }
93
+ async *createChatCompletionStream(params) {
94
+ const stream = await this.openai.chat.completions.create({
95
+ ...params,
96
+ stream: true,
97
+ });
98
+ for await (const chunk of stream) {
99
+ yield chunk;
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,9 @@
1
+ import { ArkApiClient } from './arkApiClient.js';
2
+ export declare class ArkApiProxy {
3
+ private serviceProxy;
4
+ constructor(localPort?: number);
5
+ start(): Promise<ArkApiClient>;
6
+ stop(): void;
7
+ isRunning(): boolean;
8
+ getLocalUrl(): string;
9
+ }