@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.
Files changed (215) hide show
  1. package/dist/commands/cluster/index.d.ts +1 -2
  2. package/dist/commands/cluster/index.js +5 -3
  3. package/dist/commands/completion.js +2 -159
  4. package/dist/commands/config.d.ts +3 -0
  5. package/dist/commands/config.js +321 -38
  6. package/dist/commands/generate/config.js +24 -5
  7. package/dist/commands/generate/generators/agent.js +2 -2
  8. package/dist/commands/generate/generators/mcpserver.d.ts +1 -2
  9. package/dist/commands/generate/generators/mcpserver.js +5 -26
  10. package/dist/commands/generate/generators/project.js +41 -22
  11. package/dist/commands/generate/generators/team.js +2 -2
  12. package/dist/commands/generate/index.d.ts +1 -2
  13. package/dist/commands/generate/index.js +1 -1
  14. package/dist/components/statusChecker.d.ts +23 -13
  15. package/dist/components/statusChecker.js +129 -295
  16. package/dist/config.d.ts +22 -3
  17. package/dist/config.js +161 -10
  18. package/dist/index.d.ts +1 -1
  19. package/dist/index.js +42 -44
  20. package/dist/lib/cluster.d.ts +1 -2
  21. package/dist/lib/cluster.js +16 -37
  22. package/dist/lib/config.d.ts +80 -28
  23. package/dist/lib/config.js +205 -70
  24. package/dist/lib/consts.d.ts +1 -0
  25. package/dist/lib/consts.js +2 -0
  26. package/dist/lib/errors.js +1 -1
  27. package/dist/lib/exec.d.ts +4 -0
  28. package/dist/lib/exec.js +11 -0
  29. package/dist/lib/types.d.ts +3 -17
  30. package/dist/ui/MainMenu.d.ts +1 -5
  31. package/dist/ui/MainMenu.js +91 -222
  32. package/dist/ui/statusFormatter.d.ts +7 -22
  33. package/dist/ui/statusFormatter.js +39 -39
  34. package/package.json +5 -17
  35. package/dist/arkServices.d.ts +0 -42
  36. package/dist/arkServices.js +0 -138
  37. package/dist/arkServices.spec.d.ts +0 -1
  38. package/dist/arkServices.spec.js +0 -24
  39. package/dist/charts/charts.d.ts +0 -5
  40. package/dist/charts/charts.js +0 -6
  41. package/dist/charts/dependencies.d.ts +0 -6
  42. package/dist/charts/dependencies.js +0 -50
  43. package/dist/charts/types.d.ts +0 -40
  44. package/dist/charts/types.js +0 -1
  45. package/dist/commands/agents/index.d.ts +0 -3
  46. package/dist/commands/agents/index.js +0 -51
  47. package/dist/commands/agents/index.spec.d.ts +0 -1
  48. package/dist/commands/agents/index.spec.js +0 -67
  49. package/dist/commands/agents/selector.d.ts +0 -8
  50. package/dist/commands/agents/selector.js +0 -53
  51. package/dist/commands/agents.d.ts +0 -2
  52. package/dist/commands/agents.js +0 -53
  53. package/dist/commands/chat/index.d.ts +0 -3
  54. package/dist/commands/chat/index.js +0 -29
  55. package/dist/commands/chat.d.ts +0 -2
  56. package/dist/commands/chat.js +0 -45
  57. package/dist/commands/cluster/get.d.ts +0 -2
  58. package/dist/commands/cluster/get.js +0 -39
  59. package/dist/commands/cluster/get.spec.d.ts +0 -1
  60. package/dist/commands/cluster/get.spec.js +0 -92
  61. package/dist/commands/cluster/index.spec.d.ts +0 -1
  62. package/dist/commands/cluster/index.spec.js +0 -24
  63. package/dist/commands/completion/index.d.ts +0 -3
  64. package/dist/commands/completion/index.js +0 -290
  65. package/dist/commands/completion/index.spec.d.ts +0 -1
  66. package/dist/commands/completion/index.spec.js +0 -34
  67. package/dist/commands/config/index.d.ts +0 -3
  68. package/dist/commands/config/index.js +0 -42
  69. package/dist/commands/config/index.spec.d.ts +0 -1
  70. package/dist/commands/config/index.spec.js +0 -78
  71. package/dist/commands/dashboard/index.d.ts +0 -4
  72. package/dist/commands/dashboard/index.js +0 -39
  73. package/dist/commands/dashboard.d.ts +0 -3
  74. package/dist/commands/dashboard.js +0 -39
  75. package/dist/commands/dev/index.d.ts +0 -3
  76. package/dist/commands/dev/index.js +0 -9
  77. package/dist/commands/dev/tool/check.d.ts +0 -2
  78. package/dist/commands/dev/tool/check.js +0 -142
  79. package/dist/commands/dev/tool/clean.d.ts +0 -2
  80. package/dist/commands/dev/tool/clean.js +0 -153
  81. package/dist/commands/dev/tool/generate.d.ts +0 -2
  82. package/dist/commands/dev/tool/generate.js +0 -28
  83. package/dist/commands/dev/tool/index.d.ts +0 -2
  84. package/dist/commands/dev/tool/index.js +0 -14
  85. package/dist/commands/dev/tool/init.d.ts +0 -2
  86. package/dist/commands/dev/tool/init.js +0 -320
  87. package/dist/commands/dev/tool/shared.d.ts +0 -5
  88. package/dist/commands/dev/tool/shared.js +0 -256
  89. package/dist/commands/dev/tool/status.d.ts +0 -2
  90. package/dist/commands/dev/tool/status.js +0 -136
  91. package/dist/commands/dev/tool-generate.spec.d.ts +0 -1
  92. package/dist/commands/dev/tool-generate.spec.js +0 -163
  93. package/dist/commands/dev/tool.d.ts +0 -2
  94. package/dist/commands/dev/tool.js +0 -559
  95. package/dist/commands/dev/tool.spec.d.ts +0 -1
  96. package/dist/commands/dev/tool.spec.js +0 -48
  97. package/dist/commands/docs/index.d.ts +0 -4
  98. package/dist/commands/docs/index.js +0 -18
  99. package/dist/commands/install/index.d.ts +0 -8
  100. package/dist/commands/install/index.js +0 -300
  101. package/dist/commands/install/index.spec.d.ts +0 -1
  102. package/dist/commands/install/index.spec.js +0 -143
  103. package/dist/commands/install.d.ts +0 -3
  104. package/dist/commands/install.js +0 -147
  105. package/dist/commands/models/create.d.ts +0 -1
  106. package/dist/commands/models/create.js +0 -213
  107. package/dist/commands/models/create.spec.d.ts +0 -1
  108. package/dist/commands/models/create.spec.js +0 -125
  109. package/dist/commands/models/index.d.ts +0 -3
  110. package/dist/commands/models/index.js +0 -60
  111. package/dist/commands/models/index.spec.d.ts +0 -1
  112. package/dist/commands/models/index.spec.js +0 -76
  113. package/dist/commands/models/selector.d.ts +0 -8
  114. package/dist/commands/models/selector.js +0 -53
  115. package/dist/commands/query/index.d.ts +0 -3
  116. package/dist/commands/query/index.js +0 -131
  117. package/dist/commands/routes/index.d.ts +0 -3
  118. package/dist/commands/routes/index.js +0 -93
  119. package/dist/commands/routes.d.ts +0 -2
  120. package/dist/commands/routes.js +0 -101
  121. package/dist/commands/status/index.d.ts +0 -4
  122. package/dist/commands/status/index.js +0 -262
  123. package/dist/commands/status.d.ts +0 -3
  124. package/dist/commands/status.js +0 -33
  125. package/dist/commands/targets/index.d.ts +0 -3
  126. package/dist/commands/targets/index.js +0 -65
  127. package/dist/commands/targets/index.spec.d.ts +0 -1
  128. package/dist/commands/targets/index.spec.js +0 -105
  129. package/dist/commands/targets.d.ts +0 -2
  130. package/dist/commands/targets.js +0 -65
  131. package/dist/commands/teams/index.d.ts +0 -3
  132. package/dist/commands/teams/index.js +0 -49
  133. package/dist/commands/teams/index.spec.d.ts +0 -1
  134. package/dist/commands/teams/index.spec.js +0 -70
  135. package/dist/commands/teams/selector.d.ts +0 -8
  136. package/dist/commands/teams/selector.js +0 -55
  137. package/dist/commands/tools/index.d.ts +0 -3
  138. package/dist/commands/tools/index.js +0 -49
  139. package/dist/commands/tools/index.spec.d.ts +0 -1
  140. package/dist/commands/tools/index.spec.js +0 -70
  141. package/dist/commands/tools/selector.d.ts +0 -8
  142. package/dist/commands/tools/selector.js +0 -53
  143. package/dist/commands/uninstall/index.d.ts +0 -3
  144. package/dist/commands/uninstall/index.js +0 -106
  145. package/dist/commands/uninstall/index.spec.d.ts +0 -1
  146. package/dist/commands/uninstall/index.spec.js +0 -125
  147. package/dist/commands/uninstall.d.ts +0 -2
  148. package/dist/commands/uninstall.js +0 -83
  149. package/dist/components/ChatUI.d.ts +0 -16
  150. package/dist/components/ChatUI.js +0 -801
  151. package/dist/components/StatusView.d.ts +0 -10
  152. package/dist/components/StatusView.js +0 -39
  153. package/dist/lib/arkApiClient.d.ts +0 -53
  154. package/dist/lib/arkApiClient.js +0 -102
  155. package/dist/lib/arkApiProxy.d.ts +0 -9
  156. package/dist/lib/arkApiProxy.js +0 -22
  157. package/dist/lib/arkServiceProxy.d.ts +0 -14
  158. package/dist/lib/arkServiceProxy.js +0 -95
  159. package/dist/lib/arkStatus.d.ts +0 -10
  160. package/dist/lib/arkStatus.js +0 -79
  161. package/dist/lib/arkStatus.spec.d.ts +0 -1
  162. package/dist/lib/arkStatus.spec.js +0 -49
  163. package/dist/lib/chatClient.d.ts +0 -33
  164. package/dist/lib/chatClient.js +0 -99
  165. package/dist/lib/cluster.spec.d.ts +0 -1
  166. package/dist/lib/cluster.spec.js +0 -338
  167. package/dist/lib/commandUtils.d.ts +0 -4
  168. package/dist/lib/commandUtils.js +0 -18
  169. package/dist/lib/commandUtils.test.d.ts +0 -1
  170. package/dist/lib/commandUtils.test.js +0 -44
  171. package/dist/lib/commands.d.ts +0 -16
  172. package/dist/lib/commands.js +0 -29
  173. package/dist/lib/commands.spec.d.ts +0 -1
  174. package/dist/lib/commands.spec.js +0 -146
  175. package/dist/lib/config.spec.d.ts +0 -1
  176. package/dist/lib/config.spec.js +0 -99
  177. package/dist/lib/config.test.d.ts +0 -1
  178. package/dist/lib/config.test.js +0 -93
  179. package/dist/lib/consts.spec.d.ts +0 -1
  180. package/dist/lib/consts.spec.js +0 -15
  181. package/dist/lib/dev/tools/analyzer.d.ts +0 -30
  182. package/dist/lib/dev/tools/analyzer.js +0 -190
  183. package/dist/lib/dev/tools/discover_tools.py +0 -392
  184. package/dist/lib/dev/tools/mcp-types.d.ts +0 -28
  185. package/dist/lib/dev/tools/mcp-types.js +0 -86
  186. package/dist/lib/dev/tools/types.d.ts +0 -50
  187. package/dist/lib/dev/tools/types.js +0 -1
  188. package/dist/lib/errors.spec.d.ts +0 -1
  189. package/dist/lib/errors.spec.js +0 -221
  190. package/dist/lib/nextSteps.d.ts +0 -4
  191. package/dist/lib/nextSteps.js +0 -20
  192. package/dist/lib/nextSteps.spec.d.ts +0 -1
  193. package/dist/lib/nextSteps.spec.js +0 -59
  194. package/dist/lib/output.d.ts +0 -36
  195. package/dist/lib/output.js +0 -89
  196. package/dist/lib/output.spec.d.ts +0 -1
  197. package/dist/lib/output.spec.js +0 -123
  198. package/dist/lib/portUtils.d.ts +0 -8
  199. package/dist/lib/portUtils.js +0 -39
  200. package/dist/lib/startup.d.ts +0 -9
  201. package/dist/lib/startup.js +0 -93
  202. package/dist/lib/startup.spec.d.ts +0 -1
  203. package/dist/lib/startup.spec.js +0 -168
  204. package/dist/types/types.d.ts +0 -40
  205. package/dist/types/types.js +0 -1
  206. package/dist/ui/AgentSelector.d.ts +0 -8
  207. package/dist/ui/AgentSelector.js +0 -53
  208. package/dist/ui/ModelSelector.d.ts +0 -8
  209. package/dist/ui/ModelSelector.js +0 -53
  210. package/dist/ui/TeamSelector.d.ts +0 -8
  211. package/dist/ui/TeamSelector.js +0 -55
  212. package/dist/ui/ToolSelector.d.ts +0 -8
  213. package/dist/ui/ToolSelector.js +0 -53
  214. package/dist/ui/statusFormatter.spec.d.ts +0 -1
  215. package/dist/ui/statusFormatter.spec.js +0 -58
