@agents-at-scale/ark 0.1.35 → 0.1.36
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/arkServices.d.ts +42 -0
- package/dist/arkServices.js +138 -0
- package/dist/arkServices.spec.d.ts +1 -0
- package/dist/arkServices.spec.js +24 -0
- package/dist/commands/agents/index.d.ts +3 -0
- package/dist/commands/agents/index.js +65 -0
- package/dist/commands/agents/index.spec.d.ts +1 -0
- package/dist/commands/agents/index.spec.js +67 -0
- package/dist/commands/chat/index.d.ts +3 -0
- package/dist/commands/chat/index.js +29 -0
- package/dist/commands/cluster/get.d.ts +2 -0
- package/dist/commands/cluster/get.js +39 -0
- package/dist/commands/cluster/get.spec.d.ts +1 -0
- package/dist/commands/cluster/get.spec.js +92 -0
- package/dist/commands/cluster/index.d.ts +2 -1
- package/dist/commands/cluster/index.js +3 -5
- package/dist/commands/cluster/index.spec.d.ts +1 -0
- package/dist/commands/cluster/index.spec.js +24 -0
- package/dist/commands/completion/index.d.ts +3 -0
- package/dist/commands/completion/index.js +230 -0
- package/dist/commands/completion/index.spec.d.ts +1 -0
- package/dist/commands/completion/index.spec.js +34 -0
- package/dist/commands/config/index.d.ts +3 -0
- package/dist/commands/config/index.js +42 -0
- package/dist/commands/config/index.spec.d.ts +1 -0
- package/dist/commands/config/index.spec.js +78 -0
- package/dist/commands/dashboard/index.d.ts +4 -0
- package/dist/commands/dashboard/index.js +39 -0
- package/dist/commands/docs/index.d.ts +4 -0
- package/dist/commands/docs/index.js +18 -0
- package/dist/commands/generate/config.js +5 -24
- package/dist/commands/generate/generators/mcpserver.d.ts +2 -1
- package/dist/commands/generate/generators/mcpserver.js +26 -5
- package/dist/commands/generate/generators/project.js +22 -41
- package/dist/commands/generate/index.d.ts +2 -1
- package/dist/commands/generate/index.js +1 -1
- package/dist/commands/install/index.d.ts +8 -0
- package/dist/commands/install/index.js +295 -0
- package/dist/commands/install/index.spec.d.ts +1 -0
- package/dist/commands/install/index.spec.js +143 -0
- package/dist/commands/models/create.d.ts +1 -0
- package/dist/commands/models/create.js +213 -0
- package/dist/commands/models/create.spec.d.ts +1 -0
- package/dist/commands/models/create.spec.js +125 -0
- package/dist/commands/models/index.d.ts +3 -0
- package/dist/commands/models/index.js +75 -0
- package/dist/commands/models/index.spec.d.ts +1 -0
- package/dist/commands/models/index.spec.js +96 -0
- package/dist/commands/query/index.d.ts +3 -0
- package/dist/commands/query/index.js +24 -0
- package/dist/commands/query/index.spec.d.ts +1 -0
- package/dist/commands/query/index.spec.js +53 -0
- package/dist/commands/routes/index.d.ts +3 -0
- package/dist/commands/routes/index.js +93 -0
- package/dist/commands/status/index.d.ts +3 -0
- package/dist/commands/status/index.js +281 -0
- package/dist/commands/targets/index.d.ts +3 -0
- package/dist/commands/targets/index.js +72 -0
- package/dist/commands/targets/index.spec.d.ts +1 -0
- package/dist/commands/targets/index.spec.js +154 -0
- package/dist/commands/teams/index.d.ts +3 -0
- package/dist/commands/teams/index.js +64 -0
- package/dist/commands/teams/index.spec.d.ts +1 -0
- package/dist/commands/teams/index.spec.js +70 -0
- package/dist/commands/tools/index.d.ts +3 -0
- package/dist/commands/tools/index.js +49 -0
- package/dist/commands/tools/index.spec.d.ts +1 -0
- package/dist/commands/tools/index.spec.js +70 -0
- package/dist/commands/uninstall/index.d.ts +3 -0
- package/dist/commands/uninstall/index.js +101 -0
- package/dist/commands/uninstall/index.spec.d.ts +1 -0
- package/dist/commands/uninstall/index.spec.js +125 -0
- package/dist/components/ChatUI.d.ts +16 -0
- package/dist/components/ChatUI.js +801 -0
- package/dist/components/statusChecker.d.ts +14 -24
- package/dist/components/statusChecker.js +295 -129
- package/dist/index.d.ts +1 -1
- package/dist/index.js +42 -42
- package/dist/lib/arkApiClient.d.ts +53 -0
- package/dist/lib/arkApiClient.js +102 -0
- package/dist/lib/arkApiProxy.d.ts +9 -0
- package/dist/lib/arkApiProxy.js +22 -0
- package/dist/lib/arkServiceProxy.d.ts +14 -0
- package/dist/lib/arkServiceProxy.js +95 -0
- package/dist/lib/arkStatus.d.ts +10 -0
- package/dist/lib/arkStatus.js +79 -0
- package/dist/lib/arkStatus.spec.d.ts +1 -0
- package/dist/lib/arkStatus.spec.js +49 -0
- package/dist/lib/chatClient.d.ts +33 -0
- package/dist/lib/chatClient.js +93 -0
- package/dist/lib/cluster.d.ts +2 -1
- package/dist/lib/cluster.js +37 -16
- package/dist/lib/cluster.spec.d.ts +1 -0
- package/dist/lib/cluster.spec.js +338 -0
- package/dist/lib/commands.d.ts +16 -0
- package/dist/lib/commands.js +29 -0
- package/dist/lib/commands.spec.d.ts +1 -0
- package/dist/lib/commands.spec.js +146 -0
- package/dist/lib/config.d.ts +26 -80
- package/dist/lib/config.js +70 -205
- package/dist/lib/config.spec.d.ts +1 -0
- package/dist/lib/config.spec.js +99 -0
- package/dist/lib/errors.js +1 -1
- package/dist/lib/errors.spec.d.ts +1 -0
- package/dist/lib/errors.spec.js +221 -0
- package/dist/lib/executeQuery.d.ts +20 -0
- package/dist/lib/executeQuery.js +135 -0
- package/dist/lib/executeQuery.spec.d.ts +1 -0
- package/dist/lib/executeQuery.spec.js +170 -0
- package/dist/lib/nextSteps.d.ts +4 -0
- package/dist/lib/nextSteps.js +20 -0
- package/dist/lib/nextSteps.spec.d.ts +1 -0
- package/dist/lib/nextSteps.spec.js +59 -0
- package/dist/lib/output.d.ts +36 -0
- package/dist/lib/output.js +89 -0
- package/dist/lib/output.spec.d.ts +1 -0
- package/dist/lib/output.spec.js +123 -0
- package/dist/lib/startup.d.ts +9 -0
- package/dist/lib/startup.js +87 -0
- package/dist/lib/startup.spec.d.ts +1 -0
- package/dist/lib/startup.spec.js +152 -0
- package/dist/lib/types.d.ts +87 -3
- package/dist/lib/versions.d.ts +23 -0
- package/dist/lib/versions.js +51 -0
- package/dist/types/types.d.ts +40 -0
- package/dist/types/types.js +1 -0
- package/dist/ui/AgentSelector.d.ts +8 -0
- package/dist/ui/AgentSelector.js +53 -0
- package/dist/ui/MainMenu.d.ts +5 -1
- package/dist/ui/MainMenu.js +226 -91
- package/dist/ui/ModelSelector.d.ts +8 -0
- package/dist/ui/ModelSelector.js +53 -0
- package/dist/ui/TeamSelector.d.ts +8 -0
- package/dist/ui/TeamSelector.js +55 -0
- package/dist/ui/ToolSelector.d.ts +8 -0
- package/dist/ui/ToolSelector.js +53 -0
- package/dist/ui/statusFormatter.d.ts +22 -7
- package/dist/ui/statusFormatter.js +39 -39
- package/dist/ui/statusFormatter.spec.d.ts +1 -0
- package/dist/ui/statusFormatter.spec.js +58 -0
- package/package.json +16 -5
- package/dist/commands/cluster/get-ip.d.ts +0 -2
- package/dist/commands/cluster/get-ip.js +0 -32
- package/dist/commands/cluster/get-type.d.ts +0 -2
- package/dist/commands/cluster/get-type.js +0 -26
- package/dist/commands/completion.d.ts +0 -2
- package/dist/commands/completion.js +0 -108
- package/dist/commands/config.d.ts +0 -5
- package/dist/commands/config.js +0 -327
- package/dist/components/DashboardCLI.d.ts +0 -3
- package/dist/components/DashboardCLI.js +0 -149
- package/dist/config.d.ts +0 -42
- package/dist/config.js +0 -243
- package/dist/lib/arkClient.d.ts +0 -32
- package/dist/lib/arkClient.js +0 -43
- package/dist/lib/consts.d.ts +0 -10
- package/dist/lib/consts.js +0 -15
- package/dist/lib/exec.d.ts +0 -5
- package/dist/lib/exec.js +0 -20
- package/dist/lib/gatewayManager.d.ts +0 -24
- package/dist/lib/gatewayManager.js +0 -85
- package/dist/lib/kubernetes.d.ts +0 -28
- package/dist/lib/kubernetes.js +0 -122
- package/dist/lib/progress.d.ts +0 -128
- package/dist/lib/progress.js +0 -273
- package/dist/lib/wrappers/git.d.ts +0 -2
- package/dist/lib/wrappers/git.js +0 -43
|
@@ -1,38 +1,29 @@
|
|
|
1
|
-
import { StatusData, CommandVersionConfig } from '../lib/types.js';
|
|
2
|
-
import { ArkClient } from '../lib/arkClient.js';
|
|
1
|
+
import { StatusData, CommandVersionConfig, ClusterInfo } from '../lib/types.js';
|
|
3
2
|
export declare const getNodeVersion: () => CommandVersionConfig;
|
|
4
3
|
export declare const getNpmVersion: () => CommandVersionConfig;
|
|
5
4
|
export declare const getKubectlVersion: () => CommandVersionConfig;
|
|
6
5
|
export declare const getDockerVersion: () => CommandVersionConfig;
|
|
7
6
|
export declare const getHelmVersion: () => CommandVersionConfig;
|
|
7
|
+
export declare const getMinikubeVersion: () => CommandVersionConfig;
|
|
8
|
+
export declare const getKindVersion: () => CommandVersionConfig;
|
|
8
9
|
export declare class StatusChecker {
|
|
9
|
-
private arkClient;
|
|
10
|
-
private kubernetesManager;
|
|
11
|
-
constructor(arkClient: ArkClient);
|
|
12
|
-
/**
|
|
13
|
-
* Check if a command is available in the system
|
|
14
|
-
*/
|
|
15
|
-
private isCommandAvailable;
|
|
16
10
|
/**
|
|
17
11
|
* Get version of a command
|
|
18
12
|
*/
|
|
19
13
|
private getCommandVersion;
|
|
20
14
|
/**
|
|
21
|
-
* Check
|
|
22
|
-
|
|
23
|
-
private checkServiceHealth;
|
|
24
|
-
/**
|
|
25
|
-
* Check if ark-api is running and healthy
|
|
15
|
+
* Check combined deployment and helm status
|
|
16
|
+
* Gets health from deployment, version/revision from Helm
|
|
26
17
|
*/
|
|
27
|
-
private
|
|
18
|
+
private checkCombinedStatus;
|
|
28
19
|
/**
|
|
29
|
-
*
|
|
20
|
+
* Check deployment status
|
|
30
21
|
*/
|
|
31
|
-
private
|
|
22
|
+
private checkDeploymentStatus;
|
|
32
23
|
/**
|
|
33
|
-
* Check
|
|
24
|
+
* Check helm release status (fallback for services without deployments)
|
|
34
25
|
*/
|
|
35
|
-
private
|
|
26
|
+
private checkHelmStatus;
|
|
36
27
|
/**
|
|
37
28
|
* Check system dependencies
|
|
38
29
|
*/
|
|
@@ -40,9 +31,8 @@ export declare class StatusChecker {
|
|
|
40
31
|
/**
|
|
41
32
|
* Run all checks and return results
|
|
42
33
|
*/
|
|
43
|
-
checkAll(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
private getHealthPath;
|
|
34
|
+
checkAll(): Promise<StatusData & {
|
|
35
|
+
clusterAccess: boolean;
|
|
36
|
+
clusterInfo?: ClusterInfo;
|
|
37
|
+
}>;
|
|
48
38
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import axios from 'axios';
|
|
6
|
-
const execAsync = promisify(exec);
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { checkCommandExists } from '../lib/commands.js';
|
|
3
|
+
import { arkServices } from '../arkServices.js';
|
|
4
|
+
import { isArkReady } from '../lib/arkStatus.js';
|
|
7
5
|
export const getNodeVersion = () => ({
|
|
8
6
|
command: 'node',
|
|
9
7
|
versionArgs: '--version',
|
|
@@ -40,6 +38,20 @@ export const getHelmVersion = () => ({
|
|
|
40
38
|
versionArgs: 'version --short',
|
|
41
39
|
versionExtract: (output) => output.trim(),
|
|
42
40
|
});
|
|
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
|
+
});
|
|
43
55
|
function createErrorServiceStatus(name, url, error, defaultStatus = 'unhealthy', defaultDetails) {
|
|
44
56
|
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
45
57
|
return {
|
|
@@ -50,32 +62,13 @@ function createErrorServiceStatus(name, url, error, defaultStatus = 'unhealthy',
|
|
|
50
62
|
};
|
|
51
63
|
}
|
|
52
64
|
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
|
-
}
|
|
72
65
|
/**
|
|
73
66
|
* Get version of a command
|
|
74
67
|
*/
|
|
75
68
|
async getCommandVersion(config) {
|
|
76
69
|
try {
|
|
77
|
-
const
|
|
78
|
-
const { stdout } = await
|
|
70
|
+
const args = config.versionArgs.split(' ');
|
|
71
|
+
const { stdout } = await execa(config.command, args);
|
|
79
72
|
return config.versionExtract(stdout);
|
|
80
73
|
}
|
|
81
74
|
catch (error) {
|
|
@@ -83,92 +76,220 @@ export class StatusChecker {
|
|
|
83
76
|
}
|
|
84
77
|
}
|
|
85
78
|
/**
|
|
86
|
-
* Check
|
|
79
|
+
* Check combined deployment and helm status
|
|
80
|
+
* Gets health from deployment, version/revision from Helm
|
|
87
81
|
*/
|
|
88
|
-
async
|
|
89
|
-
|
|
82
|
+
async checkCombinedStatus(serviceName, deploymentName, helmReleaseName, namespace, devDeploymentName) {
|
|
83
|
+
// Get deployment status for health
|
|
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) {
|
|
90
111
|
try {
|
|
91
|
-
await
|
|
112
|
+
const { stdout } = await execa('kubectl', [
|
|
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
|
+
}
|
|
92
184
|
return {
|
|
93
185
|
name: serviceName,
|
|
94
|
-
status
|
|
95
|
-
|
|
96
|
-
|
|
186
|
+
status,
|
|
187
|
+
details: `${readyReplicas}/${replicas} replicas ready`,
|
|
188
|
+
namespace,
|
|
97
189
|
};
|
|
98
190
|
}
|
|
99
191
|
catch (error) {
|
|
100
|
-
|
|
192
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
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}`);
|
|
101
250
|
}
|
|
102
251
|
}
|
|
103
252
|
/**
|
|
104
|
-
* Check
|
|
253
|
+
* Check helm release status (fallback for services without deployments)
|
|
105
254
|
*/
|
|
106
|
-
async
|
|
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') {
|
|
255
|
+
async checkHelmStatus(serviceName, helmReleaseName, namespace) {
|
|
124
256
|
try {
|
|
125
|
-
await
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
name: kubernetesServiceName,
|
|
131
|
-
namespace,
|
|
132
|
-
});
|
|
133
|
-
const endpoints = await k8sApi.readNamespacedEndpoints({
|
|
134
|
-
name: kubernetesServiceName,
|
|
257
|
+
const { stdout } = await execa('helm', [
|
|
258
|
+
'list',
|
|
259
|
+
'--filter',
|
|
260
|
+
helmReleaseName,
|
|
261
|
+
'--namespace',
|
|
135
262
|
namespace,
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (readyAddresses > 0) {
|
|
142
|
-
const serviceIP = service.spec?.clusterIP;
|
|
143
|
-
const servicePort = service.spec?.ports?.[0]?.port;
|
|
144
|
-
return {
|
|
145
|
-
name: serviceName,
|
|
146
|
-
status: 'healthy',
|
|
147
|
-
url: `cluster://${serviceIP}:${servicePort}`,
|
|
148
|
-
details: `${serviceName} running in cluster (${readyAddresses} ready endpoints)`,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
263
|
+
'--output',
|
|
264
|
+
'json',
|
|
265
|
+
]);
|
|
266
|
+
const helmList = JSON.parse(stdout);
|
|
267
|
+
if (helmList.length === 0) {
|
|
152
268
|
return {
|
|
153
269
|
name: serviceName,
|
|
154
|
-
status: '
|
|
155
|
-
details:
|
|
270
|
+
status: 'not installed',
|
|
271
|
+
details: `Helm release '${helmReleaseName}' not found`,
|
|
272
|
+
namespace,
|
|
156
273
|
};
|
|
157
274
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return this.createNotInstalledStatus(serviceName);
|
|
164
|
-
}
|
|
165
|
-
// Other errors indicate unhealthy
|
|
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';
|
|
166
280
|
return {
|
|
167
281
|
name: serviceName,
|
|
168
|
-
status: 'unhealthy',
|
|
169
|
-
|
|
282
|
+
status: isHealthy ? 'healthy' : 'unhealthy',
|
|
283
|
+
version: appVersion,
|
|
284
|
+
revision: revision,
|
|
285
|
+
details: `Status: ${status}`,
|
|
286
|
+
namespace,
|
|
170
287
|
};
|
|
171
288
|
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
291
|
+
return createErrorServiceStatus(serviceName, '', error, 'unhealthy', `Failed to check helm status: ${errorMessage}`);
|
|
292
|
+
}
|
|
172
293
|
}
|
|
173
294
|
/**
|
|
174
295
|
* Check system dependencies
|
|
@@ -180,10 +301,13 @@ export class StatusChecker {
|
|
|
180
301
|
{ name: 'kubectl', ...getKubectlVersion() },
|
|
181
302
|
{ name: 'docker', ...getDockerVersion() },
|
|
182
303
|
{ name: 'helm', ...getHelmVersion() },
|
|
304
|
+
{ name: 'minikube', ...getMinikubeVersion() },
|
|
305
|
+
{ name: 'kind', ...getKindVersion() },
|
|
183
306
|
];
|
|
184
307
|
const results = [];
|
|
185
308
|
for (const dep of dependencies) {
|
|
186
|
-
const
|
|
309
|
+
const args = dep.versionArgs.split(' ');
|
|
310
|
+
const installed = await checkCommandExists(dep.command, args);
|
|
187
311
|
const version = installed
|
|
188
312
|
? await this.getCommandVersion({
|
|
189
313
|
command: dep.command,
|
|
@@ -205,47 +329,89 @@ export class StatusChecker {
|
|
|
205
329
|
/**
|
|
206
330
|
* Run all checks and return results
|
|
207
331
|
*/
|
|
208
|
-
async checkAll(
|
|
209
|
-
//
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
332
|
+
async checkAll() {
|
|
333
|
+
// Check dependencies first
|
|
334
|
+
const dependencies = await this.checkDependencies();
|
|
335
|
+
// Test cluster access
|
|
336
|
+
let clusterAccess = false;
|
|
337
|
+
try {
|
|
338
|
+
await execa('kubectl', ['get', 'namespaces', '-o', 'name'], {
|
|
339
|
+
timeout: 5000,
|
|
340
|
+
});
|
|
341
|
+
clusterAccess = true;
|
|
213
342
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
343
|
+
catch {
|
|
344
|
+
clusterAccess = false;
|
|
345
|
+
}
|
|
346
|
+
// Get cluster info if accessible
|
|
347
|
+
let clusterInfo;
|
|
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
|
+
}
|
|
219
405
|
}
|
|
220
|
-
serviceChecks.push(this.checkServiceHealth(serviceName, serviceUrl, `${serviceName} is running`, this.getHealthPath(serviceName)));
|
|
221
406
|
}
|
|
222
|
-
// Always check dependencies
|
|
223
|
-
const dependenciesCheck = this.checkDependencies();
|
|
224
|
-
const [dependencies, ...serviceStatuses] = await Promise.all([
|
|
225
|
-
dependenciesCheck,
|
|
226
|
-
...serviceChecks,
|
|
227
|
-
]);
|
|
228
407
|
return {
|
|
229
|
-
services
|
|
408
|
+
services,
|
|
230
409
|
dependencies,
|
|
410
|
+
clusterAccess,
|
|
411
|
+
clusterInfo,
|
|
412
|
+
arkReady,
|
|
413
|
+
defaultModelExists,
|
|
414
|
+
defaultModel,
|
|
231
415
|
};
|
|
232
416
|
}
|
|
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
417
|
}
|
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 {};
|