@agents-at-scale/ark 0.1.62 → 0.1.63
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.
|
@@ -6,5 +6,6 @@ export declare function installArk(config: ArkConfig, serviceNames?: string[], o
|
|
|
6
6
|
verbose?: boolean;
|
|
7
7
|
arkVersion?: string;
|
|
8
8
|
marketplaceVersion?: string;
|
|
9
|
+
backend?: string;
|
|
9
10
|
}): Promise<void>;
|
|
10
11
|
export declare function createInstallCommand(config: ArkConfig): Command;
|
|
@@ -10,7 +10,43 @@ import { printNextSteps } from '../../lib/nextSteps.js';
|
|
|
10
10
|
import ora from 'ora';
|
|
11
11
|
import { waitForServicesReady, } from '../../lib/waitForReady.js';
|
|
12
12
|
import { parseTimeoutToSeconds } from '../../lib/timeout.js';
|
|
13
|
-
import {
|
|
13
|
+
import { runReadinessChecks } from '../../lib/readinessChecks.js';
|
|
14
|
+
function validatePostgresConfig(pg) {
|
|
15
|
+
if (!pg) {
|
|
16
|
+
throw new Error("missing 'storage.postgresql' block in .arkrc.yaml");
|
|
17
|
+
}
|
|
18
|
+
for (const key of ['host', 'user', 'passwordSecretName']) {
|
|
19
|
+
if (!pg[key]) {
|
|
20
|
+
throw new Error(`missing required field storage.postgresql.${key} in .arkrc.yaml`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return pg;
|
|
24
|
+
}
|
|
25
|
+
function backendInstallArgs(service, backend, values) {
|
|
26
|
+
if (backend === 'etcd')
|
|
27
|
+
return [];
|
|
28
|
+
if (!values)
|
|
29
|
+
return [];
|
|
30
|
+
if (service.helmReleaseName === 'ark-controller') {
|
|
31
|
+
return ['--set', 'storage.backend=postgresql'];
|
|
32
|
+
}
|
|
33
|
+
if (service.helmReleaseName === 'ark-apiserver') {
|
|
34
|
+
const args = [];
|
|
35
|
+
args.push('--set', `postgresql.host=${values.host}`);
|
|
36
|
+
if (values.port !== undefined)
|
|
37
|
+
args.push('--set', `postgresql.port=${values.port}`);
|
|
38
|
+
if (values.database)
|
|
39
|
+
args.push('--set', `postgresql.database=${values.database}`);
|
|
40
|
+
args.push('--set', `postgresql.user=${values.user}`);
|
|
41
|
+
args.push('--set', `postgresql.passwordSecretName=${values.passwordSecretName}`);
|
|
42
|
+
if (values.passwordSecretKey)
|
|
43
|
+
args.push('--set', `postgresql.passwordSecretKey=${values.passwordSecretKey}`);
|
|
44
|
+
if (values.sslMode)
|
|
45
|
+
args.push('--set', `postgresql.sslMode=${values.sslMode}`);
|
|
46
|
+
return args;
|
|
47
|
+
}
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
14
50
|
function isValidVersion(version) {
|
|
15
51
|
return /^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/.test(version);
|
|
16
52
|
}
|
|
@@ -76,7 +112,7 @@ async function checkAndCleanFailedRelease(releaseName, namespace, verbose = fals
|
|
|
76
112
|
// Ignore errors - prerequisite may not exist
|
|
77
113
|
}
|
|
78
114
|
}
|
|
79
|
-
async function installService(service, verbose = false, arkVersionOverride, marketplaceVersionOverride,
|
|
115
|
+
async function installService(service, verbose = false, arkVersionOverride, marketplaceVersionOverride, extraArgs) {
|
|
80
116
|
await uninstallPrerequisites(service, verbose);
|
|
81
117
|
await checkAndCleanFailedRelease(service.helmReleaseName, service.namespace, verbose);
|
|
82
118
|
let chartPath = service.chartPath;
|
|
@@ -112,6 +148,8 @@ async function installService(service, verbose = false, arkVersionOverride, mark
|
|
|
112
148
|
}
|
|
113
149
|
// Add any additional install args
|
|
114
150
|
helmArgs.push(...(service.installArgs || []));
|
|
151
|
+
if (extraArgs)
|
|
152
|
+
helmArgs.push(...extraArgs);
|
|
115
153
|
await execute('helm', helmArgs, {
|
|
116
154
|
stdout: 'inherit',
|
|
117
155
|
stderr: 'pipe',
|
|
@@ -141,7 +179,22 @@ export async function installArk(config, serviceNames = [], options = {}) {
|
|
|
141
179
|
// Show cluster info
|
|
142
180
|
output.success(`connected to cluster: ${chalk.bold(clusterInfo.context)}`);
|
|
143
181
|
console.log(); // Add blank line after cluster info
|
|
144
|
-
const
|
|
182
|
+
const requestedBackend = options.backend ?? config.storage?.backend ?? 'etcd';
|
|
183
|
+
if (requestedBackend !== 'etcd' && requestedBackend !== 'postgresql') {
|
|
184
|
+
output.error(`Invalid backend value: ${requestedBackend}. Expected 'etcd' or 'postgresql'.`);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
const backend = requestedBackend;
|
|
188
|
+
let postgresValues;
|
|
189
|
+
if (backend === 'postgresql') {
|
|
190
|
+
try {
|
|
191
|
+
postgresValues = validatePostgresConfig(config.storage?.postgresql);
|
|
192
|
+
}
|
|
193
|
+
catch (err) {
|
|
194
|
+
output.error(`${err instanceof Error ? err.message : String(err)}`);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
145
198
|
// If specific services are requested, install only those services
|
|
146
199
|
if (serviceNames.length > 0) {
|
|
147
200
|
for (const serviceName of serviceNames) {
|
|
@@ -176,7 +229,7 @@ export async function installArk(config, serviceNames = [], options = {}) {
|
|
|
176
229
|
}
|
|
177
230
|
output.info(`installing marketplace item ${service.name}...`);
|
|
178
231
|
try {
|
|
179
|
-
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion);
|
|
232
|
+
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion, []);
|
|
180
233
|
output.success(`${service.name} installed successfully`);
|
|
181
234
|
}
|
|
182
235
|
catch (error) {
|
|
@@ -199,8 +252,26 @@ export async function installArk(config, serviceNames = [], options = {}) {
|
|
|
199
252
|
}
|
|
200
253
|
output.info(`installing ${service.name}...`);
|
|
201
254
|
try {
|
|
202
|
-
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion);
|
|
255
|
+
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion, backendInstallArgs(service, backend, postgresValues));
|
|
203
256
|
output.success(`${service.name} installed successfully`);
|
|
257
|
+
// Wait for ark-apiserver to be ready before continuing to other services
|
|
258
|
+
if (service.helmReleaseName === 'ark-apiserver' && backend === 'postgresql') {
|
|
259
|
+
const spinner = ora('Waiting for ark-apiserver to be ready...').start();
|
|
260
|
+
try {
|
|
261
|
+
const results = await runReadinessChecks(120); // 2 minute timeout
|
|
262
|
+
const failed = results.find((r) => !r.passed);
|
|
263
|
+
if (failed) {
|
|
264
|
+
spinner.fail(`ark-apiserver readiness check failed: ${failed.message || 'unknown error'}`);
|
|
265
|
+
output.error('ark-apiserver is not ready. Stopping installation.');
|
|
266
|
+
process.exit(1);
|
|
267
|
+
}
|
|
268
|
+
spinner.succeed('ark-apiserver is ready');
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
spinner.fail('Failed to check ark-apiserver readiness');
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
204
275
|
}
|
|
205
276
|
catch (error) {
|
|
206
277
|
if (handleInstallError(error, service, options)) {
|
|
@@ -341,7 +412,25 @@ export async function installArk(config, serviceNames = [], options = {}) {
|
|
|
341
412
|
}
|
|
342
413
|
output.info(`installing ${service.name}...`);
|
|
343
414
|
try {
|
|
344
|
-
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion);
|
|
415
|
+
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion, backendInstallArgs(service, backend, postgresValues));
|
|
416
|
+
// Wait for ark-apiserver to be ready before continuing to other services
|
|
417
|
+
if (service.helmReleaseName === 'ark-apiserver' && backend === 'postgresql') {
|
|
418
|
+
const spinner = ora('Waiting for ark-apiserver to be ready...').start();
|
|
419
|
+
try {
|
|
420
|
+
const results = await runReadinessChecks(120); // 2 minute timeout
|
|
421
|
+
const failed = results.find((r) => !r.passed);
|
|
422
|
+
if (failed) {
|
|
423
|
+
spinner.fail(`ark-apiserver readiness check failed: ${failed.message || 'unknown error'}`);
|
|
424
|
+
output.error('ark-apiserver is not ready. Stopping installation.');
|
|
425
|
+
process.exit(1);
|
|
426
|
+
}
|
|
427
|
+
spinner.succeed('ark-apiserver is ready');
|
|
428
|
+
}
|
|
429
|
+
catch (error) {
|
|
430
|
+
spinner.fail('Failed to check ark-apiserver readiness');
|
|
431
|
+
throw error;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
345
434
|
console.log(); // Add blank line after command output
|
|
346
435
|
}
|
|
347
436
|
catch (error) {
|
|
@@ -383,7 +472,7 @@ export async function installArk(config, serviceNames = [], options = {}) {
|
|
|
383
472
|
for (const service of sortedServices) {
|
|
384
473
|
output.info(`installing ${service.name}...`);
|
|
385
474
|
try {
|
|
386
|
-
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion);
|
|
475
|
+
await installService(service, options.verbose, options.arkVersion, options.marketplaceVersion, backendInstallArgs(service, backend, postgresValues));
|
|
387
476
|
console.log(); // Add blank line after command output
|
|
388
477
|
}
|
|
389
478
|
catch (error) {
|
|
@@ -447,6 +536,7 @@ export function createInstallCommand(config) {
|
|
|
447
536
|
.option('--ark-version <version>', 'ARK version to install (e.g., 0.1.50, defaults to CLI version)')
|
|
448
537
|
.option('--marketplace-version <version>', 'Marketplace item version to install (e.g., 0.1.5)')
|
|
449
538
|
.option('--wait-for-ready <timeout>', 'wait for Ark to be ready after installation (e.g., 30s, 2m)')
|
|
539
|
+
.option('--backend <type>', "storage backend: 'etcd' (default) or 'postgresql' (overrides storage.backend in .arkrc.yaml)")
|
|
450
540
|
.option('-v, --verbose', 'show commands being executed')
|
|
451
541
|
.action(async (services, options) => {
|
|
452
542
|
await installArk(config, services, options);
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -8,6 +8,19 @@ export interface MarketplaceConfig {
|
|
|
8
8
|
repoUrl?: string;
|
|
9
9
|
registry?: string;
|
|
10
10
|
}
|
|
11
|
+
export interface PostgresStorageConfig {
|
|
12
|
+
host: string;
|
|
13
|
+
port?: number | string;
|
|
14
|
+
database?: string;
|
|
15
|
+
user: string;
|
|
16
|
+
passwordSecretName: string;
|
|
17
|
+
passwordSecretKey?: string;
|
|
18
|
+
sslMode?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface StorageConfig {
|
|
21
|
+
backend?: 'etcd' | 'postgresql';
|
|
22
|
+
postgresql?: PostgresStorageConfig;
|
|
23
|
+
}
|
|
11
24
|
export interface ArkConfig {
|
|
12
25
|
chat?: ChatConfig;
|
|
13
26
|
marketplace?: MarketplaceConfig;
|
|
@@ -15,6 +28,7 @@ export interface ArkConfig {
|
|
|
15
28
|
reusePortForwards?: boolean;
|
|
16
29
|
[serviceName: string]: Partial<ArkService> | boolean | undefined;
|
|
17
30
|
};
|
|
31
|
+
storage?: StorageConfig;
|
|
18
32
|
queryTimeout?: string;
|
|
19
33
|
defaultExportTypes?: string[];
|
|
20
34
|
clusterInfo?: ClusterInfo;
|
package/dist/lib/config.js
CHANGED
|
@@ -80,6 +80,13 @@ export function loadConfig() {
|
|
|
80
80
|
config.services.reusePortForwards =
|
|
81
81
|
process.env.ARK_SERVICES_REUSE_PORT_FORWARDS === '1';
|
|
82
82
|
}
|
|
83
|
+
if (process.env.ARK_STORAGE_BACKEND !== undefined) {
|
|
84
|
+
const backend = process.env.ARK_STORAGE_BACKEND;
|
|
85
|
+
if (backend === 'etcd' || backend === 'postgresql') {
|
|
86
|
+
config.storage = config.storage || {};
|
|
87
|
+
config.storage.backend = backend;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
83
90
|
return config;
|
|
84
91
|
}
|
|
85
92
|
/**
|
|
@@ -119,6 +126,18 @@ function mergeConfig(target, source) {
|
|
|
119
126
|
}
|
|
120
127
|
}
|
|
121
128
|
}
|
|
129
|
+
if (source.storage) {
|
|
130
|
+
target.storage = target.storage || {};
|
|
131
|
+
if (source.storage.backend !== undefined) {
|
|
132
|
+
target.storage.backend = source.storage.backend;
|
|
133
|
+
}
|
|
134
|
+
if (source.storage.postgresql) {
|
|
135
|
+
target.storage.postgresql = {
|
|
136
|
+
...target.storage.postgresql,
|
|
137
|
+
...source.storage.postgresql,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
122
141
|
if (source.queryTimeout !== undefined) {
|
|
123
142
|
target.queryTimeout = source.queryTimeout;
|
|
124
143
|
}
|
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.63",
|
|
4
4
|
"description": "Ark CLI - Interactive terminal interface for ARK agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"overrides": {
|
|
88
88
|
"minimatch": "^10.2.3",
|
|
89
89
|
"rollup": "4.59.0",
|
|
90
|
-
"hono": "^4.12.
|
|
90
|
+
"hono": "^4.12.18",
|
|
91
91
|
"@hono/node-server": "^1.19.13",
|
|
92
92
|
"flatted": "^3.4.2",
|
|
93
93
|
"tar": "^7.5.11",
|
package/templates/tool/uv.lock
CHANGED
|
@@ -772,11 +772,11 @@ wheels = [
|
|
|
772
772
|
|
|
773
773
|
[[package]]
|
|
774
774
|
name = "python-multipart"
|
|
775
|
-
version = "0.0.
|
|
775
|
+
version = "0.0.27"
|
|
776
776
|
source = { registry = "https://pypi.org/simple" }
|
|
777
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
777
|
+
sdist = { url = "https://files.pythonhosted.org/packages/69/9b/f23807317a113dc36e74e75eb265a02dd1a4d9082abc3c1064acd22997c4/python_multipart-0.0.27.tar.gz", hash = "sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602", size = 44043, upload-time = "2026-04-27T10:51:26.649Z" }
|
|
778
778
|
wheels = [
|
|
779
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
779
|
+
{ url = "https://files.pythonhosted.org/packages/99/78/4126abcbdbd3c559d43e0db7f7b9173fc6befe45d39a2856cc0b8ec2a5a6/python_multipart-0.0.27-py3-none-any.whl", hash = "sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645", size = 29254, upload-time = "2026-04-27T10:51:24.997Z" },
|
|
780
780
|
]
|
|
781
781
|
|
|
782
782
|
[[package]]
|