package/dist/config.js CHANGED
@@ -1,22 +1,118 @@
1
+ import { promises as fs } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
1
4
  import axios from 'axios';
2
5
  import Debug from 'debug';
3
- import { DEFAULT_ADDRESS_ARK_API } from './lib/consts.js';
6
+ import { ArkClient } from './lib/arkClient.js';
7
+ import { DEFAULT_ADDRESS_ARK_API, CONFIG_DIR_NAME, CONFIG_FILE_NAME, } from './lib/consts.js';
8
+ import { GatewayManager } from './lib/gatewayManager.js';
4
9
  import { KubernetesConfigManager } from './lib/kubernetes.js';
5
- import { getStatusCheckableServices } from './arkServices.js';
6
10
  const debug = Debug('ark:config');
7
11
  /**
8
- * ConfigManager handles API URL discovery and cluster access testing.
9
- * Complex discovery logic can be debugged by setting DEBUG=ark:config
12
+ * ConfigManager handles ARK CLI configuration with automatic service discovery
13
+ * and multiple fallback mechanisms. Complex discovery logic can be debugged by
14
+ * setting DEBUG=ark:config or DEBUG=ark:* environment variable.
10
15
  *
11
16
  * Example usage:
12
- * DEBUG=ark:config ark status
17
+ * DEBUG=ark:config ark check status
18
+ * DEBUG=ark:* ark dashboard
13
19
  */
