@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.
- package/dist/arkServices.d.ts +50 -0
- package/dist/arkServices.js +153 -0
- package/dist/charts/charts.d.ts +5 -0
- package/dist/charts/charts.js +6 -0
- package/dist/charts/dependencies.d.ts +6 -0
- package/dist/charts/dependencies.js +50 -0
- package/dist/charts/types.d.ts +40 -0
- package/dist/charts/types.js +1 -0
- package/dist/commands/agents/index.d.ts +2 -0
- package/dist/commands/agents/index.js +56 -0
- package/dist/commands/agents/selector.d.ts +8 -0
- package/dist/commands/agents/selector.js +53 -0
- package/dist/commands/agents.d.ts +2 -0
- package/dist/commands/agents.js +53 -0
- package/dist/commands/chat/index.d.ts +2 -0
- package/dist/commands/chat/index.js +45 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +45 -0
- package/dist/commands/cluster/get.d.ts +2 -0
- package/dist/commands/cluster/get.js +39 -0
- package/dist/commands/cluster/index.js +2 -4
- package/dist/commands/completion/index.d.ts +2 -0
- package/dist/commands/completion/index.js +268 -0
- package/dist/commands/completion.js +159 -2
- package/dist/commands/config/index.d.ts +2 -0
- package/dist/commands/config/index.js +42 -0
- package/dist/commands/config.d.ts +0 -3
- package/dist/commands/config.js +38 -321
- package/dist/commands/dashboard/index.d.ts +3 -0
- package/dist/commands/dashboard/index.js +39 -0
- package/dist/commands/dashboard.d.ts +3 -0
- package/dist/commands/dashboard.js +39 -0
- package/dist/commands/dev/index.d.ts +2 -0
- package/dist/commands/dev/index.js +9 -0
- package/dist/commands/dev/tool/check.d.ts +2 -0
- package/dist/commands/dev/tool/check.js +142 -0
- package/dist/commands/dev/tool/clean.d.ts +2 -0
- package/dist/commands/dev/tool/clean.js +153 -0
- package/dist/commands/dev/tool/generate.d.ts +2 -0
- package/dist/commands/dev/tool/generate.js +28 -0
- package/dist/commands/dev/tool/index.d.ts +2 -0
- package/dist/commands/dev/tool/index.js +14 -0
- package/dist/commands/dev/tool/init.d.ts +2 -0
- package/dist/commands/dev/tool/init.js +320 -0
- package/dist/commands/dev/tool/shared.d.ts +5 -0
- package/dist/commands/dev/tool/shared.js +256 -0
- package/dist/commands/dev/tool/status.d.ts +2 -0
- package/dist/commands/dev/tool/status.js +136 -0
- package/dist/commands/dev/tool.d.ts +2 -0
- package/dist/commands/dev/tool.js +559 -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/install/index.d.ts +6 -0
- package/dist/commands/install/index.js +165 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.js +147 -0
- package/dist/commands/models/create.d.ts +1 -0
- package/dist/commands/models/create.js +213 -0
- package/dist/commands/models/index.d.ts +2 -0
- package/dist/commands/models/index.js +65 -0
- package/dist/commands/models/selector.d.ts +8 -0
- package/dist/commands/models/selector.js +53 -0
- package/dist/commands/routes/index.d.ts +2 -0
- package/dist/commands/routes/index.js +101 -0
- package/dist/commands/routes.d.ts +2 -0
- package/dist/commands/routes.js +101 -0
- package/dist/commands/status/index.d.ts +3 -0
- package/dist/commands/status/index.js +33 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +33 -0
- package/dist/commands/targets/index.d.ts +2 -0
- package/dist/commands/targets/index.js +65 -0
- package/dist/commands/targets.d.ts +2 -0
- package/dist/commands/targets.js +65 -0
- package/dist/commands/teams/index.d.ts +2 -0
- package/dist/commands/teams/index.js +54 -0
- package/dist/commands/teams/selector.d.ts +8 -0
- package/dist/commands/teams/selector.js +55 -0
- package/dist/commands/tools/index.d.ts +2 -0
- package/dist/commands/tools/index.js +54 -0
- package/dist/commands/tools/selector.d.ts +8 -0
- package/dist/commands/tools/selector.js +53 -0
- package/dist/commands/uninstall/index.d.ts +2 -0
- package/dist/commands/uninstall/index.js +84 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.js +83 -0
- package/dist/components/ChatUI.d.ts +16 -0
- package/dist/components/ChatUI.js +801 -0
- package/dist/components/StatusView.d.ts +10 -0
- package/dist/components/StatusView.js +39 -0
- package/dist/components/statusChecker.d.ts +10 -13
- package/dist/components/statusChecker.js +128 -65
- package/dist/config.js +3 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +31 -36
- 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 +93 -0
- package/dist/lib/arkStatus.d.ts +5 -0
- package/dist/lib/arkStatus.js +20 -0
- package/dist/lib/chatClient.d.ts +33 -0
- package/dist/lib/chatClient.js +101 -0
- package/dist/lib/cluster.d.ts +2 -1
- package/dist/lib/cluster.js +27 -3
- package/dist/lib/commandUtils.d.ts +4 -0
- package/dist/lib/commandUtils.js +18 -0
- package/dist/lib/commandUtils.test.d.ts +1 -0
- package/dist/lib/commandUtils.test.js +44 -0
- package/dist/lib/config.d.ts +24 -80
- package/dist/lib/config.js +68 -205
- package/dist/lib/config.test.d.ts +1 -0
- package/dist/lib/config.test.js +93 -0
- package/dist/lib/dev/tools/analyzer.d.ts +30 -0
- package/dist/lib/dev/tools/analyzer.js +190 -0
- package/dist/lib/dev/tools/discover_tools.py +392 -0
- package/dist/lib/dev/tools/mcp-types.d.ts +28 -0
- package/dist/lib/dev/tools/mcp-types.js +86 -0
- package/dist/lib/dev/tools/types.d.ts +50 -0
- package/dist/lib/dev/tools/types.js +1 -0
- package/dist/lib/output.d.ts +36 -0
- package/dist/lib/output.js +89 -0
- package/dist/lib/types.d.ts +8 -3
- package/dist/types/types.d.ts +40 -0
- package/dist/types/types.js +1 -0
- package/dist/ui/MainMenu.js +158 -90
- package/dist/ui/statusFormatter.d.ts +4 -1
- package/dist/ui/statusFormatter.js +91 -19
- package/package.json +16 -4
package/dist/lib/types.d.ts
CHANGED
|
@@ -13,13 +13,16 @@ export interface KubernetesConfig {
|
|
|
13
13
|
namespace?: string;
|
|
14
14
|
inCluster: boolean;
|
|
15
15
|
}
|
|
16
|
-
export
|
|
16
|
+
export type DeploymentStatus = 'available' | 'progressing' | 'replicafailure' | 'failed' | 'not found' | 'unknown';
|
|
17
|
+
export type ServiceStatus = {
|
|
17
18
|
name: string;
|
|
18
|
-
status: 'healthy' | 'unhealthy' | 'not installed';
|
|
19
|
+
status: 'healthy' | 'warning' | 'unhealthy' | 'not installed' | 'not ready';
|
|
20
|
+
deploymentStatus?: DeploymentStatus;
|
|
19
21
|
url?: string;
|
|
20
22
|
version?: string;
|
|
23
|
+
revision?: string;
|
|
21
24
|
details?: string;
|
|
22
|
-
}
|
|
25
|
+
};
|
|
23
26
|
export interface DependencyStatus {
|
|
24
27
|
name: string;
|
|
25
28
|
installed: boolean;
|
|
@@ -29,6 +32,8 @@ export interface DependencyStatus {
|
|
|
29
32
|
export interface StatusData {
|
|
30
33
|
services: ServiceStatus[];
|
|
31
34
|
dependencies: DependencyStatus[];
|
|
35
|
+
arkReady?: boolean;
|
|
36
|
+
defaultModelExists?: boolean;
|
|
32
37
|
}
|
|
33
38
|
export interface CommandVersionConfig {
|
|
34
39
|
command: string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a Helm chart configuration for ARK components
|
|
3
|
+
*/
|
|
4
|
+
export interface ArkChart {
|
|
5
|
+
/** Name of the chart (used as release name) */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Full chart path (OCI registry or local path) */
|
|
8
|
+
chartPath: string;
|
|
9
|
+
/** Kubernetes namespace to install into */
|
|
10
|
+
namespace: string;
|
|
11
|
+
/** Additional arguments to pass to helm (e.g., --create-namespace, --wait, --timeout 300s, --set key=value) */
|
|
12
|
+
args?: string[];
|
|
13
|
+
/** Description of what this chart provides */
|
|
14
|
+
description?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Collection of ARK charts
|
|
18
|
+
*/
|
|
19
|
+
export interface ChartCollection {
|
|
20
|
+
[key: string]: ArkChart;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Represents a dependency that needs to be installed
|
|
24
|
+
*/
|
|
25
|
+
export interface Dependency {
|
|
26
|
+
/** Name of the dependency */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Command to execute (helm, kubectl, etc.) */
|
|
29
|
+
command: string;
|
|
30
|
+
/** Arguments to pass to the command */
|
|
31
|
+
args: string[];
|
|
32
|
+
/** Description of what this dependency provides */
|
|
33
|
+
description?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Collection of dependencies
|
|
37
|
+
*/
|
|
38
|
+
export interface DependencyCollection {
|
|
39
|
+
[key: string]: Dependency;
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/ui/MainMenu.js
CHANGED
|
@@ -1,70 +1,169 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Text, Box, useInput } from 'ink';
|
|
3
|
-
import SelectInput from 'ink-select-input';
|
|
2
|
+
import { Text, Box, render, useInput } from 'ink';
|
|
4
3
|
import * as React from 'react';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
// Helper function to unmount the main ink app - used when we move from a
|
|
5
|
+
// React TUI app to basic input/output.
|
|
6
|
+
async function unmountInkApp() {
|
|
7
|
+
const app = globalThis.inkApp;
|
|
8
|
+
if (app) {
|
|
9
|
+
app.unmount();
|
|
10
|
+
// Remove all existing signal listeners that might interfere with inquirer
|
|
11
|
+
process.removeAllListeners('SIGINT');
|
|
12
|
+
process.removeAllListeners('SIGTERM');
|
|
13
|
+
process.removeAllListeners('SIGQUIT');
|
|
14
|
+
process.removeAllListeners('exit');
|
|
15
|
+
// Reset stdin completely
|
|
16
|
+
if (process.stdin.isTTY) {
|
|
17
|
+
process.stdin.setRawMode(false);
|
|
18
|
+
process.stdin.pause();
|
|
19
|
+
process.stdin.removeAllListeners();
|
|
20
|
+
process.stdin.resume();
|
|
21
|
+
}
|
|
22
|
+
// Reset stdout/stderr
|
|
23
|
+
process.stdout.removeAllListeners();
|
|
24
|
+
process.stderr.removeAllListeners();
|
|
25
|
+
console.clear();
|
|
26
|
+
// Give terminal more time to fully reset
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
11
30
|
const MainMenu = () => {
|
|
12
|
-
const [
|
|
13
|
-
const [statusData, setStatusData] = React.useState(null);
|
|
14
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
15
|
-
const [error, setError] = React.useState(null);
|
|
31
|
+
const [selectedIndex, setSelectedIndex] = React.useState(0);
|
|
16
32
|
const choices = [
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
33
|
+
{
|
|
34
|
+
label: 'Chat',
|
|
35
|
+
description: 'Interactive chat with ARK agents',
|
|
36
|
+
value: 'chat',
|
|
37
|
+
command: 'ark chat',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: 'Install',
|
|
41
|
+
description: 'Install Ark',
|
|
42
|
+
value: 'install',
|
|
43
|
+
command: 'ark install',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: 'Dashboard',
|
|
47
|
+
description: 'Open ARK dashboard in browser',
|
|
48
|
+
value: 'dashboard',
|
|
49
|
+
command: 'ark dashboard',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
label: 'Status Check',
|
|
53
|
+
description: 'Check ARK services status',
|
|
54
|
+
value: 'status',
|
|
55
|
+
command: 'ark status',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: 'Generate',
|
|
59
|
+
description: 'Generate new ARK components',
|
|
60
|
+
value: 'generate',
|
|
61
|
+
command: 'ark generate',
|
|
62
|
+
},
|
|
63
|
+
{ label: 'Exit', description: 'Exit ARK CLI', value: 'exit' },
|
|
21
64
|
];
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
process.exit(0);
|
|
26
|
-
}, EXIT_TIMEOUT_MS);
|
|
27
|
-
return () => clearTimeout(timer);
|
|
28
|
-
}
|
|
29
|
-
}, [selectedChoice]);
|
|
30
|
-
React.useEffect(() => {
|
|
31
|
-
if (selectedChoice === 'status' && !statusData && !isLoading) {
|
|
32
|
-
checkStatus();
|
|
65
|
+
useInput((input, key) => {
|
|
66
|
+
if (key.upArrow || input === 'k') {
|
|
67
|
+
setSelectedIndex((prev) => (prev > 0 ? prev - 1 : choices.length - 1));
|
|
33
68
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
setIsLoading(true);
|
|
37
|
-
setError(null);
|
|
38
|
-
try {
|
|
39
|
-
const configManager = new ConfigManager();
|
|
40
|
-
const apiBaseUrl = await configManager.getApiBaseUrl();
|
|
41
|
-
const serviceUrls = await configManager.getServiceUrls();
|
|
42
|
-
const arkClient = new ArkClient(apiBaseUrl);
|
|
43
|
-
const statusChecker = new StatusChecker(arkClient);
|
|
44
|
-
const status = await statusChecker.checkAll(serviceUrls, apiBaseUrl);
|
|
45
|
-
setStatusData(status);
|
|
69
|
+
else if (key.downArrow || input === 'j') {
|
|
70
|
+
setSelectedIndex((prev) => (prev < choices.length - 1 ? prev + 1 : 0));
|
|
46
71
|
}
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
else if (key.return) {
|
|
73
|
+
handleSelect(choices[selectedIndex]);
|
|
49
74
|
}
|
|
50
|
-
|
|
51
|
-
|
|
75
|
+
else {
|
|
76
|
+
// Handle number keys for quick selection
|
|
77
|
+
const num = parseInt(input, 10);
|
|
78
|
+
if (!isNaN(num) && num >= 1 && num <= choices.length) {
|
|
79
|
+
handleSelect(choices[num - 1]);
|
|
80
|
+
}
|
|
52
81
|
}
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
82
|
+
});
|
|
83
|
+
const handleSelect = async (item) => {
|
|
84
|
+
switch (item.value) {
|
|
85
|
+
case 'exit':
|
|
86
|
+
process.exit(0);
|
|
87
|
+
break;
|
|
88
|
+
case 'chat': {
|
|
89
|
+
// Unmount fullscreen app and clear screen.
|
|
90
|
+
await unmountInkApp();
|
|
91
|
+
// Import and start ChatUI in the same process
|
|
92
|
+
const { render } = await import('ink');
|
|
93
|
+
const { ArkApiProxy } = await import('../lib/arkApiProxy.js');
|
|
94
|
+
const ChatUI = (await import('../components/ChatUI.js')).default;
|
|
95
|
+
try {
|
|
96
|
+
const proxy = new ArkApiProxy();
|
|
97
|
+
const arkApiClient = await proxy.start();
|
|
98
|
+
// Render ChatUI as a new Ink app
|
|
99
|
+
render(_jsx(ChatUI, { arkApiClient: arkApiClient, arkApiProxy: proxy }));
|
|
60
100
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
101
|
+
catch (error) {
|
|
102
|
+
const output = (await import('../lib/output.js')).default;
|
|
103
|
+
output.error(error instanceof Error
|
|
104
|
+
? error.message
|
|
105
|
+
: 'Failed to connect to ARK API');
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case 'install': {
|
|
111
|
+
// Unmount fullscreen app and clear screen.
|
|
112
|
+
await unmountInkApp();
|
|
113
|
+
// NOTE: We spawn the install command as a separate process to avoid
|
|
114
|
+
// signal handling conflicts between Ink's useInput and inquirer's prompts.
|
|
115
|
+
// The signal-exit library used by inquirer conflicts with Ink's signal handlers,
|
|
116
|
+
// causing ExitPromptError even after proper cleanup. Spawning ensures
|
|
117
|
+
// a clean process environment for inquirer to work correctly.
|
|
118
|
+
const { spawn } = await import('child_process');
|
|
119
|
+
const child = spawn(process.execPath, [process.argv[1], 'install'], {
|
|
120
|
+
stdio: 'inherit',
|
|
121
|
+
});
|
|
122
|
+
await new Promise((resolve, reject) => {
|
|
123
|
+
child.on('close', (code) => {
|
|
124
|
+
if (code === 0) {
|
|
125
|
+
resolve();
|
|
126
|
+
}
|
|
127
|
+
else if (code === 130) {
|
|
128
|
+
// 130 is the exit code for SIGINT (Ctrl+C)
|
|
129
|
+
process.exit(130);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
reject(new Error(`Install command failed with code ${code}`));
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
child.on('error', reject);
|
|
136
|
+
// Forward SIGINT to child and exit
|
|
137
|
+
process.on('SIGINT', () => {
|
|
138
|
+
child.kill('SIGINT');
|
|
139
|
+
process.exit(130);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case 'dashboard': {
|
|
145
|
+
// Unmount fullscreen app and clear screen.
|
|
146
|
+
await unmountInkApp();
|
|
147
|
+
const { openDashboard } = await import('../commands/dashboard/index.js');
|
|
148
|
+
await openDashboard();
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 'status': {
|
|
152
|
+
// Unmount fullscreen app and clear screen.
|
|
153
|
+
await unmountInkApp();
|
|
154
|
+
const { checkStatus } = await import('../commands/status/index.js');
|
|
155
|
+
await checkStatus();
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'generate': {
|
|
159
|
+
const GeneratorUI = (await import('../components/GeneratorUI.js'))
|
|
160
|
+
.default;
|
|
161
|
+
render(_jsx(GeneratorUI, {}));
|
|
162
|
+
break;
|
|
64
163
|
}
|
|
65
164
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
165
|
+
};
|
|
166
|
+
return (_jsxs(_Fragment, { children: [_jsxs(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: `
|
|
68
167
|
╔═══════════════════════════════════════╗
|
|
69
168
|
║ ║
|
|
70
169
|
║ █████╗ ██████╗ ██╗ ██╗ ║
|
|
@@ -77,40 +176,9 @@ const MainMenu = () => {
|
|
|
77
176
|
║ Agents at Scale Platform ║
|
|
78
177
|
║ ║
|
|
79
178
|
╚═══════════════════════════════════════╝
|
|
80
|
-
` }), _jsx(Text, { color: "green", bold: true, children: "Welcome to ARK! \uD83D\uDE80" }), _jsx(Text, { color: "gray", children: "Interactive terminal interface for ARK agents" })] }))
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
: service.status === 'unhealthy'
|
|
85
|
-
? 'red'
|
|
86
|
-
: 'yellow';
|
|
87
|
-
const statusIcon = service.status === 'healthy'
|
|
88
|
-
? '✓'
|
|
89
|
-
: service.status === 'unhealthy'
|
|
90
|
-
? '✗'
|
|
91
|
-
: '?';
|
|
92
|
-
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));
|
|
93
|
-
};
|
|
94
|
-
const renderDependencyStatus = (dep) => {
|
|
95
|
-
const statusColor = dep.installed ? 'green' : 'red';
|
|
96
|
-
const statusIcon = dep.installed ? '✓' : '✗';
|
|
97
|
-
const statusText = dep.installed ? 'installed' : 'missing';
|
|
98
|
-
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));
|
|
99
|
-
};
|
|
100
|
-
const renderStatus = () => {
|
|
101
|
-
if (isLoading) {
|
|
102
|
-
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." })] }));
|
|
103
|
-
}
|
|
104
|
-
if (error) {
|
|
105
|
-
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..." }) })] }));
|
|
106
|
-
}
|
|
107
|
-
if (!statusData) {
|
|
108
|
-
return null;
|
|
109
|
-
}
|
|
110
|
-
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..." }) })] }));
|
|
111
|
-
};
|
|
112
|
-
return (_jsxs(_Fragment, { children: [renderBanner(), !selectedChoice && (_jsx(SelectInput, { items: choices, onSelect: (choice) => {
|
|
113
|
-
setSelectedChoice(choice.value);
|
|
114
|
-
} })), selectedChoice === 'status' && renderStatus(), selectedChoice === 'dashboard' && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "green", children: "\uD83C\uDFF7\uFE0F Dashboard feature selected" }), _jsx(DashboardCLI, {})] })), selectedChoice === 'generate' && _jsx(GeneratorUI, {}), selectedChoice === 'exit' && _jsx(Text, { color: "yellow", children: "\uD83D\uDC4B Goodbye!" })] }));
|
|
179
|
+
` }), _jsx(Text, { color: "green", bold: true, children: "Welcome to ARK! \uD83D\uDE80" }), _jsx(Text, { color: "gray", children: "Interactive terminal interface for ARK agents" })] }), _jsx(Box, { flexDirection: "column", paddingX: 4, marginTop: 1, children: choices.map((choice, index) => {
|
|
180
|
+
const isSelected = index === selectedIndex;
|
|
181
|
+
return (_jsxs(Box, { flexDirection: "row", paddingY: 0, children: [_jsx(Text, { color: "gray", dimColor: true, children: isSelected ? '❯ ' : ' ' }), _jsxs(Text, { color: "gray", dimColor: true, children: [index + 1, "."] }), _jsx(Box, { marginLeft: 1, width: 20, children: _jsx(Text, { color: isSelected ? 'green' : 'white', bold: isSelected, children: choice.label }) }), _jsx(Text, { color: "gray", children: choice.description })] }, choice.value));
|
|
182
|
+
}) })] }));
|
|
115
183
|
};
|
|
116
184
|
export default MainMenu;
|
|
@@ -3,7 +3,10 @@ export declare class StatusFormatter {
|
|
|
3
3
|
/**
|
|
4
4
|
* Print status check results to console
|
|
5
5
|
*/
|
|
6
|
-
static printStatus(statusData: StatusData
|
|
6
|
+
static printStatus(statusData: StatusData & {
|
|
7
|
+
clusterAccess?: boolean;
|
|
8
|
+
clusterInfo?: any;
|
|
9
|
+
}): void;
|
|
7
10
|
private static printService;
|
|
8
11
|
private static printDependency;
|
|
9
12
|
}
|
|
@@ -4,18 +4,78 @@ export class StatusFormatter {
|
|
|
4
4
|
* Print status check results to console
|
|
5
5
|
*/
|
|
6
6
|
static printStatus(statusData) {
|
|
7
|
-
console.log(
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
console.log(chalk.cyan.bold('📡 ARK Services:'));
|
|
11
|
-
for (const service of statusData.services) {
|
|
12
|
-
StatusFormatter.printService(service);
|
|
13
|
-
}
|
|
14
|
-
// Print dependencies status
|
|
15
|
-
console.log(chalk.cyan.bold('\n🛠️ System Dependencies:'));
|
|
7
|
+
console.log();
|
|
8
|
+
// Print dependencies status first
|
|
9
|
+
console.log(chalk.cyan.bold('system dependencies:'));
|
|
16
10
|
for (const dep of statusData.dependencies) {
|
|
17
11
|
StatusFormatter.printDependency(dep);
|
|
18
12
|
}
|
|
13
|
+
// Print cluster status
|
|
14
|
+
console.log(chalk.cyan.bold('\ncluster access:'));
|
|
15
|
+
if (statusData.clusterAccess && statusData.clusterInfo) {
|
|
16
|
+
const clusterName = statusData.clusterInfo.context || 'kubernetes cluster';
|
|
17
|
+
const clusterDetails = [];
|
|
18
|
+
if (statusData.clusterInfo.type &&
|
|
19
|
+
statusData.clusterInfo.type !== 'unknown') {
|
|
20
|
+
clusterDetails.push(statusData.clusterInfo.type);
|
|
21
|
+
}
|
|
22
|
+
if (statusData.clusterInfo.ip) {
|
|
23
|
+
clusterDetails.push(statusData.clusterInfo.ip);
|
|
24
|
+
}
|
|
25
|
+
console.log(` ${chalk.green('✓ accessible')} ${chalk.bold.white(clusterName)}${clusterDetails.length > 0 ? chalk.gray(' ' + clusterDetails.join(', ')) : ''}`);
|
|
26
|
+
}
|
|
27
|
+
else if (statusData.clusterAccess) {
|
|
28
|
+
console.log(` ${chalk.green('✓ accessible')} ${chalk.bold('kubernetes cluster')}`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log(` ${chalk.red('✗ unreachable')} ${chalk.bold('kubernetes cluster')}`);
|
|
32
|
+
console.log(` ${chalk.gray('Install minikube: https://minikube.sigs.k8s.io/docs/start')}`);
|
|
33
|
+
}
|
|
34
|
+
// Only show ARK services if we have cluster access
|
|
35
|
+
if (statusData.clusterAccess) {
|
|
36
|
+
console.log(chalk.cyan.bold('\nark services:'));
|
|
37
|
+
// Show all services except ark-controller (already shown in ark status)
|
|
38
|
+
for (const service of statusData.services) {
|
|
39
|
+
if (service.name !== 'ark-controller') {
|
|
40
|
+
StatusFormatter.printService(service);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(chalk.cyan.bold('\nark services:'));
|
|
46
|
+
console.log(` ${chalk.gray('Cannot check ARK services - cluster not accessible')}`);
|
|
47
|
+
}
|
|
48
|
+
// Print ARK status section
|
|
49
|
+
console.log(chalk.cyan.bold('\nark status:'));
|
|
50
|
+
if (!statusData.clusterAccess) {
|
|
51
|
+
console.log(` ${chalk.red('✗ no cluster access')}`);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Show ark-controller status
|
|
55
|
+
const controllerStatus = statusData.services?.find(s => s.name === 'ark-controller');
|
|
56
|
+
if (controllerStatus) {
|
|
57
|
+
// Show the actual status but replace "not installed" with "not ready" for display
|
|
58
|
+
if (controllerStatus.status === 'not installed') {
|
|
59
|
+
console.log(` ${chalk.yellow('○ not ready')} ${chalk.bold('ark-controller')} ${chalk.gray(controllerStatus.details || '')}`);
|
|
60
|
+
}
|
|
61
|
+
else if (controllerStatus.status === 'healthy') {
|
|
62
|
+
// Controller is healthy - show ready status with model info
|
|
63
|
+
if (!statusData.defaultModelExists) {
|
|
64
|
+
console.log(` ${chalk.green('✓ ready')} ${chalk.bold('ark-controller')} ${chalk.gray(controllerStatus.details || '')}`);
|
|
65
|
+
console.log(` ${chalk.gray(' (no default model configured)')}`);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(` ${chalk.green('✓ ready')} ${chalk.bold('ark-controller')} ${chalk.gray(controllerStatus.details || '')}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
StatusFormatter.printService(controllerStatus);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.log(` ${chalk.yellow('○ not ready')} ${chalk.bold('ark-controller')}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
19
79
|
console.log();
|
|
20
80
|
}
|
|
21
81
|
static printService(service) {
|
|
@@ -23,24 +83,36 @@ export class StatusFormatter {
|
|
|
23
83
|
? chalk.green('✓ healthy')
|
|
24
84
|
: service.status === 'unhealthy'
|
|
25
85
|
? chalk.red('✗ unhealthy')
|
|
26
|
-
:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
86
|
+
: service.status === 'warning'
|
|
87
|
+
? chalk.yellow('⚠ warning')
|
|
88
|
+
: service.status === 'not ready'
|
|
89
|
+
? chalk.yellow('○ not ready')
|
|
90
|
+
: chalk.yellow('? not installed');
|
|
91
|
+
// Show version and revision in grey after the name for healthy services
|
|
92
|
+
let versionInfo = '';
|
|
93
|
+
if (service.status === 'healthy' && (service.version || service.revision)) {
|
|
94
|
+
const parts = [];
|
|
95
|
+
if (service.version)
|
|
96
|
+
parts.push(`v${service.version}`);
|
|
97
|
+
if (service.revision)
|
|
98
|
+
parts.push(`revision ${service.revision}`);
|
|
99
|
+
versionInfo = chalk.gray(` ${parts.join(', ')}`);
|
|
30
100
|
}
|
|
101
|
+
// Show details inline in grey for all statuses
|
|
102
|
+
let inlineDetails = '';
|
|
31
103
|
if (service.details) {
|
|
32
|
-
|
|
104
|
+
inlineDetails = chalk.gray(` ${service.details}`);
|
|
33
105
|
}
|
|
106
|
+
console.log(` ${statusColor} ${chalk.bold(service.name)}${versionInfo}${inlineDetails}`);
|
|
34
107
|
}
|
|
35
108
|
static printDependency(dep) {
|
|
36
109
|
const statusColor = dep.installed
|
|
37
110
|
? chalk.green('✓ installed')
|
|
38
111
|
: chalk.red('✗ missing');
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (dep.details) {
|
|
112
|
+
const versionText = dep.version ? chalk.gray(` ${dep.version}`) : '';
|
|
113
|
+
console.log(` ${statusColor} ${chalk.bold(dep.name)}${versionText}`);
|
|
114
|
+
if (dep.details && !dep.installed) {
|
|
115
|
+
// Only show details if there's an issue
|
|
44
116
|
console.log(` ${chalk.gray(dep.details)}`);
|
|
45
117
|
}
|
|
46
118
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agents-at-scale/ark",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.35-rc.1",
|
|
4
4
|
"description": "ARK CLI - Interactive terminal interface for ARK agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -12,11 +12,13 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc && chmod +x dist/index.js",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
15
|
+
"postbuild": "mkdir -p dist/lib/dev/tools && cp src/lib/dev/tools/*.py dist/lib/dev/tools/ 2>/dev/null || true",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"start": "NODE_NO_WARNINGS=1 node dist/index.js",
|
|
17
18
|
"clean": "rm -rf dist",
|
|
18
19
|
"lint": "eslint src/ --fix && prettier --write src/",
|
|
19
20
|
"lint:check": "eslint src/ && prettier --check src/",
|
|
21
|
+
"test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage --coverageDirectory=./artifacts/coverage",
|
|
20
22
|
"postinstall": "echo \"ARK CLI installed! Run 'ark' to try it out.\""
|
|
21
23
|
},
|
|
22
24
|
"keywords": [
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
},
|
|
40
42
|
"dependencies": {
|
|
41
43
|
"@kubernetes/client-node": "^1.3.0",
|
|
42
|
-
"@
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
43
45
|
"axios": "^1.7.7",
|
|
44
46
|
"chalk": "^4.1.2",
|
|
45
47
|
"commander": "^12.1.0",
|
|
@@ -47,9 +49,14 @@
|
|
|
47
49
|
"execa": "^9.6.0",
|
|
48
50
|
"ink": "^6.0.1",
|
|
49
51
|
"ink-select-input": "^6.2.0",
|
|
52
|
+
"ink-spinner": "^5.0.0",
|
|
50
53
|
"ink-text-input": "^6.0.0",
|
|
51
54
|
"inquirer": "^12.1.0",
|
|
55
|
+
"marked": "^15.0.12",
|
|
56
|
+
"marked-terminal": "^7.3.0",
|
|
52
57
|
"open": "^10.2.0",
|
|
58
|
+
"openai": "^5.19.1",
|
|
59
|
+
"ora": "^8.2.0",
|
|
53
60
|
"react": "^19.1.0",
|
|
54
61
|
"simple-git": "^3.28.0",
|
|
55
62
|
"yaml": "^2.6.1"
|
|
@@ -58,12 +65,17 @@
|
|
|
58
65
|
"@eslint/js": "^9.17.0",
|
|
59
66
|
"@types/debug": "^4.1.12",
|
|
60
67
|
"@types/inquirer": "^9.0.7",
|
|
68
|
+
"@types/jest": "^30.0.0",
|
|
61
69
|
"@types/node": "^22.10.2",
|
|
70
|
+
"@types/react": "^19.1.13",
|
|
62
71
|
"@typescript-eslint/eslint-plugin": "^8.20.0",
|
|
63
72
|
"@typescript-eslint/parser": "^8.20.0",
|
|
64
73
|
"eslint": "^9.17.0",
|
|
74
|
+
"jest": "^30.1.3",
|
|
65
75
|
"prettier": "^3.6.2",
|
|
76
|
+
"ts-jest": "^29.4.1",
|
|
66
77
|
"ts-node": "^10.9.2",
|
|
78
|
+
"tsx": "^4.20.5",
|
|
67
79
|
"typescript": "^5.7.2"
|
|
68
80
|
},
|
|
69
81
|
"engines": {
|