@agents-at-scale/ark 0.1.35-rc2 → 0.1.35
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.
- package/dist/commands/cluster/index.d.ts +1 -2
- package/dist/commands/cluster/index.js +5 -3
- package/dist/commands/completion.js +2 -159
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.js +321 -38
- package/dist/commands/generate/config.js +24 -5
- package/dist/commands/generate/generators/agent.js +2 -2
- package/dist/commands/generate/generators/mcpserver.d.ts +1 -2
- package/dist/commands/generate/generators/mcpserver.js +5 -26
- package/dist/commands/generate/generators/project.js +41 -22
- package/dist/commands/generate/generators/team.js +2 -2
- package/dist/commands/generate/index.d.ts +1 -2
- package/dist/commands/generate/index.js +1 -1
- package/dist/components/statusChecker.d.ts +23 -13
- package/dist/components/statusChecker.js +129 -295
- package/dist/config.d.ts +22 -3
- package/dist/config.js +161 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +42 -44
- package/dist/lib/cluster.d.ts +1 -2
- package/dist/lib/cluster.js +16 -37
- package/dist/lib/config.d.ts +80 -28
- package/dist/lib/config.js +205 -70
- package/dist/lib/consts.d.ts +1 -0
- package/dist/lib/consts.js +2 -0
- package/dist/lib/errors.js +1 -1
- package/dist/lib/exec.d.ts +4 -0
- package/dist/lib/exec.js +11 -0
- package/dist/lib/types.d.ts +3 -17
- package/dist/ui/MainMenu.d.ts +1 -5
- package/dist/ui/MainMenu.js +91 -222
- package/dist/ui/statusFormatter.d.ts +7 -22
- package/dist/ui/statusFormatter.js +39 -39
- package/package.json +5 -17
- package/dist/arkServices.d.ts +0 -42
- package/dist/arkServices.js +0 -138
- package/dist/arkServices.spec.d.ts +0 -1
- package/dist/arkServices.spec.js +0 -24
- package/dist/charts/charts.d.ts +0 -5
- package/dist/charts/charts.js +0 -6
- package/dist/charts/dependencies.d.ts +0 -6
- package/dist/charts/dependencies.js +0 -50
- package/dist/charts/types.d.ts +0 -40
- package/dist/charts/types.js +0 -1
- package/dist/commands/agents/index.d.ts +0 -3
- package/dist/commands/agents/index.js +0 -51
- package/dist/commands/agents/index.spec.d.ts +0 -1
- package/dist/commands/agents/index.spec.js +0 -67
- package/dist/commands/agents/selector.d.ts +0 -8
- package/dist/commands/agents/selector.js +0 -53
- package/dist/commands/agents.d.ts +0 -2
- package/dist/commands/agents.js +0 -53
- package/dist/commands/chat/index.d.ts +0 -3
- package/dist/commands/chat/index.js +0 -29
- package/dist/commands/chat.d.ts +0 -2
- package/dist/commands/chat.js +0 -45
- package/dist/commands/cluster/get.d.ts +0 -2
- package/dist/commands/cluster/get.js +0 -39
- package/dist/commands/cluster/get.spec.d.ts +0 -1
- package/dist/commands/cluster/get.spec.js +0 -92
- package/dist/commands/cluster/index.spec.d.ts +0 -1
- package/dist/commands/cluster/index.spec.js +0 -24
- package/dist/commands/completion/index.d.ts +0 -3
- package/dist/commands/completion/index.js +0 -290
- package/dist/commands/completion/index.spec.d.ts +0 -1
- package/dist/commands/completion/index.spec.js +0 -34
- package/dist/commands/config/index.d.ts +0 -3
- package/dist/commands/config/index.js +0 -42
- package/dist/commands/config/index.spec.d.ts +0 -1
- package/dist/commands/config/index.spec.js +0 -78
- package/dist/commands/dashboard/index.d.ts +0 -4
- package/dist/commands/dashboard/index.js +0 -39
- package/dist/commands/dashboard.d.ts +0 -3
- package/dist/commands/dashboard.js +0 -39
- package/dist/commands/dev/index.d.ts +0 -3
- package/dist/commands/dev/index.js +0 -9
- package/dist/commands/dev/tool/check.d.ts +0 -2
- package/dist/commands/dev/tool/check.js +0 -142
- package/dist/commands/dev/tool/clean.d.ts +0 -2
- package/dist/commands/dev/tool/clean.js +0 -153
- package/dist/commands/dev/tool/generate.d.ts +0 -2
- package/dist/commands/dev/tool/generate.js +0 -28
- package/dist/commands/dev/tool/index.d.ts +0 -2
- package/dist/commands/dev/tool/index.js +0 -14
- package/dist/commands/dev/tool/init.d.ts +0 -2
- package/dist/commands/dev/tool/init.js +0 -320
- package/dist/commands/dev/tool/shared.d.ts +0 -5
- package/dist/commands/dev/tool/shared.js +0 -256
- package/dist/commands/dev/tool/status.d.ts +0 -2
- package/dist/commands/dev/tool/status.js +0 -136
- package/dist/commands/dev/tool-generate.spec.d.ts +0 -1
- package/dist/commands/dev/tool-generate.spec.js +0 -163
- package/dist/commands/dev/tool.d.ts +0 -2
- package/dist/commands/dev/tool.js +0 -559
- package/dist/commands/dev/tool.spec.d.ts +0 -1
- package/dist/commands/dev/tool.spec.js +0 -48
- package/dist/commands/docs/index.d.ts +0 -4
- package/dist/commands/docs/index.js +0 -18
- package/dist/commands/install/index.d.ts +0 -8
- package/dist/commands/install/index.js +0 -300
- package/dist/commands/install/index.spec.d.ts +0 -1
- package/dist/commands/install/index.spec.js +0 -143
- package/dist/commands/install.d.ts +0 -3
- package/dist/commands/install.js +0 -147
- package/dist/commands/models/create.d.ts +0 -1
- package/dist/commands/models/create.js +0 -213
- package/dist/commands/models/create.spec.d.ts +0 -1
- package/dist/commands/models/create.spec.js +0 -125
- package/dist/commands/models/index.d.ts +0 -3
- package/dist/commands/models/index.js +0 -60
- package/dist/commands/models/index.spec.d.ts +0 -1
- package/dist/commands/models/index.spec.js +0 -76
- package/dist/commands/models/selector.d.ts +0 -8
- package/dist/commands/models/selector.js +0 -53
- package/dist/commands/query/index.d.ts +0 -3
- package/dist/commands/query/index.js +0 -131
- package/dist/commands/routes/index.d.ts +0 -3
- package/dist/commands/routes/index.js +0 -93
- package/dist/commands/routes.d.ts +0 -2
- package/dist/commands/routes.js +0 -101
- package/dist/commands/status/index.d.ts +0 -4
- package/dist/commands/status/index.js +0 -262
- package/dist/commands/status.d.ts +0 -3
- package/dist/commands/status.js +0 -33
- package/dist/commands/targets/index.d.ts +0 -3
- package/dist/commands/targets/index.js +0 -65
- package/dist/commands/targets/index.spec.d.ts +0 -1
- package/dist/commands/targets/index.spec.js +0 -105
- package/dist/commands/targets.d.ts +0 -2
- package/dist/commands/targets.js +0 -65
- package/dist/commands/teams/index.d.ts +0 -3
- package/dist/commands/teams/index.js +0 -49
- package/dist/commands/teams/index.spec.d.ts +0 -1
- package/dist/commands/teams/index.spec.js +0 -70
- package/dist/commands/teams/selector.d.ts +0 -8
- package/dist/commands/teams/selector.js +0 -55
- package/dist/commands/tools/index.d.ts +0 -3
- package/dist/commands/tools/index.js +0 -49
- package/dist/commands/tools/index.spec.d.ts +0 -1
- package/dist/commands/tools/index.spec.js +0 -70
- package/dist/commands/tools/selector.d.ts +0 -8
- package/dist/commands/tools/selector.js +0 -53
- package/dist/commands/uninstall/index.d.ts +0 -3
- package/dist/commands/uninstall/index.js +0 -106
- package/dist/commands/uninstall/index.spec.d.ts +0 -1
- package/dist/commands/uninstall/index.spec.js +0 -125
- package/dist/commands/uninstall.d.ts +0 -2
- package/dist/commands/uninstall.js +0 -83
- package/dist/components/ChatUI.d.ts +0 -16
- package/dist/components/ChatUI.js +0 -801
- package/dist/components/StatusView.d.ts +0 -10
- package/dist/components/StatusView.js +0 -39
- package/dist/lib/arkApiClient.d.ts +0 -53
- package/dist/lib/arkApiClient.js +0 -102
- package/dist/lib/arkApiProxy.d.ts +0 -9
- package/dist/lib/arkApiProxy.js +0 -22
- package/dist/lib/arkServiceProxy.d.ts +0 -14
- package/dist/lib/arkServiceProxy.js +0 -95
- package/dist/lib/arkStatus.d.ts +0 -10
- package/dist/lib/arkStatus.js +0 -79
- package/dist/lib/arkStatus.spec.d.ts +0 -1
- package/dist/lib/arkStatus.spec.js +0 -49
- package/dist/lib/chatClient.d.ts +0 -33
- package/dist/lib/chatClient.js +0 -99
- package/dist/lib/cluster.spec.d.ts +0 -1
- package/dist/lib/cluster.spec.js +0 -338
- package/dist/lib/commandUtils.d.ts +0 -4
- package/dist/lib/commandUtils.js +0 -18
- package/dist/lib/commandUtils.test.d.ts +0 -1
- package/dist/lib/commandUtils.test.js +0 -44
- package/dist/lib/commands.d.ts +0 -16
- package/dist/lib/commands.js +0 -29
- package/dist/lib/commands.spec.d.ts +0 -1
- package/dist/lib/commands.spec.js +0 -146
- package/dist/lib/config.spec.d.ts +0 -1
- package/dist/lib/config.spec.js +0 -99
- package/dist/lib/config.test.d.ts +0 -1
- package/dist/lib/config.test.js +0 -93
- package/dist/lib/consts.spec.d.ts +0 -1
- package/dist/lib/consts.spec.js +0 -15
- package/dist/lib/dev/tools/analyzer.d.ts +0 -30
- package/dist/lib/dev/tools/analyzer.js +0 -190
- package/dist/lib/dev/tools/discover_tools.py +0 -392
- package/dist/lib/dev/tools/mcp-types.d.ts +0 -28
- package/dist/lib/dev/tools/mcp-types.js +0 -86
- package/dist/lib/dev/tools/types.d.ts +0 -50
- package/dist/lib/dev/tools/types.js +0 -1
- package/dist/lib/errors.spec.d.ts +0 -1
- package/dist/lib/errors.spec.js +0 -221
- package/dist/lib/nextSteps.d.ts +0 -4
- package/dist/lib/nextSteps.js +0 -20
- package/dist/lib/nextSteps.spec.d.ts +0 -1
- package/dist/lib/nextSteps.spec.js +0 -59
- package/dist/lib/output.d.ts +0 -36
- package/dist/lib/output.js +0 -89
- package/dist/lib/output.spec.d.ts +0 -1
- package/dist/lib/output.spec.js +0 -123
- package/dist/lib/portUtils.d.ts +0 -8
- package/dist/lib/portUtils.js +0 -39
- package/dist/lib/startup.d.ts +0 -9
- package/dist/lib/startup.js +0 -93
- package/dist/lib/startup.spec.d.ts +0 -1
- package/dist/lib/startup.spec.js +0 -168
- package/dist/types/types.d.ts +0 -40
- package/dist/types/types.js +0 -1
- package/dist/ui/AgentSelector.d.ts +0 -8
- package/dist/ui/AgentSelector.js +0 -53
- package/dist/ui/ModelSelector.d.ts +0 -8
- package/dist/ui/ModelSelector.js +0 -53
- package/dist/ui/TeamSelector.d.ts +0 -8
- package/dist/ui/TeamSelector.js +0 -55
- package/dist/ui/ToolSelector.d.ts +0 -8
- package/dist/ui/ToolSelector.js +0 -53
- package/dist/ui/statusFormatter.spec.d.ts +0 -1
- package/dist/ui/statusFormatter.spec.js +0 -58
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import { KubernetesConfigManager } from '../lib/kubernetes.js';
|
|
4
|
+
import * as k8s from '@kubernetes/client-node';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
const execAsync = promisify(exec);
|
|
5
7
|
export const getNodeVersion = () => ({
|
|
6
8
|
command: 'node',
|
|
7
9
|
versionArgs: '--version',
|
|
@@ -38,20 +40,6 @@ export const getHelmVersion = () => ({
|
|
|
38
40
|
versionArgs: 'version --short',
|
|
39
41
|
versionExtract: (output) => output.trim(),
|
|
40
42
|
});
|
|
41
|
-
export const getMinikubeVersion = () => ({
|
|
42
|
-
command: 'minikube',
|
|
43
|
-
versionArgs: 'version --short',
|
|
44
|
-
versionExtract: (output) => output.trim(),
|
|
45
|
-
});
|
|
46
|
-
export const getKindVersion = () => ({
|
|
47
|
-
command: 'kind',
|
|
48
|
-
versionArgs: 'version',
|
|
49
|
-
versionExtract: (output) => {
|
|
50
|
-
// kind version output is like "kind v0.20.0 go1.21.0 linux/amd64"
|
|
51
|
-
const match = output.match(/kind (v[\d.]+)/);
|
|
52
|
-
return match ? match[1] : output.trim();
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
43
|
function createErrorServiceStatus(name, url, error, defaultStatus = 'unhealthy', defaultDetails) {
|
|
56
44
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
57
45
|
return {
|
|
@@ -62,13 +50,32 @@ function createErrorServiceStatus(name, url, error, defaultStatus = 'unhealthy',
|
|
|
62
50
|
};
|
|
63
51
|
}
|
|
64
52
|
export class StatusChecker {
|
|
53
|
+
constructor(arkClient) {
|
|
54
|
+
this.arkClient = arkClient;
|
|
55
|
+
this.kubernetesManager = new KubernetesConfigManager();
|
|
56
|
+
}
|
|
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
|
+
}
|
|
65
72
|
/**
|
|
66
73
|
* Get version of a command
|
|
67
74
|
*/
|
|
68
75
|
async getCommandVersion(config) {
|
|
69
76
|
try {
|
|
70
|
-
const
|
|
71
|
-
const { stdout } = await
|
|
77
|
+
const cmd = `${config.command} ${config.versionArgs}`;
|
|
78
|
+
const { stdout } = await execAsync(cmd);
|
|
72
79
|
return config.versionExtract(stdout);
|
|
73
80
|
}
|
|
74
81
|
catch (error) {
|
|
@@ -76,219 +83,91 @@ export class StatusChecker {
|
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
85
|
/**
|
|
79
|
-
* Check
|
|
80
|
-
* Gets health from deployment, version/revision from Helm
|
|
86
|
+
* Check health of a service by URL
|
|
81
87
|
*/
|
|
82
|
-
async
|
|
83
|
-
|
|
84
|
-
const deploymentStatus = await this.checkDeploymentStatus(serviceName, deploymentName, namespace, devDeploymentName);
|
|
85
|
-
// Try to get version info from Helm if it's a healthy deployment
|
|
86
|
-
if (deploymentStatus.status === 'healthy' ||
|
|
87
|
-
deploymentStatus.status === 'warning') {
|
|
88
|
-
try {
|
|
89
|
-
const { stdout } = await execa('helm', ['list', '-n', namespace, '-o', 'json'], { timeout: 5000 });
|
|
90
|
-
const releases = JSON.parse(stdout);
|
|
91
|
-
const release = releases.find((r) => r.name === helmReleaseName);
|
|
92
|
-
if (release) {
|
|
93
|
-
// Merge Helm version info into deployment status
|
|
94
|
-
return {
|
|
95
|
-
...deploymentStatus,
|
|
96
|
-
version: release.app_version,
|
|
97
|
-
revision: release.revision,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
// If Helm check fails, return deployment status as-is
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return deploymentStatus;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Check deployment status
|
|
109
|
-
*/
|
|
110
|
-
async checkDeploymentStatus(serviceName, deploymentName, namespace, devDeploymentName) {
|
|
88
|
+
async checkServiceHealth(serviceName, serviceUrl, successMessage, healthPath = '') {
|
|
89
|
+
const fullUrl = `${serviceUrl}${healthPath}`;
|
|
111
90
|
try {
|
|
112
|
-
|
|
113
|
-
'get',
|
|
114
|
-
'deployment',
|
|
115
|
-
deploymentName,
|
|
116
|
-
'--namespace',
|
|
117
|
-
namespace,
|
|
118
|
-
'-o',
|
|
119
|
-
'json',
|
|
120
|
-
]);
|
|
121
|
-
const deployment = JSON.parse(stdout);
|
|
122
|
-
const replicas = deployment.spec?.replicas || 0;
|
|
123
|
-
const readyReplicas = deployment.status?.readyReplicas || 0;
|
|
124
|
-
const availableReplicas = deployment.status?.availableReplicas || 0;
|
|
125
|
-
// Check Kubernetes 'Available' condition - only 'available' deployments are healthy
|
|
126
|
-
const availableCondition = deployment.status?.conditions?.find((condition) => condition.type === 'Available');
|
|
127
|
-
const isAvailable = availableCondition?.status === 'True';
|
|
128
|
-
const allReplicasReady = readyReplicas === replicas && availableReplicas === replicas;
|
|
129
|
-
// Determine status: not ready if 0 replicas, healthy if available and all ready, warning otherwise
|
|
130
|
-
let status;
|
|
131
|
-
if (replicas === 0 || readyReplicas === 0) {
|
|
132
|
-
status = 'not ready';
|
|
133
|
-
}
|
|
134
|
-
else if (isAvailable && allReplicasReady) {
|
|
135
|
-
status = 'healthy';
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
status = 'warning';
|
|
139
|
-
}
|
|
140
|
-
// If main deployment has 0 replicas and we have a dev deployment, check it
|
|
141
|
-
if (replicas === 0 && devDeploymentName) {
|
|
142
|
-
try {
|
|
143
|
-
const { stdout: devStdout } = await execa('kubectl', [
|
|
144
|
-
'get',
|
|
145
|
-
'deployment',
|
|
146
|
-
devDeploymentName,
|
|
147
|
-
'--namespace',
|
|
148
|
-
namespace,
|
|
149
|
-
'-o',
|
|
150
|
-
'json',
|
|
151
|
-
]);
|
|
152
|
-
const devDeployment = JSON.parse(devStdout);
|
|
153
|
-
const devReplicas = devDeployment.spec?.replicas || 0;
|
|
154
|
-
const devReadyReplicas = devDeployment.status?.readyReplicas || 0;
|
|
155
|
-
const devAvailableReplicas = devDeployment.status?.availableReplicas || 0;
|
|
156
|
-
if (devReplicas > 0) {
|
|
157
|
-
const devAvailableCondition = devDeployment.status?.conditions?.find((condition) => condition.type === 'Available');
|
|
158
|
-
const devIsAvailable = devAvailableCondition?.status === 'True';
|
|
159
|
-
const devAllReplicasReady = devReadyReplicas === devReplicas &&
|
|
160
|
-
devAvailableReplicas === devReplicas;
|
|
161
|
-
let devStatus;
|
|
162
|
-
if (devReplicas === 0 || devReadyReplicas === 0) {
|
|
163
|
-
devStatus = 'not ready';
|
|
164
|
-
}
|
|
165
|
-
else if (devIsAvailable && devAllReplicasReady) {
|
|
166
|
-
devStatus = 'healthy';
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
devStatus = 'warning';
|
|
170
|
-
}
|
|
171
|
-
return {
|
|
172
|
-
name: serviceName,
|
|
173
|
-
status: devStatus,
|
|
174
|
-
details: `${devReadyReplicas}/${devReplicas} replicas ready`,
|
|
175
|
-
isDev: true,
|
|
176
|
-
namespace,
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
// If dev deployment check fails, return the original status
|
|
182
|
-
}
|
|
183
|
-
}
|
|
91
|
+
await axios.get(fullUrl, { timeout: 5000 });
|
|
184
92
|
return {
|
|
185
93
|
name: serviceName,
|
|
186
|
-
status,
|
|
187
|
-
|
|
188
|
-
|
|
94
|
+
status: 'healthy',
|
|
95
|
+
url: serviceUrl,
|
|
96
|
+
details: successMessage,
|
|
189
97
|
};
|
|
190
98
|
}
|
|
191
99
|
catch (error) {
|
|
192
|
-
|
|
193
|
-
// If main deployment not found or not healthy, try dev deployment
|
|
194
|
-
if (errorMessage.includes('not found') ||
|
|
195
|
-
errorMessage.includes('NotFound')) {
|
|
196
|
-
if (devDeploymentName) {
|
|
197
|
-
try {
|
|
198
|
-
const { stdout } = await execa('kubectl', [
|
|
199
|
-
'get',
|
|
200
|
-
'deployment',
|
|
201
|
-
devDeploymentName,
|
|
202
|
-
'--namespace',
|
|
203
|
-
namespace,
|
|
204
|
-
'-o',
|
|
205
|
-
'json',
|
|
206
|
-
]);
|
|
207
|
-
const devDeployment = JSON.parse(stdout);
|
|
208
|
-
const replicas = devDeployment.spec?.replicas || 0;
|
|
209
|
-
const readyReplicas = devDeployment.status?.readyReplicas || 0;
|
|
210
|
-
const availableReplicas = devDeployment.status?.availableReplicas || 0;
|
|
211
|
-
const availableCondition = devDeployment.status?.conditions?.find((condition) => condition.type === 'Available');
|
|
212
|
-
const isAvailable = availableCondition?.status === 'True';
|
|
213
|
-
const allReplicasReady = readyReplicas === replicas && availableReplicas === replicas;
|
|
214
|
-
let status;
|
|
215
|
-
if (replicas === 0 || readyReplicas === 0) {
|
|
216
|
-
status = 'not ready';
|
|
217
|
-
}
|
|
218
|
-
else if (isAvailable && allReplicasReady) {
|
|
219
|
-
status = 'healthy';
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
status = 'warning';
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
name: serviceName,
|
|
226
|
-
status,
|
|
227
|
-
details: `${readyReplicas}/${replicas} replicas ready`,
|
|
228
|
-
isDev: true,
|
|
229
|
-
namespace,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
// If dev deployment also not found, return not installed
|
|
234
|
-
return {
|
|
235
|
-
name: serviceName,
|
|
236
|
-
status: 'not installed',
|
|
237
|
-
details: `Deployment '${deploymentName}' not found`,
|
|
238
|
-
namespace,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
name: serviceName,
|
|
244
|
-
status: 'not installed',
|
|
245
|
-
details: `Deployment '${deploymentName}' not found`,
|
|
246
|
-
namespace,
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
return createErrorServiceStatus(serviceName, '', error, 'unhealthy', `Failed to check deployment: ${errorMessage}`);
|
|
100
|
+
return createErrorServiceStatus(serviceName, serviceUrl, error, 'unhealthy', `${serviceName} is not running or not accessible`);
|
|
250
101
|
}
|
|
251
102
|
}
|
|
252
103
|
/**
|
|
253
|
-
* Check
|
|
104
|
+
* Check if ark-api is running and healthy
|
|
254
105
|
*/
|
|
255
|
-
async
|
|
106
|
+
async checkArkApi(customUrl) {
|
|
107
|
+
const url = customUrl || this.arkClient.getBaseURL();
|
|
108
|
+
return this.checkServiceHealth('ark-api', url, 'ARK API is running', '/health');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Return a "not installed" status for a service
|
|
112
|
+
*/
|
|
113
|
+
createNotInstalledStatus(serviceName) {
|
|
114
|
+
return {
|
|
115
|
+
name: serviceName,
|
|
116
|
+
status: 'not installed',
|
|
117
|
+
details: `${serviceName} is not configured or not part of this deployment`,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check Kubernetes service health via pods and endpoints
|
|
122
|
+
*/
|
|
123
|
+
async checkKubernetesService(serviceName, kubernetesServiceName, namespace = 'default') {
|
|
256
124
|
try {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
125
|
+
await this.kubernetesManager.initializeConfig();
|
|
126
|
+
const kc = this.kubernetesManager.getKubeConfig();
|
|
127
|
+
const k8sApi = kc.makeApiClient(k8s.CoreV1Api);
|
|
128
|
+
// Check if service exists and has endpoints
|
|
129
|
+
const service = await k8sApi.readNamespacedService({
|
|
130
|
+
name: kubernetesServiceName,
|
|
131
|
+
namespace,
|
|
132
|
+
});
|
|
133
|
+
const endpoints = await k8sApi.readNamespacedEndpoints({
|
|
134
|
+
name: kubernetesServiceName,
|
|
262
135
|
namespace,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
136
|
+
});
|
|
137
|
+
// Check if service has ready endpoints
|
|
138
|
+
const readyAddresses = endpoints.subsets?.reduce((total, subset) => {
|
|
139
|
+
return total + (subset.addresses?.length || 0);
|
|
140
|
+
}, 0) || 0;
|
|
141
|
+
if (readyAddresses > 0) {
|
|
142
|
+
const serviceIP = service.spec?.clusterIP;
|
|
143
|
+
const servicePort = service.spec?.ports?.[0]?.port;
|
|
268
144
|
return {
|
|
269
145
|
name: serviceName,
|
|
270
|
-
status: '
|
|
271
|
-
|
|
272
|
-
|
|
146
|
+
status: 'healthy',
|
|
147
|
+
url: `cluster://${serviceIP}:${servicePort}`,
|
|
148
|
+
details: `${serviceName} running in cluster (${readyAddresses} ready endpoints)`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
return {
|
|
153
|
+
name: serviceName,
|
|
154
|
+
status: 'unhealthy',
|
|
155
|
+
details: `${serviceName} service exists but has no ready endpoints`,
|
|
273
156
|
};
|
|
274
157
|
}
|
|
275
|
-
const release = helmList[0];
|
|
276
|
-
const status = release.status?.toLowerCase() || 'unknown';
|
|
277
|
-
const revision = release.revision || 'unknown';
|
|
278
|
-
const appVersion = release.app_version || 'unknown';
|
|
279
|
-
const isHealthy = status === 'deployed';
|
|
280
|
-
return {
|
|
281
|
-
name: serviceName,
|
|
282
|
-
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
283
|
-
version: appVersion,
|
|
284
|
-
revision: revision,
|
|
285
|
-
details: `Status: ${status}`,
|
|
286
|
-
namespace,
|
|
287
|
-
};
|
|
288
158
|
}
|
|
289
159
|
catch (error) {
|
|
290
160
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
291
|
-
|
|
161
|
+
// If service not found, it's not installed
|
|
162
|
+
if (errorMessage.includes('not found')) {
|
|
163
|
+
return this.createNotInstalledStatus(serviceName);
|
|
164
|
+
}
|
|
165
|
+
// Other errors indicate unhealthy
|
|
166
|
+
return {
|
|
167
|
+
name: serviceName,
|
|
168
|
+
status: 'unhealthy',
|
|
169
|
+
details: `Failed to check ${serviceName}: ${errorMessage}`,
|
|
170
|
+
};
|
|
292
171
|
}
|
|
293
172
|
}
|
|
294
173
|
/**
|
|
@@ -301,13 +180,10 @@ export class StatusChecker {
|
|
|
301
180
|
{ name: 'kubectl', ...getKubectlVersion() },
|
|
302
181
|
{ name: 'docker', ...getDockerVersion() },
|
|
303
182
|
{ name: 'helm', ...getHelmVersion() },
|
|
304
|
-
{ name: 'minikube', ...getMinikubeVersion() },
|
|
305
|
-
{ name: 'kind', ...getKindVersion() },
|
|
306
183
|
];
|
|
307
184
|
const results = [];
|
|
308
185
|
for (const dep of dependencies) {
|
|
309
|
-
const
|
|
310
|
-
const installed = await checkCommandExists(dep.command, args);
|
|
186
|
+
const installed = await this.isCommandAvailable(dep.command);
|
|
311
187
|
const version = installed
|
|
312
188
|
? await this.getCommandVersion({
|
|
313
189
|
command: dep.command,
|
|
@@ -329,89 +205,47 @@ export class StatusChecker {
|
|
|
329
205
|
/**
|
|
330
206
|
* Run all checks and return results
|
|
331
207
|
*/
|
|
332
|
-
async checkAll() {
|
|
333
|
-
//
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
try {
|
|
338
|
-
await execa('kubectl', ['get', 'namespaces', '-o', 'name'], {
|
|
339
|
-
timeout: 5000,
|
|
340
|
-
});
|
|
341
|
-
clusterAccess = true;
|
|
208
|
+
async checkAll(serviceUrls = {}, arkApiUrl) {
|
|
209
|
+
// Always check ark-api if provided
|
|
210
|
+
const serviceChecks = [];
|
|
211
|
+
if (arkApiUrl) {
|
|
212
|
+
serviceChecks.push(this.checkArkApi(arkApiUrl));
|
|
342
213
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (clusterAccess) {
|
|
349
|
-
const { getClusterInfo } = await import('../lib/cluster.js');
|
|
350
|
-
clusterInfo = await getClusterInfo();
|
|
351
|
-
}
|
|
352
|
-
let services = [];
|
|
353
|
-
// Only check ARK services if we have cluster access
|
|
354
|
-
if (clusterAccess) {
|
|
355
|
-
const serviceChecks = [];
|
|
356
|
-
for (const [serviceName, service] of Object.entries(arkServices)) {
|
|
357
|
-
// Skip disabled services
|
|
358
|
-
if (!service.enabled)
|
|
359
|
-
continue;
|
|
360
|
-
// Use service namespace if defined, otherwise use current namespace from clusterInfo
|
|
361
|
-
const namespace = service.namespace || clusterInfo?.namespace || 'default';
|
|
362
|
-
if (service.k8sDeploymentName) {
|
|
363
|
-
// For deployments, get health from deployment and version from Helm
|
|
364
|
-
serviceChecks.push(this.checkCombinedStatus(serviceName, service.k8sDeploymentName, service.helmReleaseName, namespace, service.k8sDevDeploymentName));
|
|
365
|
-
}
|
|
366
|
-
else {
|
|
367
|
-
serviceChecks.push(this.checkHelmStatus(serviceName, service.helmReleaseName, namespace));
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
services = await Promise.all(serviceChecks);
|
|
371
|
-
}
|
|
372
|
-
// Check if ARK is ready (controller is running)
|
|
373
|
-
let arkReady = false;
|
|
374
|
-
let defaultModelExists = false;
|
|
375
|
-
let defaultModel;
|
|
376
|
-
if (clusterAccess) {
|
|
377
|
-
arkReady = await isArkReady();
|
|
378
|
-
// Check for default model with detailed status
|
|
379
|
-
if (arkReady) {
|
|
380
|
-
try {
|
|
381
|
-
const { stdout } = await execa('kubectl', [
|
|
382
|
-
'get',
|
|
383
|
-
'model',
|
|
384
|
-
'default',
|
|
385
|
-
'-o',
|
|
386
|
-
'json',
|
|
387
|
-
]);
|
|
388
|
-
const model = JSON.parse(stdout);
|
|
389
|
-
defaultModelExists = true;
|
|
390
|
-
// Extract model details
|
|
391
|
-
const available = model.status?.conditions?.find((c) => c.type === 'Available')?.status === 'True';
|
|
392
|
-
defaultModel = {
|
|
393
|
-
exists: true,
|
|
394
|
-
available,
|
|
395
|
-
provider: model.spec?.provider,
|
|
396
|
-
details: model.spec?.model || model.spec?.apiEndpoint,
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
catch {
|
|
400
|
-
defaultModelExists = false;
|
|
401
|
-
defaultModel = {
|
|
402
|
-
exists: false,
|
|
403
|
-
};
|
|
404
|
-
}
|
|
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;
|
|
405
219
|
}
|
|
220
|
+
serviceChecks.push(this.checkServiceHealth(serviceName, serviceUrl, `${serviceName} is running`, this.getHealthPath(serviceName)));
|
|
406
221
|
}
|
|
222
|
+
// Always check dependencies
|
|
223
|
+
const dependenciesCheck = this.checkDependencies();
|
|
224
|
+
const [dependencies, ...serviceStatuses] = await Promise.all([
|
|
225
|
+
dependenciesCheck,
|
|
226
|
+
...serviceChecks,
|
|
227
|
+
]);
|
|
407
228
|
return {
|
|
408
|
-
services,
|
|
229
|
+
services: serviceStatuses,
|
|
409
230
|
dependencies,
|
|
410
|
-
clusterAccess,
|
|
411
|
-
clusterInfo,
|
|
412
|
-
arkReady,
|
|
413
|
-
defaultModelExists,
|
|
414
|
-
defaultModel,
|
|
415
231
|
};
|
|
416
232
|
}
|
|
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
|
+
}
|
|
417
251
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
import { ArkConfig, KubernetesConfig } from './lib/types.js';
|
|
1
2
|
/**
|
|
2
|
-
* ConfigManager handles
|
|
3
|
-
* Complex discovery logic can be debugged by
|
|
3
|
+
* ConfigManager handles ARK CLI configuration with automatic service discovery
|
|
4
|
+
* and multiple fallback mechanisms. Complex discovery logic can be debugged by
|
|
5
|
+
* setting DEBUG=ark:config or DEBUG=ark:* environment variable.
|
|
4
6
|
*
|
|
5
7
|
* Example usage:
|
|
6
|
-
* DEBUG=ark:config ark status
|
|
8
|
+
* DEBUG=ark:config ark check status
|
|
9
|
+
* DEBUG=ark:* ark dashboard
|
|
7
10
|
*/
|
|
8
11
|
export declare class ConfigManager {
|
|
12
|
+
private configDir;
|
|
13
|
+
private configFile;
|
|
9
14
|
private kubernetesManager;
|
|
15
|
+
private gatewayManager;
|
|
10
16
|
private kubeConfig;
|
|
11
17
|
constructor();
|
|
18
|
+
ensureConfigDir(): Promise<void>;
|
|
19
|
+
loadConfig(): Promise<ArkConfig>;
|
|
20
|
+
saveConfig(config: ArkConfig): Promise<void>;
|
|
21
|
+
updateConfig(updates: Partial<ArkConfig>): Promise<ArkConfig>;
|
|
22
|
+
private getDefaultConfig;
|
|
23
|
+
initializeConfig(): Promise<ArkConfig>;
|
|
24
|
+
getConfigPath(): string;
|
|
12
25
|
getApiBaseUrl(): Promise<string>;
|
|
13
26
|
/**
|
|
14
27
|
* Check if localhost-gateway is running by testing port 8080
|
|
@@ -19,5 +32,11 @@ export declare class ConfigManager {
|
|
|
19
32
|
*/
|
|
20
33
|
private getLocalhostGatewayUrls;
|
|
21
34
|
private initKubernetesConfig;
|
|
35
|
+
getKubernetesConfig(): Promise<KubernetesConfig | null>;
|
|
22
36
|
testClusterAccess(): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Discover service URLs from ark-api service discovery
|
|
39
|
+
*/
|
|
40
|
+
private discoverServicesFromApi;
|
|
41
|
+
getServiceUrls(): Promise<Record<string, string>>;
|
|
23
42
|
}
|