14
20
  export class ConfigManager {
15
21
  constructor() {
16
22
  this.kubeConfig = null;
23
+ this.configDir = join(homedir(), '.config', CONFIG_DIR_NAME);
24
+ this.configFile = join(this.configDir, CONFIG_FILE_NAME);
17
25
  this.kubernetesManager = new KubernetesConfigManager();
26
+ this.gatewayManager = new GatewayManager();
27
+ }
28
+ async ensureConfigDir() {
29
+ try {
30
+ await fs.mkdir(this.configDir, { recursive: true });
31
+ }
32
+ catch (_error) {
33
+ // Directory might already exist
34
+ }
35
+ }
36
+ async loadConfig() {
37
+ await this.ensureConfigDir();
38
+ try {
39
+ // Check if config file exists
40
+ await fs.access(this.configFile);
41
+ }
42
+ catch (error) {
43
+ // Config file doesn't exist - start with default config and enrich with kube config
44
+ if (error &&
45
+ typeof error === 'object' &&
46
+ 'code' in error &&
47
+ error.code === 'ENOENT') {
48
+ return await this.getDefaultConfig();
49
+ }
50
+ // Other access errors (permissions, etc.) should be thrown
51
+ throw error;
52
+ }
53
+ try {
54
+ // Config file exists - try to read and parse it
55
+ const data = await fs.readFile(this.configFile, 'utf-8');
56
+ const config = JSON.parse(data);
57
+ // Merge with current Kubernetes config if not present
58
+ await this.initKubernetesConfig();
59
+ return {
60
+ ...config,
61
+ kubeconfig: config.kubeconfig || this.kubeConfig?.kubeconfig,
62
+ currentContext: config.currentContext || this.kubeConfig?.currentContext,
63
+ kubeNamespace: config.kubeNamespace || this.kubeConfig?.namespace,
64
+ };
65
+ }
66
+ catch (error) {
67
+ // If it's a JSON parsing error, throw a clear error message
68
+ if (error instanceof SyntaxError) {
69
+ throw new Error(`Invalid JSON in config file ${this.configFile}: ${error.message}`);
70
+ }
71
+ // Other errors (read errors, etc.) should be thrown as-is
72
+ throw error;
73
+ }
74
+ }
75
+ async saveConfig(config) {
76
+ await this.ensureConfigDir();
77
+ const jsonData = JSON.stringify(config, null, 2);
78
+ await fs.writeFile(this.configFile, jsonData);
79
+ }
80
+ async updateConfig(updates) {
81
+ const currentConfig = await this.loadConfig();
82
+ const newConfig = { ...currentConfig, ...updates };
83
+ await this.saveConfig(newConfig);
84
+ return newConfig;
85
+ }
86
+ async getDefaultConfig() {
87
+ // Initialize Kubernetes config to get defaults
88
+ await this.initKubernetesConfig();
89
+ return {
90
+ defaultAgent: 'default',
91
+ defaultModel: 'default',
92
+ defaultNamespace: this.kubeConfig?.namespace || 'default',
93
+ apiBaseUrl: DEFAULT_ADDRESS_ARK_API,
94
+ kubeconfig: this.kubeConfig?.kubeconfig,
95
+ currentContext: this.kubeConfig?.currentContext,
96
+ kubeNamespace: this.kubeConfig?.namespace,
97
+ };
98
+ }
99
+ async initializeConfig() {
100
+ const config = await this.loadConfig();
101
+ const defaultConfig = await this.getDefaultConfig();
102
+ const mergedConfig = { ...defaultConfig, ...config };
103
+ await this.saveConfig(mergedConfig);
104
+ return mergedConfig;
105
+ }
106
+ getConfigPath() {
107
+ return this.configFile;
18
108
  }
19
109
  async getApiBaseUrl() {
110
+ const config = await this.loadConfig();
111
+ // If apiBaseUrl is explicitly set in config, use it
112
+ if (config.apiBaseUrl && config.apiBaseUrl !== DEFAULT_ADDRESS_ARK_API) {
113
+ debug('using explicit config apiBaseUrl: %s', config.apiBaseUrl);
114
+ return config.apiBaseUrl;
115
+ }
20
116
  // First try to detect localhost-gateway (works for everyone with standard setup)
21
117
  if (await this.isLocalhostGatewayRunning()) {
22
118
  const gatewayUrls = this.getLocalhostGatewayUrls();
@@ -30,7 +126,7 @@ export class ConfigManager {
30
126
  await this.initKubernetesConfig();
31
127
  if (this.kubeConfig) {
32
128
  try {
33
- const namespace = 'default';
129
+ const namespace = config.kubeNamespace || config.defaultNamespace || 'default';
34
130
  const discoveredUrl = await this.kubernetesManager.getArkApiUrl(namespace);
35
131
  debug('kubernetes discovery successful in %s: %s', namespace, discoveredUrl);
36
132
  return discoveredUrl;
@@ -40,8 +136,9 @@ export class ConfigManager {
40
136
  // Fall back to default if discovery fails
41
137
  }
42
138
  }
43
- debug('falling back to default: %s', DEFAULT_ADDRESS_ARK_API);
44
- return DEFAULT_ADDRESS_ARK_API;
139
+ const fallbackUrl = config.apiBaseUrl || DEFAULT_ADDRESS_ARK_API;
140
+ debug('falling back to default: %s', fallbackUrl);
141
+ return fallbackUrl;
45
142
  }
46
143
  /**
47
144
  * Check if localhost-gateway is running by testing port 8080
@@ -66,8 +163,16 @@ export class ConfigManager {
66
163
  * Construct standard localhost-gateway URLs for known ARK services
67
164
  */
68
165
  getLocalhostGatewayUrls() {
69
- // Use centralized service definitions from arkServices
70
- return getStatusCheckableServices();
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;
71
176
  }
72
177
  async initKubernetesConfig() {
73
178
  if (!this.kubeConfig) {
@@ -82,6 +187,10 @@ export class ConfigManager {
82
187
  }
83
188
  }
84
189
  }
190
+ async getKubernetesConfig() {
191
+ await this.initKubernetesConfig();
192
+ return this.kubeConfig;
193
+ }
85
194
  async testClusterAccess() {
86
195
  await this.initKubernetesConfig();
87
196
  if (!this.kubeConfig) {
@@ -89,4 +198,46 @@ export class ConfigManager {
89
198
  }
90
199
  return await this.kubernetesManager.testClusterAccess();
91
200
  }
201
+ /**
202
+ * Discover service URLs from ark-api service discovery
203
+ */
204
+ async discoverServicesFromApi() {
205
+ try {
206
+ const apiBaseUrl = await this.getApiBaseUrl();
207
+ const arkClient = new ArkClient(apiBaseUrl);
208
+ const config = await this.loadConfig();
209
+ const namespace = config.kubeNamespace || config.defaultNamespace || 'default';
210
+ debug('service discovery: querying ark-api at %s (namespace: %s)', apiBaseUrl, namespace);
211
+ const services = await arkClient.getArkServices(namespace);
212
+ const serviceUrls = {};
213
+ // Dynamically map all discovered services with HTTP routes
214
+ for (const service of services) {
215
+ if (service.httproutes && service.httproutes.length > 0) {
216
+ const serviceName = service.release_name || service.name;
217
+ const serviceUrl = service.httproutes[0].url; // Use first route URL
218
+ serviceUrls[serviceName] = serviceUrl;
219
+ }
220
+ }
221
+ const discoveredServices = Object.entries(serviceUrls).map(([key, url]) => `${key}: ${url}`);
222
+ debug('service discovery: found %d services - %s', discoveredServices.length, discoveredServices.join(', ') || 'none');
223
+ return serviceUrls;
224
+ }
225
+ catch (error) {
226
+ debug('service discovery failed: %s', error instanceof Error ? error.message : error);
227
+ // Return empty object if discovery fails - will fall back to config/defaults
228
+ return {};
229
+ }
230
+ }
231
+ async getServiceUrls() {
232
+ // Try localhost-gateway detection (works for everyone with standard setup)
233
+ if (await this.isLocalhostGatewayRunning()) {
234
+ const gatewayUrls = this.getLocalhostGatewayUrls();
235
+ debug('localhost-gateway detected, using: %o', gatewayUrls);
236
+ return gatewayUrls;
237
+ }
238
+ // Try to discover services from ark-api (requires kubeconfig)
239
+ const discoveredUrls = await this.discoverServicesFromApi();
240
+ debug('discovered services: %o', discoveredUrls);
241
+ return discoveredUrls;
242
+ }
92
243
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- #!/usr/bin/env NODE_NO_WARNINGS=1 node
1
+ #!/usr/bin/env node
2
2
  export {};
package/dist/index.js CHANGED
@@ -1,69 +1,67 @@
1
- #!/usr/bin/env NODE_NO_WARNINGS=1 node
1
+ #!/usr/bin/env node
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
+ import chalk from 'chalk';
3
4
  import { Command } from 'commander';
4
5
  import { render } from 'ink';
5
6
  import { createRequire } from 'module';
6
7
  const require = createRequire(import.meta.url);
7
8
  const packageJson = require('../package.json');
8
- import output from './lib/output.js';
9
- import { startup } from './lib/startup.js';
10
- import { createAgentsCommand } from './commands/agents/index.js';
11
- import { createChatCommand } from './commands/chat/index.js';
12
9
  import { createClusterCommand } from './commands/cluster/index.js';
13
- import { createCompletionCommand } from './commands/completion/index.js';
14
- import { createDashboardCommand } from './commands/dashboard/index.js';
15
- import { createDocsCommand } from './commands/docs/index.js';
16
- import { createDevCommand } from './commands/dev/index.js';
10
+ import { createCompletionCommand } from './commands/completion.js';
17
11
  import { createGenerateCommand } from './commands/generate/index.js';
18
- import { createInstallCommand } from './commands/install/index.js';
19
- import { createModelsCommand } from './commands/models/index.js';
20
- import { createQueryCommand } from './commands/query/index.js';
21
- import { createUninstallCommand } from './commands/uninstall/index.js';
22
- import { createStatusCommand } from './commands/status/index.js';
23
- import { createConfigCommand } from './commands/config/index.js';
24
- import { createTargetsCommand } from './commands/targets/index.js';
25
- import { createTeamsCommand } from './commands/teams/index.js';
26
- import { createToolsCommand } from './commands/tools/index.js';
27
- import { createRoutesCommand } from './commands/routes/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';
28
16
  import MainMenu from './ui/MainMenu.js';
29
- function showMainMenu(config) {
30
- const app = render(_jsx(MainMenu, { config: config }));
31
- globalThis.inkApp = app;
17
+ import { StatusFormatter } from './ui/statusFormatter.js';
18
+ 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
+ }
32
37
  }
33
38
  async function main() {
34
- // Initialize CLI - check requirements and load config
35
- const config = await startup();
36
39
  const program = new Command();
37
40
  program
38
41
  .name(packageJson.name)
39
42
  .description(packageJson.description)
40
43
  .version(packageJson.version);
41
- program.addCommand(createAgentsCommand(config));
42
- program.addCommand(createChatCommand(config));
43
- program.addCommand(createClusterCommand(config));
44
- program.addCommand(createCompletionCommand(config));
45
- program.addCommand(createDashboardCommand(config));
46
- program.addCommand(createDocsCommand(config));
47
- program.addCommand(createDevCommand(config));
48
- program.addCommand(createGenerateCommand(config));
49
- program.addCommand(createInstallCommand(config));
50
- program.addCommand(createModelsCommand(config));
51
- program.addCommand(createQueryCommand(config));
52
- program.addCommand(createUninstallCommand(config));
53
- program.addCommand(createStatusCommand(config));
54
- program.addCommand(createConfigCommand(config));
55
- program.addCommand(createTargetsCommand(config));
56
- program.addCommand(createTeamsCommand(config));
57
- program.addCommand(createToolsCommand(config));
58
- program.addCommand(createRoutesCommand(config));
44
+ program.addCommand(createClusterCommand());
45
+ program.addCommand(createCompletionCommand());
46
+ program.addCommand(createGenerateCommand());
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);
59
56
  // If no args provided, show interactive menu
60
57
  if (process.argv.length === 2) {
61
- showMainMenu(config);
58
+ console.log();
59
+ showMainMenu();
62
60
  return;
63
61
  }
64
62
  await program.parseAsync(process.argv);
65
63
  }
66
64
  main().catch((error) => {
67
- output.error('failed to start ark cli: ', error);
65
+ console.error(chalk.red('Failed to start ARK CLI:'), error);
68
66
  process.exit(1);
69
67
  });
@@ -2,8 +2,7 @@ export interface ClusterInfo {
2
2
  type: 'minikube' | 'kind' | 'k3s' | 'docker-desktop' | 'cloud' | 'unknown';
3
3
  ip?: string;
4
4
  context?: string;
5
- namespace?: string;
6
5
  error?: string;
7
6
  }
8
7
  export declare function detectClusterType(): Promise<ClusterInfo>;
9
- export declare function getClusterInfo(context?: string): Promise<ClusterInfo>;
8
+ export declare function getClusterIp(_context?: string): Promise<ClusterInfo>;
@@ -1,7 +1,10 @@
1
- import { execa } from 'execa';
1
+ import { executeCommand } from './exec.js';
2
2
  export async function detectClusterType() {
3
3
  try {
4
- const { stdout } = await execa('kubectl', ['config', 'current-context']);
4
+ const { stdout } = await executeCommand('kubectl', [
5
+ 'config',
6
+ 'current-context',
7
+ ]);
5
8
  const context = stdout.trim();
6
9
  if (context.includes('minikube')) {
7
10
  return { type: 'minikube', context };
@@ -25,33 +28,12 @@ export async function detectClusterType() {
25
28
  }
26
29
  }
27
30
  catch (error) {
28
- return {
29
- type: 'unknown',
30
- error: error instanceof Error ? error.message : 'Unknown error',
31
- };
31
+ return { type: 'unknown', error: error.message };
32
32
  }
33
33
  }
34
- export async function getClusterInfo(context) {
34
+ export async function getClusterIp(_context) {
35
35
  try {
36
- // If context is provided, use it
37
- const contextArgs = context ? ['--context', context] : [];
38
- // Get all config info in one command
39
- const { stdout: configJson } = await execa('kubectl', [
40
- 'config',
41
- 'view',
42
- '--minify',
43
- '-o',
44
- 'json',
45
- ...contextArgs,
46
- ]);
47
- const config = JSON.parse(configJson);
48
- const currentContext = config['current-context'] || '';
49
- const contextData = config.contexts?.find((c) => c.name === currentContext);
50
- const namespace = contextData?.context?.namespace || 'default';
51
- // Detect cluster type from context name
52
36
  const clusterInfo = await detectClusterType();
53
- clusterInfo.context = currentContext;
54
- clusterInfo.namespace = namespace;
55
37
  if (clusterInfo.error) {
56
38
  return clusterInfo;
57
39
  }
@@ -59,12 +41,12 @@ export async function getClusterInfo(context) {
59
41
  switch (clusterInfo.type) {
60
42
  case 'minikube':
61
43
  try {
62
- const { stdout } = await execa('minikube', ['ip']);
44
+ const { stdout } = await executeCommand('minikube', ['ip']);
63
45
  ip = stdout.trim();
64
46
  }
65
47
  catch {
66
48
  // Fallback to kubectl if minikube command fails
67
- const { stdout } = await execa('kubectl', [
49
+ const { stdout } = await executeCommand('kubectl', [
68
50
  'get',
69
51
  'nodes',
70
52
  '-o',
@@ -74,7 +56,7 @@ export async function getClusterInfo(context) {
74
56
  }
75
57
  break;
76
58
  case 'kind': {
77
- const { stdout: kindOutput } = await execa('kubectl', [
59
+ const { stdout: kindOutput } = await executeCommand('kubectl', [
78
60
  'get',
79
61
  'nodes',
80
62
  '-o',
@@ -87,7 +69,7 @@ export async function getClusterInfo(context) {
87
69
  ip = 'localhost';
88
70
  break;
89
71
  case 'k3s': {
90
- const { stdout: k3sOutput } = await execa('kubectl', [
72
+ const { stdout: k3sOutput } = await executeCommand('kubectl', [
91
73
  'get',
92
74
  'nodes',
93
75
  '-o',
@@ -99,7 +81,7 @@ export async function getClusterInfo(context) {
99
81
  case 'cloud':
100
82
  // For cloud clusters, try to get the external IP or load balancer IP
101
83
  try {
102
- const { stdout: lbOutput } = await execa('kubectl', [
84
+ const { stdout: lbOutput } = await executeCommand('kubectl', [
103
85
  'get',
104
86
  'svc',
105
87
  '-n',
@@ -110,7 +92,7 @@ export async function getClusterInfo(context) {
110
92
  ]);
111
93
  ip = lbOutput.trim();
112
94
  if (!ip) {
113
- const { stdout: hostnameOutput } = await execa('kubectl', [
95
+ const { stdout: hostnameOutput } = await executeCommand('kubectl', [
114
96
  'get',
115
97
  'svc',
116
98
  '-n',
@@ -124,7 +106,7 @@ export async function getClusterInfo(context) {
124
106
  }
125
107
  catch {
126
108
  // Fallback to node IP
127
- const { stdout: nodeOutput } = await execa('kubectl', [
109
+ const { stdout: nodeOutput } = await executeCommand('kubectl', [
128
110
  'get',
129
111
  'nodes',
130
112
  '-o',
@@ -134,7 +116,7 @@ export async function getClusterInfo(context) {
134
116
  }
135
117
  break;
136
118
  default: {
137
- const { stdout: defaultOutput } = await execa('kubectl', [
119
+ const { stdout: defaultOutput } = await executeCommand('kubectl', [
138
120
  'get',
139
121
  'nodes',
140
122
  '-o',
@@ -147,9 +129,6 @@ export async function getClusterInfo(context) {
147
129
  return { ...clusterInfo, ip };
148
130
  }
149
131
  catch (error) {
150
- return {
151
- type: 'unknown',
152
- error: error instanceof Error ? error.message : 'Unknown error',
153
- };
132
+ return { type: 'unknown', error: error.message };
154
133
  }
155
134
  }
@@ -1,30 +1,82 @@
1
- import type { ClusterInfo } from './cluster.js';
2
- export interface ChatConfig {
3
- streaming?: boolean;
4
- outputFormat?: 'text' | 'markdown';
5
- }
6
- export interface ArkConfig {
7
- chat?: ChatConfig;
8
- latestVersion?: string;
9
- currentVersion?: string;
10
- clusterInfo?: ClusterInfo;
11
- }
12
- /**
13
- * Load configuration from multiple sources with proper precedence:
14
- * 1. Defaults
15
- * 2. ~/.arkrc.yaml (user config)
16
- * 3. .arkrc.yaml (project config)
17
- * 4. Environment variables (override all)
18
- */
19
- export declare function loadConfig(): ArkConfig;
20
1
  /**
21
- * Get the paths checked for config files
2
+ * Configuration management for ARK CLI
22
3
  */
23
- export declare function getConfigPaths(): {
24
- user: string;
25
- project: string;
26
- };
27
- /**
28
- * Format config as YAML for display
29
- */
30
- export declare function formatConfig(config: ArkConfig): string;
4
+ export interface ArkConfig {
5
+ defaultProjectType: 'empty' | 'with-samples';
6
+ defaultDestination: string;
7
+ skipGitByDefault: boolean;
8
+ skipModelsbyDefault: boolean;
9
+ preferredEditor: string;
10
+ colorOutput: boolean;
11
+ verboseOutput: boolean;
12
+ defaultModelProvider: 'azure' | 'openai' | 'claude' | 'gemini' | 'custom';
13
+ templateDirectory?: string;
14
+ customTemplates: Record<string, string>;
15
+ parallelOperations: boolean;
16
+ maxConcurrentFiles: number;
17
+ fileWatchingEnabled: boolean;
18
+ telemetryEnabled: boolean;
19
+ errorReporting: boolean;
20
+ }
21
+ export declare const DEFAULT_CONFIG: ArkConfig;
22
+ export declare class ConfigManager {
23
+ private configPath;
24
+ private config;
25
+ constructor();
26
+ /**
27
+ * Get the path to the configuration file
28
+ */
29
+ private getConfigPath;
30
+ /**
31
+ * Load configuration from file or create with defaults
32
+ */
33
+ private loadConfig;
34
+ /**
35
+ * Save configuration to file
36
+ */
37
+ private saveConfig;
38
+ /**
39
+ * Get the current configuration
40
+ */
41
+ getConfig(): ArkConfig;
42
+ /**
43
+ * Update configuration
44
+ */
45
+ updateConfig(updates: Partial<ArkConfig>): void;
46
+ /**
47
+ * Reset configuration to defaults
48
+ */
49
+ resetConfig(): void;
50
+ /**
51
+ * Get a specific configuration value
52
+ */
53
+ get<K extends keyof ArkConfig>(key: K): ArkConfig[K];
54
+ /**
55
+ * Set a specific configuration value
56
+ */
57
+ set<K extends keyof ArkConfig>(key: K, value: ArkConfig[K]): void;
58
+ /**
59
+ * Validate configuration values
60
+ */
61
+ validateConfig(): void;
62
+ /**
63
+ * Get environment variable overrides
64
+ */
65
+ getEnvironmentOverrides(): Partial<ArkConfig>;
66
+ /**
67
+ * Get merged configuration with environment overrides
68
+ */
69
+ getMergedConfig(): ArkConfig;
70
+ /**
71
+ * Export configuration for backup
72
+ */
73
+ exportConfig(): string;
74
+ /**
75
+ * Import configuration from backup
76
+ */
77
+ importConfig(configJson: string): void;
78
+ /**
79
+ * Get configuration file path for CLI display
80
+ */
81
+ getConfigFilePath(): string;
82
+ }