@vm0/cli 8.0.2 → 8.1.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/index.js +806 -775
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { Command as Command45 } from "commander";
|
|
5
|
-
import
|
|
5
|
+
import chalk46 from "chalk";
|
|
6
6
|
|
|
7
7
|
// src/lib/api/auth.ts
|
|
8
8
|
import chalk from "chalk";
|
|
@@ -142,16 +142,16 @@ Authentication failed: ${tokenResult.error_description ?? tokenResult.error}`
|
|
|
142
142
|
}
|
|
143
143
|
async function logout() {
|
|
144
144
|
await clearConfig();
|
|
145
|
-
console.log(chalk.green("Successfully logged out"));
|
|
145
|
+
console.log(chalk.green("\u2713 Successfully logged out"));
|
|
146
146
|
console.log("Your credentials have been cleared.");
|
|
147
147
|
}
|
|
148
148
|
async function checkAuthStatus() {
|
|
149
149
|
const config = await loadConfig();
|
|
150
150
|
if (config.token) {
|
|
151
|
-
console.log(chalk.green("Authenticated"));
|
|
151
|
+
console.log(chalk.green("\u2713 Authenticated"));
|
|
152
152
|
console.log("You are logged in to VM0.");
|
|
153
153
|
} else {
|
|
154
|
-
console.log(chalk.
|
|
154
|
+
console.log(chalk.red("\u2717 Not authenticated"));
|
|
155
155
|
console.log("Run 'vm0 auth login' to authenticate.");
|
|
156
156
|
}
|
|
157
157
|
if (process.env.VM0_TOKEN) {
|
|
@@ -161,7 +161,7 @@ async function checkAuthStatus() {
|
|
|
161
161
|
async function setupToken() {
|
|
162
162
|
const token = await getToken();
|
|
163
163
|
if (!token) {
|
|
164
|
-
console.error(chalk.red("
|
|
164
|
+
console.error(chalk.red("\u2717 Not authenticated"));
|
|
165
165
|
console.error("");
|
|
166
166
|
console.error("To get a token for CI/CD:");
|
|
167
167
|
console.error(" 1. Run 'vm0 auth login' to authenticate");
|
|
@@ -189,7 +189,6 @@ import { readFile as readFile4 } from "fs/promises";
|
|
|
189
189
|
import { existsSync as existsSync3 } from "fs";
|
|
190
190
|
import { dirname as dirname2 } from "path";
|
|
191
191
|
import { parse as parseYaml2 } from "yaml";
|
|
192
|
-
import prompts from "prompts";
|
|
193
192
|
|
|
194
193
|
// ../../packages/core/src/variable-expander.ts
|
|
195
194
|
var VARIABLE_PATTERN = /\$\{\{\s*(env|vars|secrets|credentials)\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;
|
|
@@ -1609,13 +1608,11 @@ var scopeResponseSchema = z12.object({
|
|
|
1609
1608
|
id: z12.string().uuid(),
|
|
1610
1609
|
slug: z12.string(),
|
|
1611
1610
|
type: scopeTypeSchema,
|
|
1612
|
-
displayName: z12.string().nullable(),
|
|
1613
1611
|
createdAt: z12.string(),
|
|
1614
1612
|
updatedAt: z12.string()
|
|
1615
1613
|
});
|
|
1616
1614
|
var createScopeRequestSchema = z12.object({
|
|
1617
|
-
slug: scopeSlugSchema
|
|
1618
|
-
displayName: z12.string().max(128).optional()
|
|
1615
|
+
slug: scopeSlugSchema
|
|
1619
1616
|
});
|
|
1620
1617
|
var updateScopeRequestSchema = z12.object({
|
|
1621
1618
|
slug: scopeSlugSchema,
|
|
@@ -2285,6 +2282,9 @@ var realtimeTokenContract = c14.router({
|
|
|
2285
2282
|
}
|
|
2286
2283
|
});
|
|
2287
2284
|
|
|
2285
|
+
// ../../packages/core/src/contracts/platform.ts
|
|
2286
|
+
import { z as z19 } from "zod";
|
|
2287
|
+
|
|
2288
2288
|
// ../../packages/core/src/contracts/public/common.ts
|
|
2289
2289
|
import { z as z18 } from "zod";
|
|
2290
2290
|
var publicApiErrorTypeSchema = z18.enum([
|
|
@@ -2325,29 +2325,92 @@ var listQuerySchema = z18.object({
|
|
|
2325
2325
|
var requestIdSchema = z18.string().uuid();
|
|
2326
2326
|
var timestampSchema = z18.string().datetime();
|
|
2327
2327
|
|
|
2328
|
-
// ../../packages/core/src/contracts/
|
|
2329
|
-
import { z as z19 } from "zod";
|
|
2328
|
+
// ../../packages/core/src/contracts/platform.ts
|
|
2330
2329
|
var c15 = initContract();
|
|
2331
|
-
var
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2330
|
+
var platformLogStatusSchema = z19.enum([
|
|
2331
|
+
"pending",
|
|
2332
|
+
"running",
|
|
2333
|
+
"completed",
|
|
2334
|
+
"failed",
|
|
2335
|
+
"timeout",
|
|
2336
|
+
"cancelled"
|
|
2337
|
+
]);
|
|
2338
|
+
var platformLogEntrySchema = z19.object({
|
|
2339
|
+
id: z19.string().uuid()
|
|
2340
|
+
});
|
|
2341
|
+
var platformLogsListResponseSchema = createPaginatedResponseSchema(
|
|
2342
|
+
platformLogEntrySchema
|
|
2343
|
+
);
|
|
2344
|
+
var artifactSchema = z19.object({
|
|
2345
|
+
name: z19.string().nullable(),
|
|
2346
|
+
version: z19.string().nullable()
|
|
2347
|
+
});
|
|
2348
|
+
var platformLogDetailSchema = z19.object({
|
|
2349
|
+
id: z19.string().uuid(),
|
|
2350
|
+
sessionId: z19.string().nullable(),
|
|
2351
|
+
agentName: z19.string(),
|
|
2352
|
+
provider: z19.string(),
|
|
2353
|
+
status: platformLogStatusSchema,
|
|
2354
|
+
prompt: z19.string(),
|
|
2355
|
+
error: z19.string().nullable(),
|
|
2356
|
+
createdAt: z19.string(),
|
|
2357
|
+
startedAt: z19.string().nullable(),
|
|
2358
|
+
completedAt: z19.string().nullable(),
|
|
2359
|
+
artifact: artifactSchema
|
|
2360
|
+
});
|
|
2361
|
+
var platformLogsListContract = c15.router({
|
|
2362
|
+
list: {
|
|
2363
|
+
method: "GET",
|
|
2364
|
+
path: "/api/platform/logs",
|
|
2365
|
+
query: listQuerySchema.extend({
|
|
2366
|
+
search: z19.string().optional()
|
|
2367
|
+
}),
|
|
2368
|
+
responses: {
|
|
2369
|
+
200: platformLogsListResponseSchema,
|
|
2370
|
+
401: apiErrorSchema
|
|
2371
|
+
},
|
|
2372
|
+
summary: "List agent run logs with pagination"
|
|
2373
|
+
}
|
|
2374
|
+
});
|
|
2375
|
+
var platformLogsByIdContract = c15.router({
|
|
2376
|
+
getById: {
|
|
2377
|
+
method: "GET",
|
|
2378
|
+
path: "/api/platform/logs/:id",
|
|
2379
|
+
pathParams: z19.object({
|
|
2380
|
+
id: z19.string().uuid("Invalid log ID")
|
|
2381
|
+
}),
|
|
2382
|
+
responses: {
|
|
2383
|
+
200: platformLogDetailSchema,
|
|
2384
|
+
401: apiErrorSchema,
|
|
2385
|
+
404: apiErrorSchema
|
|
2386
|
+
},
|
|
2387
|
+
summary: "Get agent run log details by ID"
|
|
2388
|
+
}
|
|
2389
|
+
});
|
|
2390
|
+
|
|
2391
|
+
// ../../packages/core/src/contracts/public/agents.ts
|
|
2392
|
+
import { z as z20 } from "zod";
|
|
2393
|
+
var c16 = initContract();
|
|
2394
|
+
var publicAgentSchema = z20.object({
|
|
2395
|
+
id: z20.string(),
|
|
2396
|
+
name: z20.string(),
|
|
2397
|
+
current_version_id: z20.string().nullable(),
|
|
2335
2398
|
created_at: timestampSchema,
|
|
2336
2399
|
updated_at: timestampSchema
|
|
2337
2400
|
});
|
|
2338
|
-
var agentVersionSchema =
|
|
2339
|
-
id:
|
|
2340
|
-
agent_id:
|
|
2341
|
-
version_number:
|
|
2401
|
+
var agentVersionSchema = z20.object({
|
|
2402
|
+
id: z20.string(),
|
|
2403
|
+
agent_id: z20.string(),
|
|
2404
|
+
version_number: z20.number(),
|
|
2342
2405
|
created_at: timestampSchema
|
|
2343
2406
|
});
|
|
2344
2407
|
var publicAgentDetailSchema = publicAgentSchema;
|
|
2345
2408
|
var paginatedAgentsSchema = createPaginatedResponseSchema(publicAgentSchema);
|
|
2346
2409
|
var paginatedAgentVersionsSchema = createPaginatedResponseSchema(agentVersionSchema);
|
|
2347
2410
|
var agentListQuerySchema = listQuerySchema.extend({
|
|
2348
|
-
name:
|
|
2411
|
+
name: z20.string().optional()
|
|
2349
2412
|
});
|
|
2350
|
-
var publicAgentsListContract =
|
|
2413
|
+
var publicAgentsListContract = c16.router({
|
|
2351
2414
|
list: {
|
|
2352
2415
|
method: "GET",
|
|
2353
2416
|
path: "/v1/agents",
|
|
@@ -2362,13 +2425,13 @@ var publicAgentsListContract = c15.router({
|
|
|
2362
2425
|
description: "List all agents in the current scope with pagination. Use the `name` query parameter to filter by agent name."
|
|
2363
2426
|
}
|
|
2364
2427
|
});
|
|
2365
|
-
var publicAgentByIdContract =
|
|
2428
|
+
var publicAgentByIdContract = c16.router({
|
|
2366
2429
|
get: {
|
|
2367
2430
|
method: "GET",
|
|
2368
2431
|
path: "/v1/agents/:id",
|
|
2369
2432
|
headers: authHeadersSchema,
|
|
2370
|
-
pathParams:
|
|
2371
|
-
id:
|
|
2433
|
+
pathParams: z20.object({
|
|
2434
|
+
id: z20.string().min(1, "Agent ID is required")
|
|
2372
2435
|
}),
|
|
2373
2436
|
responses: {
|
|
2374
2437
|
200: publicAgentDetailSchema,
|
|
@@ -2380,13 +2443,13 @@ var publicAgentByIdContract = c15.router({
|
|
|
2380
2443
|
description: "Get agent details by ID"
|
|
2381
2444
|
}
|
|
2382
2445
|
});
|
|
2383
|
-
var publicAgentVersionsContract =
|
|
2446
|
+
var publicAgentVersionsContract = c16.router({
|
|
2384
2447
|
list: {
|
|
2385
2448
|
method: "GET",
|
|
2386
2449
|
path: "/v1/agents/:id/versions",
|
|
2387
2450
|
headers: authHeadersSchema,
|
|
2388
|
-
pathParams:
|
|
2389
|
-
id:
|
|
2451
|
+
pathParams: z20.object({
|
|
2452
|
+
id: z20.string().min(1, "Agent ID is required")
|
|
2390
2453
|
}),
|
|
2391
2454
|
query: listQuerySchema,
|
|
2392
2455
|
responses: {
|
|
@@ -2401,9 +2464,9 @@ var publicAgentVersionsContract = c15.router({
|
|
|
2401
2464
|
});
|
|
2402
2465
|
|
|
2403
2466
|
// ../../packages/core/src/contracts/public/runs.ts
|
|
2404
|
-
import { z as
|
|
2405
|
-
var
|
|
2406
|
-
var publicRunStatusSchema =
|
|
2467
|
+
import { z as z21 } from "zod";
|
|
2468
|
+
var c17 = initContract();
|
|
2469
|
+
var publicRunStatusSchema = z21.enum([
|
|
2407
2470
|
"pending",
|
|
2408
2471
|
"running",
|
|
2409
2472
|
"completed",
|
|
@@ -2411,56 +2474,56 @@ var publicRunStatusSchema = z20.enum([
|
|
|
2411
2474
|
"timeout",
|
|
2412
2475
|
"cancelled"
|
|
2413
2476
|
]);
|
|
2414
|
-
var publicRunSchema =
|
|
2415
|
-
id:
|
|
2416
|
-
agent_id:
|
|
2417
|
-
agent_name:
|
|
2477
|
+
var publicRunSchema = z21.object({
|
|
2478
|
+
id: z21.string(),
|
|
2479
|
+
agent_id: z21.string(),
|
|
2480
|
+
agent_name: z21.string(),
|
|
2418
2481
|
status: publicRunStatusSchema,
|
|
2419
|
-
prompt:
|
|
2482
|
+
prompt: z21.string(),
|
|
2420
2483
|
created_at: timestampSchema,
|
|
2421
2484
|
started_at: timestampSchema.nullable(),
|
|
2422
2485
|
completed_at: timestampSchema.nullable()
|
|
2423
2486
|
});
|
|
2424
2487
|
var publicRunDetailSchema = publicRunSchema.extend({
|
|
2425
|
-
error:
|
|
2426
|
-
execution_time_ms:
|
|
2427
|
-
checkpoint_id:
|
|
2428
|
-
session_id:
|
|
2429
|
-
artifact_name:
|
|
2430
|
-
artifact_version:
|
|
2431
|
-
volumes:
|
|
2488
|
+
error: z21.string().nullable(),
|
|
2489
|
+
execution_time_ms: z21.number().nullable(),
|
|
2490
|
+
checkpoint_id: z21.string().nullable(),
|
|
2491
|
+
session_id: z21.string().nullable(),
|
|
2492
|
+
artifact_name: z21.string().nullable(),
|
|
2493
|
+
artifact_version: z21.string().nullable(),
|
|
2494
|
+
volumes: z21.record(z21.string(), z21.string()).optional()
|
|
2432
2495
|
});
|
|
2433
2496
|
var paginatedRunsSchema = createPaginatedResponseSchema(publicRunSchema);
|
|
2434
|
-
var createRunRequestSchema =
|
|
2497
|
+
var createRunRequestSchema = z21.object({
|
|
2435
2498
|
// Agent identification (one of: agent, agent_id, session_id, checkpoint_id)
|
|
2436
|
-
agent:
|
|
2499
|
+
agent: z21.string().optional(),
|
|
2437
2500
|
// Agent name
|
|
2438
|
-
agent_id:
|
|
2501
|
+
agent_id: z21.string().optional(),
|
|
2439
2502
|
// Agent ID
|
|
2440
|
-
agent_version:
|
|
2503
|
+
agent_version: z21.string().optional(),
|
|
2441
2504
|
// Version specifier (e.g., "latest", "v1", specific ID)
|
|
2442
2505
|
// Continue session
|
|
2443
|
-
session_id:
|
|
2506
|
+
session_id: z21.string().optional(),
|
|
2444
2507
|
// Resume from checkpoint
|
|
2445
|
-
checkpoint_id:
|
|
2508
|
+
checkpoint_id: z21.string().optional(),
|
|
2446
2509
|
// Required
|
|
2447
|
-
prompt:
|
|
2510
|
+
prompt: z21.string().min(1, "Prompt is required"),
|
|
2448
2511
|
// Optional configuration
|
|
2449
|
-
variables:
|
|
2450
|
-
secrets:
|
|
2451
|
-
artifact_name:
|
|
2512
|
+
variables: z21.record(z21.string(), z21.string()).optional(),
|
|
2513
|
+
secrets: z21.record(z21.string(), z21.string()).optional(),
|
|
2514
|
+
artifact_name: z21.string().optional(),
|
|
2452
2515
|
// Artifact name to mount
|
|
2453
|
-
artifact_version:
|
|
2516
|
+
artifact_version: z21.string().optional(),
|
|
2454
2517
|
// Artifact version (defaults to latest)
|
|
2455
|
-
volumes:
|
|
2518
|
+
volumes: z21.record(z21.string(), z21.string()).optional()
|
|
2456
2519
|
// volume_name -> version
|
|
2457
2520
|
});
|
|
2458
2521
|
var runListQuerySchema = listQuerySchema.extend({
|
|
2459
|
-
agent_id:
|
|
2522
|
+
agent_id: z21.string().optional(),
|
|
2460
2523
|
status: publicRunStatusSchema.optional(),
|
|
2461
2524
|
since: timestampSchema.optional()
|
|
2462
2525
|
});
|
|
2463
|
-
var publicRunsListContract =
|
|
2526
|
+
var publicRunsListContract = c17.router({
|
|
2464
2527
|
list: {
|
|
2465
2528
|
method: "GET",
|
|
2466
2529
|
path: "/v1/runs",
|
|
@@ -2491,13 +2554,13 @@ var publicRunsListContract = c16.router({
|
|
|
2491
2554
|
description: "Create and execute a new agent run. Returns 202 Accepted as runs execute asynchronously."
|
|
2492
2555
|
}
|
|
2493
2556
|
});
|
|
2494
|
-
var publicRunByIdContract =
|
|
2557
|
+
var publicRunByIdContract = c17.router({
|
|
2495
2558
|
get: {
|
|
2496
2559
|
method: "GET",
|
|
2497
2560
|
path: "/v1/runs/:id",
|
|
2498
2561
|
headers: authHeadersSchema,
|
|
2499
|
-
pathParams:
|
|
2500
|
-
id:
|
|
2562
|
+
pathParams: z21.object({
|
|
2563
|
+
id: z21.string().min(1, "Run ID is required")
|
|
2501
2564
|
}),
|
|
2502
2565
|
responses: {
|
|
2503
2566
|
200: publicRunDetailSchema,
|
|
@@ -2509,15 +2572,15 @@ var publicRunByIdContract = c16.router({
|
|
|
2509
2572
|
description: "Get run details by ID"
|
|
2510
2573
|
}
|
|
2511
2574
|
});
|
|
2512
|
-
var publicRunCancelContract =
|
|
2575
|
+
var publicRunCancelContract = c17.router({
|
|
2513
2576
|
cancel: {
|
|
2514
2577
|
method: "POST",
|
|
2515
2578
|
path: "/v1/runs/:id/cancel",
|
|
2516
2579
|
headers: authHeadersSchema,
|
|
2517
|
-
pathParams:
|
|
2518
|
-
id:
|
|
2580
|
+
pathParams: z21.object({
|
|
2581
|
+
id: z21.string().min(1, "Run ID is required")
|
|
2519
2582
|
}),
|
|
2520
|
-
body:
|
|
2583
|
+
body: z21.undefined(),
|
|
2521
2584
|
responses: {
|
|
2522
2585
|
200: publicRunDetailSchema,
|
|
2523
2586
|
400: publicApiErrorSchema,
|
|
@@ -2530,27 +2593,27 @@ var publicRunCancelContract = c16.router({
|
|
|
2530
2593
|
description: "Cancel a pending or running execution"
|
|
2531
2594
|
}
|
|
2532
2595
|
});
|
|
2533
|
-
var logEntrySchema =
|
|
2596
|
+
var logEntrySchema = z21.object({
|
|
2534
2597
|
timestamp: timestampSchema,
|
|
2535
|
-
type:
|
|
2536
|
-
level:
|
|
2537
|
-
message:
|
|
2538
|
-
metadata:
|
|
2598
|
+
type: z21.enum(["agent", "system", "network"]),
|
|
2599
|
+
level: z21.enum(["debug", "info", "warn", "error"]),
|
|
2600
|
+
message: z21.string(),
|
|
2601
|
+
metadata: z21.record(z21.string(), z21.unknown()).optional()
|
|
2539
2602
|
});
|
|
2540
2603
|
var paginatedLogsSchema = createPaginatedResponseSchema(logEntrySchema);
|
|
2541
2604
|
var logsQuerySchema = listQuerySchema.extend({
|
|
2542
|
-
type:
|
|
2605
|
+
type: z21.enum(["agent", "system", "network", "all"]).default("all"),
|
|
2543
2606
|
since: timestampSchema.optional(),
|
|
2544
2607
|
until: timestampSchema.optional(),
|
|
2545
|
-
order:
|
|
2608
|
+
order: z21.enum(["asc", "desc"]).default("asc")
|
|
2546
2609
|
});
|
|
2547
|
-
var publicRunLogsContract =
|
|
2610
|
+
var publicRunLogsContract = c17.router({
|
|
2548
2611
|
getLogs: {
|
|
2549
2612
|
method: "GET",
|
|
2550
2613
|
path: "/v1/runs/:id/logs",
|
|
2551
2614
|
headers: authHeadersSchema,
|
|
2552
|
-
pathParams:
|
|
2553
|
-
id:
|
|
2615
|
+
pathParams: z21.object({
|
|
2616
|
+
id: z21.string().min(1, "Run ID is required")
|
|
2554
2617
|
}),
|
|
2555
2618
|
query: logsQuerySchema,
|
|
2556
2619
|
responses: {
|
|
@@ -2563,30 +2626,30 @@ var publicRunLogsContract = c16.router({
|
|
|
2563
2626
|
description: "Get unified logs for a run. Combines agent, system, and network logs."
|
|
2564
2627
|
}
|
|
2565
2628
|
});
|
|
2566
|
-
var metricPointSchema =
|
|
2629
|
+
var metricPointSchema = z21.object({
|
|
2567
2630
|
timestamp: timestampSchema,
|
|
2568
|
-
cpu_percent:
|
|
2569
|
-
memory_used_mb:
|
|
2570
|
-
memory_total_mb:
|
|
2571
|
-
disk_used_mb:
|
|
2572
|
-
disk_total_mb:
|
|
2573
|
-
});
|
|
2574
|
-
var metricsSummarySchema =
|
|
2575
|
-
avg_cpu_percent:
|
|
2576
|
-
max_memory_used_mb:
|
|
2577
|
-
total_duration_ms:
|
|
2578
|
-
});
|
|
2579
|
-
var metricsResponseSchema2 =
|
|
2580
|
-
data:
|
|
2631
|
+
cpu_percent: z21.number(),
|
|
2632
|
+
memory_used_mb: z21.number(),
|
|
2633
|
+
memory_total_mb: z21.number(),
|
|
2634
|
+
disk_used_mb: z21.number(),
|
|
2635
|
+
disk_total_mb: z21.number()
|
|
2636
|
+
});
|
|
2637
|
+
var metricsSummarySchema = z21.object({
|
|
2638
|
+
avg_cpu_percent: z21.number(),
|
|
2639
|
+
max_memory_used_mb: z21.number(),
|
|
2640
|
+
total_duration_ms: z21.number().nullable()
|
|
2641
|
+
});
|
|
2642
|
+
var metricsResponseSchema2 = z21.object({
|
|
2643
|
+
data: z21.array(metricPointSchema),
|
|
2581
2644
|
summary: metricsSummarySchema
|
|
2582
2645
|
});
|
|
2583
|
-
var publicRunMetricsContract =
|
|
2646
|
+
var publicRunMetricsContract = c17.router({
|
|
2584
2647
|
getMetrics: {
|
|
2585
2648
|
method: "GET",
|
|
2586
2649
|
path: "/v1/runs/:id/metrics",
|
|
2587
2650
|
headers: authHeadersSchema,
|
|
2588
|
-
pathParams:
|
|
2589
|
-
id:
|
|
2651
|
+
pathParams: z21.object({
|
|
2652
|
+
id: z21.string().min(1, "Run ID is required")
|
|
2590
2653
|
}),
|
|
2591
2654
|
responses: {
|
|
2592
2655
|
200: metricsResponseSchema2,
|
|
@@ -2598,7 +2661,7 @@ var publicRunMetricsContract = c16.router({
|
|
|
2598
2661
|
description: "Get CPU, memory, and disk metrics for a run"
|
|
2599
2662
|
}
|
|
2600
2663
|
});
|
|
2601
|
-
var sseEventTypeSchema =
|
|
2664
|
+
var sseEventTypeSchema = z21.enum([
|
|
2602
2665
|
"status",
|
|
2603
2666
|
// Run status change
|
|
2604
2667
|
"output",
|
|
@@ -2610,26 +2673,26 @@ var sseEventTypeSchema = z20.enum([
|
|
|
2610
2673
|
"heartbeat"
|
|
2611
2674
|
// Keep-alive
|
|
2612
2675
|
]);
|
|
2613
|
-
var sseEventSchema =
|
|
2676
|
+
var sseEventSchema = z21.object({
|
|
2614
2677
|
event: sseEventTypeSchema,
|
|
2615
|
-
data:
|
|
2616
|
-
id:
|
|
2678
|
+
data: z21.unknown(),
|
|
2679
|
+
id: z21.string().optional()
|
|
2617
2680
|
// For Last-Event-ID reconnection
|
|
2618
2681
|
});
|
|
2619
|
-
var publicRunEventsContract =
|
|
2682
|
+
var publicRunEventsContract = c17.router({
|
|
2620
2683
|
streamEvents: {
|
|
2621
2684
|
method: "GET",
|
|
2622
2685
|
path: "/v1/runs/:id/events",
|
|
2623
2686
|
headers: authHeadersSchema,
|
|
2624
|
-
pathParams:
|
|
2625
|
-
id:
|
|
2687
|
+
pathParams: z21.object({
|
|
2688
|
+
id: z21.string().min(1, "Run ID is required")
|
|
2626
2689
|
}),
|
|
2627
|
-
query:
|
|
2628
|
-
last_event_id:
|
|
2690
|
+
query: z21.object({
|
|
2691
|
+
last_event_id: z21.string().optional()
|
|
2629
2692
|
// For reconnection
|
|
2630
2693
|
}),
|
|
2631
2694
|
responses: {
|
|
2632
|
-
200:
|
|
2695
|
+
200: z21.any(),
|
|
2633
2696
|
// SSE stream - actual content is text/event-stream
|
|
2634
2697
|
401: publicApiErrorSchema,
|
|
2635
2698
|
404: publicApiErrorSchema,
|
|
@@ -2641,28 +2704,28 @@ var publicRunEventsContract = c16.router({
|
|
|
2641
2704
|
});
|
|
2642
2705
|
|
|
2643
2706
|
// ../../packages/core/src/contracts/public/artifacts.ts
|
|
2644
|
-
import { z as
|
|
2645
|
-
var
|
|
2646
|
-
var publicArtifactSchema =
|
|
2647
|
-
id:
|
|
2648
|
-
name:
|
|
2649
|
-
current_version_id:
|
|
2650
|
-
size:
|
|
2707
|
+
import { z as z22 } from "zod";
|
|
2708
|
+
var c18 = initContract();
|
|
2709
|
+
var publicArtifactSchema = z22.object({
|
|
2710
|
+
id: z22.string(),
|
|
2711
|
+
name: z22.string(),
|
|
2712
|
+
current_version_id: z22.string().nullable(),
|
|
2713
|
+
size: z22.number(),
|
|
2651
2714
|
// Total size in bytes
|
|
2652
|
-
file_count:
|
|
2715
|
+
file_count: z22.number(),
|
|
2653
2716
|
created_at: timestampSchema,
|
|
2654
2717
|
updated_at: timestampSchema
|
|
2655
2718
|
});
|
|
2656
|
-
var artifactVersionSchema =
|
|
2657
|
-
id:
|
|
2719
|
+
var artifactVersionSchema = z22.object({
|
|
2720
|
+
id: z22.string(),
|
|
2658
2721
|
// SHA-256 content hash
|
|
2659
|
-
artifact_id:
|
|
2660
|
-
size:
|
|
2722
|
+
artifact_id: z22.string(),
|
|
2723
|
+
size: z22.number(),
|
|
2661
2724
|
// Size in bytes
|
|
2662
|
-
file_count:
|
|
2663
|
-
message:
|
|
2725
|
+
file_count: z22.number(),
|
|
2726
|
+
message: z22.string().nullable(),
|
|
2664
2727
|
// Optional commit message
|
|
2665
|
-
created_by:
|
|
2728
|
+
created_by: z22.string(),
|
|
2666
2729
|
created_at: timestampSchema
|
|
2667
2730
|
});
|
|
2668
2731
|
var publicArtifactDetailSchema = publicArtifactSchema.extend({
|
|
@@ -2672,7 +2735,7 @@ var paginatedArtifactsSchema = createPaginatedResponseSchema(publicArtifactSchem
|
|
|
2672
2735
|
var paginatedArtifactVersionsSchema = createPaginatedResponseSchema(
|
|
2673
2736
|
artifactVersionSchema
|
|
2674
2737
|
);
|
|
2675
|
-
var publicArtifactsListContract =
|
|
2738
|
+
var publicArtifactsListContract = c18.router({
|
|
2676
2739
|
list: {
|
|
2677
2740
|
method: "GET",
|
|
2678
2741
|
path: "/v1/artifacts",
|
|
@@ -2687,13 +2750,13 @@ var publicArtifactsListContract = c17.router({
|
|
|
2687
2750
|
description: "List all artifacts in the current scope with pagination"
|
|
2688
2751
|
}
|
|
2689
2752
|
});
|
|
2690
|
-
var publicArtifactByIdContract =
|
|
2753
|
+
var publicArtifactByIdContract = c18.router({
|
|
2691
2754
|
get: {
|
|
2692
2755
|
method: "GET",
|
|
2693
2756
|
path: "/v1/artifacts/:id",
|
|
2694
2757
|
headers: authHeadersSchema,
|
|
2695
|
-
pathParams:
|
|
2696
|
-
id:
|
|
2758
|
+
pathParams: z22.object({
|
|
2759
|
+
id: z22.string().min(1, "Artifact ID is required")
|
|
2697
2760
|
}),
|
|
2698
2761
|
responses: {
|
|
2699
2762
|
200: publicArtifactDetailSchema,
|
|
@@ -2705,13 +2768,13 @@ var publicArtifactByIdContract = c17.router({
|
|
|
2705
2768
|
description: "Get artifact details by ID"
|
|
2706
2769
|
}
|
|
2707
2770
|
});
|
|
2708
|
-
var publicArtifactVersionsContract =
|
|
2771
|
+
var publicArtifactVersionsContract = c18.router({
|
|
2709
2772
|
list: {
|
|
2710
2773
|
method: "GET",
|
|
2711
2774
|
path: "/v1/artifacts/:id/versions",
|
|
2712
2775
|
headers: authHeadersSchema,
|
|
2713
|
-
pathParams:
|
|
2714
|
-
id:
|
|
2776
|
+
pathParams: z22.object({
|
|
2777
|
+
id: z22.string().min(1, "Artifact ID is required")
|
|
2715
2778
|
}),
|
|
2716
2779
|
query: listQuerySchema,
|
|
2717
2780
|
responses: {
|
|
@@ -2724,20 +2787,20 @@ var publicArtifactVersionsContract = c17.router({
|
|
|
2724
2787
|
description: "List all versions of an artifact with pagination"
|
|
2725
2788
|
}
|
|
2726
2789
|
});
|
|
2727
|
-
var publicArtifactDownloadContract =
|
|
2790
|
+
var publicArtifactDownloadContract = c18.router({
|
|
2728
2791
|
download: {
|
|
2729
2792
|
method: "GET",
|
|
2730
2793
|
path: "/v1/artifacts/:id/download",
|
|
2731
2794
|
headers: authHeadersSchema,
|
|
2732
|
-
pathParams:
|
|
2733
|
-
id:
|
|
2795
|
+
pathParams: z22.object({
|
|
2796
|
+
id: z22.string().min(1, "Artifact ID is required")
|
|
2734
2797
|
}),
|
|
2735
|
-
query:
|
|
2736
|
-
version_id:
|
|
2798
|
+
query: z22.object({
|
|
2799
|
+
version_id: z22.string().optional()
|
|
2737
2800
|
// Defaults to current version
|
|
2738
2801
|
}),
|
|
2739
2802
|
responses: {
|
|
2740
|
-
302:
|
|
2803
|
+
302: z22.undefined(),
|
|
2741
2804
|
// Redirect to presigned URL
|
|
2742
2805
|
401: publicApiErrorSchema,
|
|
2743
2806
|
404: publicApiErrorSchema,
|
|
@@ -2749,28 +2812,28 @@ var publicArtifactDownloadContract = c17.router({
|
|
|
2749
2812
|
});
|
|
2750
2813
|
|
|
2751
2814
|
// ../../packages/core/src/contracts/public/volumes.ts
|
|
2752
|
-
import { z as
|
|
2753
|
-
var
|
|
2754
|
-
var publicVolumeSchema =
|
|
2755
|
-
id:
|
|
2756
|
-
name:
|
|
2757
|
-
current_version_id:
|
|
2758
|
-
size:
|
|
2815
|
+
import { z as z23 } from "zod";
|
|
2816
|
+
var c19 = initContract();
|
|
2817
|
+
var publicVolumeSchema = z23.object({
|
|
2818
|
+
id: z23.string(),
|
|
2819
|
+
name: z23.string(),
|
|
2820
|
+
current_version_id: z23.string().nullable(),
|
|
2821
|
+
size: z23.number(),
|
|
2759
2822
|
// Total size in bytes
|
|
2760
|
-
file_count:
|
|
2823
|
+
file_count: z23.number(),
|
|
2761
2824
|
created_at: timestampSchema,
|
|
2762
2825
|
updated_at: timestampSchema
|
|
2763
2826
|
});
|
|
2764
|
-
var volumeVersionSchema =
|
|
2765
|
-
id:
|
|
2827
|
+
var volumeVersionSchema = z23.object({
|
|
2828
|
+
id: z23.string(),
|
|
2766
2829
|
// SHA-256 content hash
|
|
2767
|
-
volume_id:
|
|
2768
|
-
size:
|
|
2830
|
+
volume_id: z23.string(),
|
|
2831
|
+
size: z23.number(),
|
|
2769
2832
|
// Size in bytes
|
|
2770
|
-
file_count:
|
|
2771
|
-
message:
|
|
2833
|
+
file_count: z23.number(),
|
|
2834
|
+
message: z23.string().nullable(),
|
|
2772
2835
|
// Optional commit message
|
|
2773
|
-
created_by:
|
|
2836
|
+
created_by: z23.string(),
|
|
2774
2837
|
created_at: timestampSchema
|
|
2775
2838
|
});
|
|
2776
2839
|
var publicVolumeDetailSchema = publicVolumeSchema.extend({
|
|
@@ -2778,7 +2841,7 @@ var publicVolumeDetailSchema = publicVolumeSchema.extend({
|
|
|
2778
2841
|
});
|
|
2779
2842
|
var paginatedVolumesSchema = createPaginatedResponseSchema(publicVolumeSchema);
|
|
2780
2843
|
var paginatedVolumeVersionsSchema = createPaginatedResponseSchema(volumeVersionSchema);
|
|
2781
|
-
var publicVolumesListContract =
|
|
2844
|
+
var publicVolumesListContract = c19.router({
|
|
2782
2845
|
list: {
|
|
2783
2846
|
method: "GET",
|
|
2784
2847
|
path: "/v1/volumes",
|
|
@@ -2793,13 +2856,13 @@ var publicVolumesListContract = c18.router({
|
|
|
2793
2856
|
description: "List all volumes in the current scope with pagination"
|
|
2794
2857
|
}
|
|
2795
2858
|
});
|
|
2796
|
-
var publicVolumeByIdContract =
|
|
2859
|
+
var publicVolumeByIdContract = c19.router({
|
|
2797
2860
|
get: {
|
|
2798
2861
|
method: "GET",
|
|
2799
2862
|
path: "/v1/volumes/:id",
|
|
2800
2863
|
headers: authHeadersSchema,
|
|
2801
|
-
pathParams:
|
|
2802
|
-
id:
|
|
2864
|
+
pathParams: z23.object({
|
|
2865
|
+
id: z23.string().min(1, "Volume ID is required")
|
|
2803
2866
|
}),
|
|
2804
2867
|
responses: {
|
|
2805
2868
|
200: publicVolumeDetailSchema,
|
|
@@ -2811,13 +2874,13 @@ var publicVolumeByIdContract = c18.router({
|
|
|
2811
2874
|
description: "Get volume details by ID"
|
|
2812
2875
|
}
|
|
2813
2876
|
});
|
|
2814
|
-
var publicVolumeVersionsContract =
|
|
2877
|
+
var publicVolumeVersionsContract = c19.router({
|
|
2815
2878
|
list: {
|
|
2816
2879
|
method: "GET",
|
|
2817
2880
|
path: "/v1/volumes/:id/versions",
|
|
2818
2881
|
headers: authHeadersSchema,
|
|
2819
|
-
pathParams:
|
|
2820
|
-
id:
|
|
2882
|
+
pathParams: z23.object({
|
|
2883
|
+
id: z23.string().min(1, "Volume ID is required")
|
|
2821
2884
|
}),
|
|
2822
2885
|
query: listQuerySchema,
|
|
2823
2886
|
responses: {
|
|
@@ -2830,20 +2893,20 @@ var publicVolumeVersionsContract = c18.router({
|
|
|
2830
2893
|
description: "List all versions of a volume with pagination"
|
|
2831
2894
|
}
|
|
2832
2895
|
});
|
|
2833
|
-
var publicVolumeDownloadContract =
|
|
2896
|
+
var publicVolumeDownloadContract = c19.router({
|
|
2834
2897
|
download: {
|
|
2835
2898
|
method: "GET",
|
|
2836
2899
|
path: "/v1/volumes/:id/download",
|
|
2837
2900
|
headers: authHeadersSchema,
|
|
2838
|
-
pathParams:
|
|
2839
|
-
id:
|
|
2901
|
+
pathParams: z23.object({
|
|
2902
|
+
id: z23.string().min(1, "Volume ID is required")
|
|
2840
2903
|
}),
|
|
2841
|
-
query:
|
|
2842
|
-
version_id:
|
|
2904
|
+
query: z23.object({
|
|
2905
|
+
version_id: z23.string().optional()
|
|
2843
2906
|
// Defaults to current version
|
|
2844
2907
|
}),
|
|
2845
2908
|
responses: {
|
|
2846
|
-
302:
|
|
2909
|
+
302: z23.undefined(),
|
|
2847
2910
|
// Redirect to presigned URL
|
|
2848
2911
|
401: publicApiErrorSchema,
|
|
2849
2912
|
404: publicApiErrorSchema,
|
|
@@ -2976,6 +3039,13 @@ var FEATURE_SWITCHES = {
|
|
|
2976
3039
|
};
|
|
2977
3040
|
|
|
2978
3041
|
// src/lib/api/core/client-factory.ts
|
|
3042
|
+
var ApiRequestError = class extends Error {
|
|
3043
|
+
constructor(message, code) {
|
|
3044
|
+
super(message);
|
|
3045
|
+
this.code = code;
|
|
3046
|
+
this.name = "ApiRequestError";
|
|
3047
|
+
}
|
|
3048
|
+
};
|
|
2979
3049
|
async function getHeaders() {
|
|
2980
3050
|
const token = await getToken();
|
|
2981
3051
|
if (!token) {
|
|
@@ -3005,7 +3075,8 @@ async function getClientConfig() {
|
|
|
3005
3075
|
function handleError(result, defaultMessage) {
|
|
3006
3076
|
const errorBody = result.body;
|
|
3007
3077
|
const message = errorBody.error?.message || defaultMessage;
|
|
3008
|
-
|
|
3078
|
+
const code = errorBody.error?.code || "UNKNOWN";
|
|
3079
|
+
throw new ApiRequestError(message, code);
|
|
3009
3080
|
}
|
|
3010
3081
|
|
|
3011
3082
|
// src/lib/api/core/http.ts
|
|
@@ -3423,8 +3494,8 @@ async function getUsage(options) {
|
|
|
3423
3494
|
}
|
|
3424
3495
|
|
|
3425
3496
|
// src/lib/domain/yaml-validator.ts
|
|
3426
|
-
import { z as
|
|
3427
|
-
var cliAgentNameSchema =
|
|
3497
|
+
import { z as z24 } from "zod";
|
|
3498
|
+
var cliAgentNameSchema = z24.string().min(3, "Agent name must be at least 3 characters").max(64, "Agent name must be 64 characters or less").regex(
|
|
3428
3499
|
/^[a-zA-Z0-9]([a-zA-Z0-9-]{0,62}[a-zA-Z0-9])?$/,
|
|
3429
3500
|
"Agent name must start and end with letter or number, and contain only letters, numbers, and hyphens"
|
|
3430
3501
|
);
|
|
@@ -3439,7 +3510,7 @@ var cliAgentDefinitionSchema = agentDefinitionSchema.superRefine(
|
|
|
3439
3510
|
const skillUrl = agent.skills[i];
|
|
3440
3511
|
if (skillUrl && !validateGitHubTreeUrl(skillUrl)) {
|
|
3441
3512
|
ctx.addIssue({
|
|
3442
|
-
code:
|
|
3513
|
+
code: z24.ZodIssueCode.custom,
|
|
3443
3514
|
message: `Invalid skill URL: ${skillUrl}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`,
|
|
3444
3515
|
path: ["skills", i]
|
|
3445
3516
|
});
|
|
@@ -3448,15 +3519,15 @@ var cliAgentDefinitionSchema = agentDefinitionSchema.superRefine(
|
|
|
3448
3519
|
}
|
|
3449
3520
|
}
|
|
3450
3521
|
);
|
|
3451
|
-
var cliComposeSchema =
|
|
3452
|
-
version:
|
|
3453
|
-
agents:
|
|
3454
|
-
volumes:
|
|
3522
|
+
var cliComposeSchema = z24.object({
|
|
3523
|
+
version: z24.string().min(1, "Missing config.version"),
|
|
3524
|
+
agents: z24.record(cliAgentNameSchema, cliAgentDefinitionSchema),
|
|
3525
|
+
volumes: z24.record(z24.string(), volumeConfigSchema).optional()
|
|
3455
3526
|
}).superRefine((config, ctx) => {
|
|
3456
3527
|
const agentKeys = Object.keys(config.agents);
|
|
3457
3528
|
if (agentKeys.length === 0) {
|
|
3458
3529
|
ctx.addIssue({
|
|
3459
|
-
code:
|
|
3530
|
+
code: z24.ZodIssueCode.custom,
|
|
3460
3531
|
message: "agents must have at least one agent defined",
|
|
3461
3532
|
path: ["agents"]
|
|
3462
3533
|
});
|
|
@@ -3464,7 +3535,7 @@ var cliComposeSchema = z23.object({
|
|
|
3464
3535
|
}
|
|
3465
3536
|
if (agentKeys.length > 1) {
|
|
3466
3537
|
ctx.addIssue({
|
|
3467
|
-
code:
|
|
3538
|
+
code: z24.ZodIssueCode.custom,
|
|
3468
3539
|
message: "Multiple agents not supported yet. Only one agent allowed.",
|
|
3469
3540
|
path: ["agents"]
|
|
3470
3541
|
});
|
|
@@ -3476,7 +3547,7 @@ var cliComposeSchema = z23.object({
|
|
|
3476
3547
|
if (agentVolumes && agentVolumes.length > 0) {
|
|
3477
3548
|
if (!config.volumes) {
|
|
3478
3549
|
ctx.addIssue({
|
|
3479
|
-
code:
|
|
3550
|
+
code: z24.ZodIssueCode.custom,
|
|
3480
3551
|
message: "Agent references volumes but no volumes section defined. Each volume must have explicit name and version.",
|
|
3481
3552
|
path: ["volumes"]
|
|
3482
3553
|
});
|
|
@@ -3486,7 +3557,7 @@ var cliComposeSchema = z23.object({
|
|
|
3486
3557
|
const parts = volDeclaration.split(":");
|
|
3487
3558
|
if (parts.length !== 2) {
|
|
3488
3559
|
ctx.addIssue({
|
|
3489
|
-
code:
|
|
3560
|
+
code: z24.ZodIssueCode.custom,
|
|
3490
3561
|
message: `Invalid volume declaration: ${volDeclaration}. Expected format: volume-key:/mount/path`,
|
|
3491
3562
|
path: ["agents", agentName, "volumes"]
|
|
3492
3563
|
});
|
|
@@ -3495,7 +3566,7 @@ var cliComposeSchema = z23.object({
|
|
|
3495
3566
|
const volumeKey = parts[0].trim();
|
|
3496
3567
|
if (!config.volumes[volumeKey]) {
|
|
3497
3568
|
ctx.addIssue({
|
|
3498
|
-
code:
|
|
3569
|
+
code: z24.ZodIssueCode.custom,
|
|
3499
3570
|
message: `Volume "${volumeKey}" is not defined in volumes section. Each volume must have explicit name and version.`,
|
|
3500
3571
|
path: ["volumes", volumeKey]
|
|
3501
3572
|
});
|
|
@@ -4045,6 +4116,89 @@ async function uploadSkill(skillUrl) {
|
|
|
4045
4116
|
}
|
|
4046
4117
|
}
|
|
4047
4118
|
|
|
4119
|
+
// src/lib/utils/prompt-utils.ts
|
|
4120
|
+
import prompts from "prompts";
|
|
4121
|
+
function isInteractive() {
|
|
4122
|
+
return process.stdout.isTTY === true;
|
|
4123
|
+
}
|
|
4124
|
+
async function promptText(message, initial, validate) {
|
|
4125
|
+
if (!isInteractive()) {
|
|
4126
|
+
return void 0;
|
|
4127
|
+
}
|
|
4128
|
+
const response = await prompts(
|
|
4129
|
+
{
|
|
4130
|
+
type: "text",
|
|
4131
|
+
name: "value",
|
|
4132
|
+
message,
|
|
4133
|
+
initial,
|
|
4134
|
+
validate
|
|
4135
|
+
},
|
|
4136
|
+
{
|
|
4137
|
+
onCancel: () => {
|
|
4138
|
+
return false;
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
4141
|
+
);
|
|
4142
|
+
return response.value;
|
|
4143
|
+
}
|
|
4144
|
+
async function promptConfirm(message, initial = true) {
|
|
4145
|
+
if (!isInteractive()) {
|
|
4146
|
+
return void 0;
|
|
4147
|
+
}
|
|
4148
|
+
const response = await prompts(
|
|
4149
|
+
{
|
|
4150
|
+
type: "confirm",
|
|
4151
|
+
name: "value",
|
|
4152
|
+
message,
|
|
4153
|
+
initial
|
|
4154
|
+
},
|
|
4155
|
+
{
|
|
4156
|
+
onCancel: () => {
|
|
4157
|
+
return false;
|
|
4158
|
+
}
|
|
4159
|
+
}
|
|
4160
|
+
);
|
|
4161
|
+
return response.value;
|
|
4162
|
+
}
|
|
4163
|
+
async function promptSelect(message, choices, initial) {
|
|
4164
|
+
if (!isInteractive()) {
|
|
4165
|
+
return void 0;
|
|
4166
|
+
}
|
|
4167
|
+
const response = await prompts(
|
|
4168
|
+
{
|
|
4169
|
+
type: "select",
|
|
4170
|
+
name: "value",
|
|
4171
|
+
message,
|
|
4172
|
+
choices,
|
|
4173
|
+
initial
|
|
4174
|
+
},
|
|
4175
|
+
{
|
|
4176
|
+
onCancel: () => {
|
|
4177
|
+
return false;
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
);
|
|
4181
|
+
return response.value;
|
|
4182
|
+
}
|
|
4183
|
+
async function promptPassword(message) {
|
|
4184
|
+
if (!isInteractive()) {
|
|
4185
|
+
return void 0;
|
|
4186
|
+
}
|
|
4187
|
+
const response = await prompts(
|
|
4188
|
+
{
|
|
4189
|
+
type: "password",
|
|
4190
|
+
name: "value",
|
|
4191
|
+
message
|
|
4192
|
+
},
|
|
4193
|
+
{
|
|
4194
|
+
onCancel: () => {
|
|
4195
|
+
return false;
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
);
|
|
4199
|
+
return response.value;
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4048
4202
|
// src/commands/compose.ts
|
|
4049
4203
|
function getSecretsFromComposeContent(content) {
|
|
4050
4204
|
const refs = extractVariableReferences(content);
|
|
@@ -4183,7 +4337,7 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
4183
4337
|
console.log();
|
|
4184
4338
|
if (trulyNewSecrets.length > 0) {
|
|
4185
4339
|
if (!options.yes) {
|
|
4186
|
-
if (!
|
|
4340
|
+
if (!isInteractive()) {
|
|
4187
4341
|
console.error(
|
|
4188
4342
|
chalk2.red(
|
|
4189
4343
|
`\u2717 New secrets detected: ${trulyNewSecrets.join(", ")}`
|
|
@@ -4196,14 +4350,12 @@ var composeCommand = new Command().name("compose").description("Create or update
|
|
|
4196
4350
|
);
|
|
4197
4351
|
process.exit(1);
|
|
4198
4352
|
}
|
|
4199
|
-
const
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
if (!response2.value) {
|
|
4206
|
-
console.log(chalk2.yellow("Compose cancelled."));
|
|
4353
|
+
const confirmed = await promptConfirm(
|
|
4354
|
+
`Approve ${trulyNewSecrets.length} new secret(s)?`,
|
|
4355
|
+
true
|
|
4356
|
+
);
|
|
4357
|
+
if (!confirmed) {
|
|
4358
|
+
console.log(chalk2.yellow("Compose cancelled"));
|
|
4207
4359
|
process.exit(0);
|
|
4208
4360
|
}
|
|
4209
4361
|
}
|
|
@@ -4710,9 +4862,9 @@ var CodexEventParser = class {
|
|
|
4710
4862
|
}
|
|
4711
4863
|
}
|
|
4712
4864
|
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
4713
|
-
const changes = item.changes.map((
|
|
4714
|
-
const action =
|
|
4715
|
-
return `${action}: ${
|
|
4865
|
+
const changes = item.changes.map((c20) => {
|
|
4866
|
+
const action = c20.kind === "add" ? "Created" : c20.kind === "modify" ? "Modified" : "Deleted";
|
|
4867
|
+
return `${action}: ${c20.path}`;
|
|
4716
4868
|
}).join("\n");
|
|
4717
4869
|
return {
|
|
4718
4870
|
type: "text",
|
|
@@ -4866,9 +5018,9 @@ var CodexEventRenderer = class {
|
|
|
4866
5018
|
return;
|
|
4867
5019
|
}
|
|
4868
5020
|
if (itemType === "file_change" && item.changes && item.changes.length > 0) {
|
|
4869
|
-
const summary = item.changes.map((
|
|
4870
|
-
const icon =
|
|
4871
|
-
return `${icon}${
|
|
5021
|
+
const summary = item.changes.map((c20) => {
|
|
5022
|
+
const icon = c20.kind === "add" ? "+" : c20.kind === "delete" ? "-" : "~";
|
|
5023
|
+
return `${icon}${c20.path}`;
|
|
4872
5024
|
}).join(", ");
|
|
4873
5025
|
console.log(chalk4.green("[files]") + ` ${summary}`);
|
|
4874
5026
|
return;
|
|
@@ -6255,9 +6407,7 @@ var mainRunCommand = new Command2().name("run").description("Run an agent").argu
|
|
|
6255
6407
|
);
|
|
6256
6408
|
} else if (error.message.startsWith("Version not found:")) {
|
|
6257
6409
|
console.error(chalk6.red(`\u2717 ${error.message}`));
|
|
6258
|
-
console.error(
|
|
6259
|
-
chalk6.dim(" Make sure the version hash is correct.")
|
|
6260
|
-
);
|
|
6410
|
+
console.error(chalk6.dim(" Make sure the version hash is correct"));
|
|
6261
6411
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6262
6412
|
console.error(chalk6.red(`\u2717 ${error.message}`));
|
|
6263
6413
|
} else if (error.message.includes("not found")) {
|
|
@@ -6594,132 +6744,49 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type =
|
|
|
6594
6744
|
await writeFile4(configPath, yamlContent, "utf8");
|
|
6595
6745
|
}
|
|
6596
6746
|
|
|
6597
|
-
// src/
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6747
|
+
// src/commands/volume/init.ts
|
|
6748
|
+
var initCommand = new Command5().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
|
|
6749
|
+
try {
|
|
6750
|
+
const cwd = process.cwd();
|
|
6751
|
+
const dirName = path6.basename(cwd);
|
|
6752
|
+
const existingConfig = await readStorageConfig(cwd);
|
|
6753
|
+
if (existingConfig) {
|
|
6754
|
+
console.log(
|
|
6755
|
+
chalk9.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
6756
|
+
);
|
|
6757
|
+
console.log(
|
|
6758
|
+
chalk9.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
6759
|
+
);
|
|
6760
|
+
return;
|
|
6761
|
+
}
|
|
6762
|
+
let volumeName;
|
|
6763
|
+
if (options.name) {
|
|
6764
|
+
volumeName = options.name;
|
|
6765
|
+
} else if (!isInteractive()) {
|
|
6766
|
+
console.error(
|
|
6767
|
+
chalk9.red("\u2717 --name flag is required in non-interactive mode")
|
|
6768
|
+
);
|
|
6769
|
+
console.error(
|
|
6770
|
+
chalk9.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
6771
|
+
);
|
|
6772
|
+
process.exit(1);
|
|
6773
|
+
} else {
|
|
6774
|
+
const defaultName = isValidStorageName(dirName) ? dirName : void 0;
|
|
6775
|
+
const name = await promptText(
|
|
6776
|
+
"Enter volume name",
|
|
6777
|
+
defaultName,
|
|
6778
|
+
(value) => {
|
|
6779
|
+
if (!isValidStorageName(value)) {
|
|
6780
|
+
return "Must be 3-64 characters, lowercase alphanumeric with hyphens";
|
|
6781
|
+
}
|
|
6782
|
+
return true;
|
|
6783
|
+
}
|
|
6784
|
+
);
|
|
6785
|
+
if (name === void 0) {
|
|
6786
|
+
console.log(chalk9.dim("Cancelled"));
|
|
6787
|
+
return;
|
|
6617
6788
|
}
|
|
6618
|
-
|
|
6619
|
-
);
|
|
6620
|
-
return response.value;
|
|
6621
|
-
}
|
|
6622
|
-
async function promptConfirm(message, initial = true) {
|
|
6623
|
-
if (!isInteractive()) {
|
|
6624
|
-
return void 0;
|
|
6625
|
-
}
|
|
6626
|
-
const response = await prompts2(
|
|
6627
|
-
{
|
|
6628
|
-
type: "confirm",
|
|
6629
|
-
name: "value",
|
|
6630
|
-
message,
|
|
6631
|
-
initial
|
|
6632
|
-
},
|
|
6633
|
-
{
|
|
6634
|
-
onCancel: () => {
|
|
6635
|
-
return false;
|
|
6636
|
-
}
|
|
6637
|
-
}
|
|
6638
|
-
);
|
|
6639
|
-
return response.value;
|
|
6640
|
-
}
|
|
6641
|
-
async function promptSelect(message, choices, initial) {
|
|
6642
|
-
if (!isInteractive()) {
|
|
6643
|
-
return void 0;
|
|
6644
|
-
}
|
|
6645
|
-
const response = await prompts2(
|
|
6646
|
-
{
|
|
6647
|
-
type: "select",
|
|
6648
|
-
name: "value",
|
|
6649
|
-
message,
|
|
6650
|
-
choices,
|
|
6651
|
-
initial
|
|
6652
|
-
},
|
|
6653
|
-
{
|
|
6654
|
-
onCancel: () => {
|
|
6655
|
-
return false;
|
|
6656
|
-
}
|
|
6657
|
-
}
|
|
6658
|
-
);
|
|
6659
|
-
return response.value;
|
|
6660
|
-
}
|
|
6661
|
-
async function promptPassword(message) {
|
|
6662
|
-
if (!isInteractive()) {
|
|
6663
|
-
return void 0;
|
|
6664
|
-
}
|
|
6665
|
-
const response = await prompts2(
|
|
6666
|
-
{
|
|
6667
|
-
type: "password",
|
|
6668
|
-
name: "value",
|
|
6669
|
-
message
|
|
6670
|
-
},
|
|
6671
|
-
{
|
|
6672
|
-
onCancel: () => {
|
|
6673
|
-
return false;
|
|
6674
|
-
}
|
|
6675
|
-
}
|
|
6676
|
-
);
|
|
6677
|
-
return response.value;
|
|
6678
|
-
}
|
|
6679
|
-
|
|
6680
|
-
// src/commands/volume/init.ts
|
|
6681
|
-
var initCommand = new Command5().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
|
|
6682
|
-
try {
|
|
6683
|
-
const cwd = process.cwd();
|
|
6684
|
-
const dirName = path6.basename(cwd);
|
|
6685
|
-
const existingConfig = await readStorageConfig(cwd);
|
|
6686
|
-
if (existingConfig) {
|
|
6687
|
-
console.log(
|
|
6688
|
-
chalk9.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
6689
|
-
);
|
|
6690
|
-
console.log(
|
|
6691
|
-
chalk9.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
6692
|
-
);
|
|
6693
|
-
return;
|
|
6694
|
-
}
|
|
6695
|
-
let volumeName;
|
|
6696
|
-
if (options.name) {
|
|
6697
|
-
volumeName = options.name;
|
|
6698
|
-
} else if (!isInteractive()) {
|
|
6699
|
-
console.error(
|
|
6700
|
-
chalk9.red("\u2717 --name flag is required in non-interactive mode")
|
|
6701
|
-
);
|
|
6702
|
-
console.error(
|
|
6703
|
-
chalk9.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
6704
|
-
);
|
|
6705
|
-
process.exit(1);
|
|
6706
|
-
} else {
|
|
6707
|
-
const defaultName = isValidStorageName(dirName) ? dirName : void 0;
|
|
6708
|
-
const name = await promptText(
|
|
6709
|
-
"Enter volume name",
|
|
6710
|
-
defaultName,
|
|
6711
|
-
(value) => {
|
|
6712
|
-
if (!isValidStorageName(value)) {
|
|
6713
|
-
return "Must be 3-64 characters, lowercase alphanumeric with hyphens";
|
|
6714
|
-
}
|
|
6715
|
-
return true;
|
|
6716
|
-
}
|
|
6717
|
-
);
|
|
6718
|
-
if (name === void 0) {
|
|
6719
|
-
console.log(chalk9.dim("Cancelled"));
|
|
6720
|
-
return;
|
|
6721
|
-
}
|
|
6722
|
-
volumeName = name;
|
|
6789
|
+
volumeName = name;
|
|
6723
6790
|
}
|
|
6724
6791
|
if (!isValidStorageName(volumeName)) {
|
|
6725
6792
|
console.error(chalk9.red(`\u2717 Invalid volume name: "${volumeName}"`));
|
|
@@ -6737,7 +6804,7 @@ var initCommand = new Command5().name("init").description("Initialize a volume i
|
|
|
6737
6804
|
console.log(chalk9.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
6738
6805
|
console.log(
|
|
6739
6806
|
chalk9.dim(
|
|
6740
|
-
|
|
6807
|
+
` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
|
|
6741
6808
|
)
|
|
6742
6809
|
);
|
|
6743
6810
|
} catch (error) {
|
|
@@ -6752,13 +6819,6 @@ var initCommand = new Command5().name("init").description("Initialize a volume i
|
|
|
6752
6819
|
// src/commands/volume/push.ts
|
|
6753
6820
|
import { Command as Command6 } from "commander";
|
|
6754
6821
|
import chalk10 from "chalk";
|
|
6755
|
-
function formatBytes2(bytes) {
|
|
6756
|
-
if (bytes === 0) return "0 B";
|
|
6757
|
-
const k = 1024;
|
|
6758
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
6759
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
6760
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
6761
|
-
}
|
|
6762
6822
|
var pushCommand = new Command6().name("push").description("Push local files to cloud volume").option(
|
|
6763
6823
|
"-f, --force",
|
|
6764
6824
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -6780,7 +6840,7 @@ var pushCommand = new Command6().name("push").description("Push local files to c
|
|
|
6780
6840
|
});
|
|
6781
6841
|
const shortVersion = result.versionId.slice(0, 8);
|
|
6782
6842
|
if (result.empty) {
|
|
6783
|
-
console.log(chalk10.
|
|
6843
|
+
console.log(chalk10.dim("No files found (empty volume)"));
|
|
6784
6844
|
} else if (result.deduplicated) {
|
|
6785
6845
|
console.log(chalk10.green("\u2713 Content unchanged (deduplicated)"));
|
|
6786
6846
|
} else {
|
|
@@ -6788,7 +6848,7 @@ var pushCommand = new Command6().name("push").description("Push local files to c
|
|
|
6788
6848
|
}
|
|
6789
6849
|
console.log(chalk10.dim(` Version: ${shortVersion}`));
|
|
6790
6850
|
console.log(chalk10.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
6791
|
-
console.log(chalk10.dim(` Size: ${
|
|
6851
|
+
console.log(chalk10.dim(` Size: ${formatBytes(result.size)}`));
|
|
6792
6852
|
} catch (error) {
|
|
6793
6853
|
console.error(chalk10.red("\u2717 Push failed"));
|
|
6794
6854
|
if (error instanceof Error) {
|
|
@@ -6823,13 +6883,6 @@ async function handleEmptyStorageResponse(cwd) {
|
|
|
6823
6883
|
}
|
|
6824
6884
|
|
|
6825
6885
|
// src/commands/volume/pull.ts
|
|
6826
|
-
function formatBytes3(bytes) {
|
|
6827
|
-
if (bytes === 0) return "0 B";
|
|
6828
|
-
const k = 1024;
|
|
6829
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
6830
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
6831
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
6832
|
-
}
|
|
6833
6886
|
var pullCommand = new Command7().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
|
|
6834
6887
|
try {
|
|
6835
6888
|
const cwd = process.cwd();
|
|
@@ -6865,7 +6918,7 @@ var pullCommand = new Command7().name("pull").description("Pull cloud files to l
|
|
|
6865
6918
|
}
|
|
6866
6919
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
6867
6920
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
6868
|
-
console.log(chalk12.green(`\u2713 Downloaded ${
|
|
6921
|
+
console.log(chalk12.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
6869
6922
|
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
|
|
6870
6923
|
const tarPath = path7.join(tmpDir, "volume.tar.gz");
|
|
6871
6924
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
@@ -6905,13 +6958,6 @@ var pullCommand = new Command7().name("pull").description("Pull cloud files to l
|
|
|
6905
6958
|
// src/commands/volume/status.ts
|
|
6906
6959
|
import { Command as Command8 } from "commander";
|
|
6907
6960
|
import chalk13 from "chalk";
|
|
6908
|
-
function formatBytes4(bytes) {
|
|
6909
|
-
if (bytes === 0) return "0 B";
|
|
6910
|
-
const k = 1024;
|
|
6911
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
6912
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
6913
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
6914
|
-
}
|
|
6915
6961
|
var statusCommand = new Command8().name("status").description("Show status of cloud volume").action(async () => {
|
|
6916
6962
|
try {
|
|
6917
6963
|
const cwd = process.cwd();
|
|
@@ -6943,7 +6989,7 @@ var statusCommand = new Command8().name("status").description("Show status of cl
|
|
|
6943
6989
|
console.log(chalk13.green("\u2713 Found"));
|
|
6944
6990
|
console.log(chalk13.dim(` Version: ${shortVersion}`));
|
|
6945
6991
|
console.log(chalk13.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
6946
|
-
console.log(chalk13.dim(` Size: ${
|
|
6992
|
+
console.log(chalk13.dim(` Size: ${formatBytes(info.size)}`));
|
|
6947
6993
|
}
|
|
6948
6994
|
} catch (error) {
|
|
6949
6995
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
@@ -7194,7 +7240,7 @@ var initCommand2 = new Command12().name("init").description("Initialize an artif
|
|
|
7194
7240
|
console.log(chalk17.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
7195
7241
|
console.log(
|
|
7196
7242
|
chalk17.dim(
|
|
7197
|
-
|
|
7243
|
+
` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
7198
7244
|
)
|
|
7199
7245
|
);
|
|
7200
7246
|
} catch (error) {
|
|
@@ -7209,13 +7255,6 @@ var initCommand2 = new Command12().name("init").description("Initialize an artif
|
|
|
7209
7255
|
// src/commands/artifact/push.ts
|
|
7210
7256
|
import { Command as Command13 } from "commander";
|
|
7211
7257
|
import chalk18 from "chalk";
|
|
7212
|
-
function formatBytes5(bytes) {
|
|
7213
|
-
if (bytes === 0) return "0 B";
|
|
7214
|
-
const k = 1024;
|
|
7215
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
7216
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7217
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
7218
|
-
}
|
|
7219
7258
|
var pushCommand2 = new Command13().name("push").description("Push local files to cloud artifact").option(
|
|
7220
7259
|
"-f, --force",
|
|
7221
7260
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7246,7 +7285,7 @@ var pushCommand2 = new Command13().name("push").description("Push local files to
|
|
|
7246
7285
|
});
|
|
7247
7286
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7248
7287
|
if (result.empty) {
|
|
7249
|
-
console.log(chalk18.
|
|
7288
|
+
console.log(chalk18.dim("No files found (empty artifact)"));
|
|
7250
7289
|
} else if (result.deduplicated) {
|
|
7251
7290
|
console.log(chalk18.green("\u2713 Content unchanged (deduplicated)"));
|
|
7252
7291
|
} else {
|
|
@@ -7254,7 +7293,7 @@ var pushCommand2 = new Command13().name("push").description("Push local files to
|
|
|
7254
7293
|
}
|
|
7255
7294
|
console.log(chalk18.dim(` Version: ${shortVersion}`));
|
|
7256
7295
|
console.log(chalk18.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7257
|
-
console.log(chalk18.dim(` Size: ${
|
|
7296
|
+
console.log(chalk18.dim(` Size: ${formatBytes(result.size)}`));
|
|
7258
7297
|
} catch (error) {
|
|
7259
7298
|
console.error(chalk18.red("\u2717 Push failed"));
|
|
7260
7299
|
if (error instanceof Error) {
|
|
@@ -7271,13 +7310,6 @@ import path10 from "path";
|
|
|
7271
7310
|
import * as fs8 from "fs";
|
|
7272
7311
|
import * as os6 from "os";
|
|
7273
7312
|
import * as tar5 from "tar";
|
|
7274
|
-
function formatBytes6(bytes) {
|
|
7275
|
-
if (bytes === 0) return "0 B";
|
|
7276
|
-
const k = 1024;
|
|
7277
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
7278
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7279
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
7280
|
-
}
|
|
7281
7313
|
var pullCommand2 = new Command14().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
|
|
7282
7314
|
try {
|
|
7283
7315
|
const cwd = process.cwd();
|
|
@@ -7322,7 +7354,7 @@ var pullCommand2 = new Command14().name("pull").description("Pull cloud artifact
|
|
|
7322
7354
|
}
|
|
7323
7355
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7324
7356
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7325
|
-
console.log(chalk19.green(`\u2713 Downloaded ${
|
|
7357
|
+
console.log(chalk19.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7326
7358
|
const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
|
|
7327
7359
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
7328
7360
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
@@ -7358,13 +7390,6 @@ var pullCommand2 = new Command14().name("pull").description("Pull cloud artifact
|
|
|
7358
7390
|
// src/commands/artifact/status.ts
|
|
7359
7391
|
import { Command as Command15 } from "commander";
|
|
7360
7392
|
import chalk20 from "chalk";
|
|
7361
|
-
function formatBytes7(bytes) {
|
|
7362
|
-
if (bytes === 0) return "0 B";
|
|
7363
|
-
const k = 1024;
|
|
7364
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
7365
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
7366
|
-
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
7367
|
-
}
|
|
7368
7393
|
var statusCommand2 = new Command15().name("status").description("Show status of cloud artifact").action(async () => {
|
|
7369
7394
|
try {
|
|
7370
7395
|
const cwd = process.cwd();
|
|
@@ -7396,7 +7421,7 @@ var statusCommand2 = new Command15().name("status").description("Show status of
|
|
|
7396
7421
|
console.log(chalk20.green("\u2713 Found"));
|
|
7397
7422
|
console.log(chalk20.dim(` Version: ${shortVersion}`));
|
|
7398
7423
|
console.log(chalk20.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7399
|
-
console.log(chalk20.dim(` Size: ${
|
|
7424
|
+
console.log(chalk20.dim(` Size: ${formatBytes(info.size)}`));
|
|
7400
7425
|
}
|
|
7401
7426
|
} catch (error) {
|
|
7402
7427
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
@@ -7863,7 +7888,7 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7863
7888
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
7864
7889
|
async (prompt, options) => {
|
|
7865
7890
|
if (!options.noAutoUpdate) {
|
|
7866
|
-
const shouldExit = await checkAndUpgrade("8.
|
|
7891
|
+
const shouldExit = await checkAndUpgrade("8.1.1", prompt);
|
|
7867
7892
|
if (shouldExit) {
|
|
7868
7893
|
process.exit(0);
|
|
7869
7894
|
}
|
|
@@ -7907,7 +7932,7 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7907
7932
|
console.log();
|
|
7908
7933
|
console.error(chalk24.red("\u2717 Missing required variables:"));
|
|
7909
7934
|
for (const varName of missingVars) {
|
|
7910
|
-
console.error(chalk24.red(`
|
|
7935
|
+
console.error(chalk24.red(` ${varName}`));
|
|
7911
7936
|
}
|
|
7912
7937
|
console.error(
|
|
7913
7938
|
chalk24.dim(
|
|
@@ -7930,9 +7955,10 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7930
7955
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
7931
7956
|
if (!existsSync8(volumeDir)) {
|
|
7932
7957
|
console.error(
|
|
7933
|
-
chalk24.red(
|
|
7934
|
-
|
|
7935
|
-
|
|
7958
|
+
chalk24.red(`\u2717 Directory not found: ${volumeConfig.name}`)
|
|
7959
|
+
);
|
|
7960
|
+
console.error(
|
|
7961
|
+
chalk24.dim(" Create the directory and add files first")
|
|
7936
7962
|
);
|
|
7937
7963
|
process.exit(1);
|
|
7938
7964
|
}
|
|
@@ -8238,17 +8264,10 @@ function parseRelativeTime(value, unit) {
|
|
|
8238
8264
|
}
|
|
8239
8265
|
|
|
8240
8266
|
// src/commands/logs/index.ts
|
|
8241
|
-
function formatBytes8(bytes) {
|
|
8242
|
-
if (bytes === 0) return "0 B";
|
|
8243
|
-
const k = 1024;
|
|
8244
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
8245
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
8246
|
-
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
|
|
8247
|
-
}
|
|
8248
8267
|
function formatMetric(metric) {
|
|
8249
8268
|
const memPercent = (metric.mem_used / metric.mem_total * 100).toFixed(1);
|
|
8250
8269
|
const diskPercent = (metric.disk_used / metric.disk_total * 100).toFixed(1);
|
|
8251
|
-
return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${
|
|
8270
|
+
return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${formatBytes(metric.mem_used)}/${formatBytes(metric.mem_total)} (${memPercent}%) | Disk: ${formatBytes(metric.disk_used)}/${formatBytes(metric.disk_total)} (${diskPercent}%)`;
|
|
8252
8271
|
}
|
|
8253
8272
|
function formatNetworkLog(entry) {
|
|
8254
8273
|
if (entry.mode === "sni" || !entry.method) {
|
|
@@ -8281,7 +8300,7 @@ function formatNetworkLog(entry) {
|
|
|
8281
8300
|
const requestSize = entry.request_size || 0;
|
|
8282
8301
|
const responseSize = entry.response_size || 0;
|
|
8283
8302
|
const url = entry.url || entry.host || "unknown";
|
|
8284
|
-
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${
|
|
8303
|
+
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk25.dim(url)}`;
|
|
8285
8304
|
}
|
|
8286
8305
|
function renderAgentEvent(event, provider) {
|
|
8287
8306
|
const eventData = event.eventData;
|
|
@@ -8361,7 +8380,7 @@ var logsCommand = new Command20().name("logs").description("View logs for an age
|
|
|
8361
8380
|
async function showAgentEvents(runId, options) {
|
|
8362
8381
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
8363
8382
|
if (response.events.length === 0) {
|
|
8364
|
-
console.log(chalk25.yellow("No agent events found for this run
|
|
8383
|
+
console.log(chalk25.yellow("No agent events found for this run"));
|
|
8365
8384
|
return;
|
|
8366
8385
|
}
|
|
8367
8386
|
const events = options.order === "desc" ? [...response.events].reverse() : response.events;
|
|
@@ -8380,7 +8399,7 @@ async function showAgentEvents(runId, options) {
|
|
|
8380
8399
|
async function showSystemLog(runId, options) {
|
|
8381
8400
|
const response = await apiClient.getSystemLog(runId, options);
|
|
8382
8401
|
if (!response.systemLog) {
|
|
8383
|
-
console.log(chalk25.yellow("No system log found for this run
|
|
8402
|
+
console.log(chalk25.yellow("No system log found for this run"));
|
|
8384
8403
|
return;
|
|
8385
8404
|
}
|
|
8386
8405
|
console.log(response.systemLog);
|
|
@@ -8394,7 +8413,7 @@ async function showSystemLog(runId, options) {
|
|
|
8394
8413
|
async function showMetrics(runId, options) {
|
|
8395
8414
|
const response = await apiClient.getMetrics(runId, options);
|
|
8396
8415
|
if (response.metrics.length === 0) {
|
|
8397
|
-
console.log(chalk25.yellow("No metrics found for this run
|
|
8416
|
+
console.log(chalk25.yellow("No metrics found for this run"));
|
|
8398
8417
|
return;
|
|
8399
8418
|
}
|
|
8400
8419
|
const metrics = options.order === "desc" ? [...response.metrics].reverse() : response.metrics;
|
|
@@ -8415,7 +8434,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
8415
8434
|
if (response.networkLogs.length === 0) {
|
|
8416
8435
|
console.log(
|
|
8417
8436
|
chalk25.yellow(
|
|
8418
|
-
"No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner
|
|
8437
|
+
"No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner"
|
|
8419
8438
|
)
|
|
8420
8439
|
);
|
|
8421
8440
|
return;
|
|
@@ -8462,9 +8481,6 @@ var statusCommand3 = new Command21().name("status").description("View current sc
|
|
|
8462
8481
|
console.log(chalk26.bold("Scope Information:"));
|
|
8463
8482
|
console.log(` Slug: ${chalk26.green(scope.slug)}`);
|
|
8464
8483
|
console.log(` Type: ${scope.type}`);
|
|
8465
|
-
if (scope.displayName) {
|
|
8466
|
-
console.log(` Display Name: ${scope.displayName}`);
|
|
8467
|
-
}
|
|
8468
8484
|
console.log(
|
|
8469
8485
|
` Created: ${new Date(scope.createdAt).toLocaleDateString()}`
|
|
8470
8486
|
);
|
|
@@ -8473,7 +8489,7 @@ var statusCommand3 = new Command21().name("status").description("View current sc
|
|
|
8473
8489
|
if (error.message.includes("Not authenticated")) {
|
|
8474
8490
|
console.error(chalk26.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8475
8491
|
} else if (error.message.includes("No scope configured")) {
|
|
8476
|
-
console.log(chalk26.yellow("No scope configured
|
|
8492
|
+
console.log(chalk26.yellow("No scope configured"));
|
|
8477
8493
|
console.log();
|
|
8478
8494
|
console.log("Set your scope with:");
|
|
8479
8495
|
console.log(chalk26.cyan(" vm0 scope set <slug>"));
|
|
@@ -8493,76 +8509,69 @@ var statusCommand3 = new Command21().name("status").description("View current sc
|
|
|
8493
8509
|
// src/commands/scope/set.ts
|
|
8494
8510
|
import { Command as Command22 } from "commander";
|
|
8495
8511
|
import chalk27 from "chalk";
|
|
8496
|
-
var setCommand = new Command22().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").
|
|
8497
|
-
|
|
8512
|
+
var setCommand = new Command22().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").action(async (slug, options) => {
|
|
8513
|
+
try {
|
|
8514
|
+
let existingScope;
|
|
8498
8515
|
try {
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
if (!(error instanceof Error) || !error.message.includes("No scope configured")) {
|
|
8504
|
-
throw error;
|
|
8505
|
-
}
|
|
8516
|
+
existingScope = await getScope();
|
|
8517
|
+
} catch (error) {
|
|
8518
|
+
if (!(error instanceof Error) || !error.message.includes("No scope configured")) {
|
|
8519
|
+
throw error;
|
|
8506
8520
|
}
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
)
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
)
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
scope = await updateScope({ slug, force: true });
|
|
8525
|
-
console.log(chalk27.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
8526
|
-
} else {
|
|
8527
|
-
scope = await createScope({
|
|
8528
|
-
slug,
|
|
8529
|
-
displayName: options.displayName
|
|
8530
|
-
});
|
|
8531
|
-
console.log(chalk27.green(`\u2713 Scope created: ${scope.slug}`));
|
|
8521
|
+
}
|
|
8522
|
+
let scope;
|
|
8523
|
+
if (existingScope) {
|
|
8524
|
+
if (!options.force) {
|
|
8525
|
+
console.error(
|
|
8526
|
+
chalk27.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
8527
|
+
);
|
|
8528
|
+
console.error();
|
|
8529
|
+
console.error("To change your scope, use --force:");
|
|
8530
|
+
console.error(chalk27.cyan(` vm0 scope set ${slug} --force`));
|
|
8531
|
+
console.error();
|
|
8532
|
+
console.error(
|
|
8533
|
+
chalk27.yellow(
|
|
8534
|
+
"Warning: Changing your scope may break existing agent references."
|
|
8535
|
+
)
|
|
8536
|
+
);
|
|
8537
|
+
process.exit(1);
|
|
8532
8538
|
}
|
|
8533
|
-
|
|
8534
|
-
console.log(
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8539
|
+
scope = await updateScope({ slug, force: true });
|
|
8540
|
+
console.log(chalk27.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
8541
|
+
} else {
|
|
8542
|
+
scope = await createScope({ slug });
|
|
8543
|
+
console.log(chalk27.green(`\u2713 Scope created: ${scope.slug}`));
|
|
8544
|
+
}
|
|
8545
|
+
console.log();
|
|
8546
|
+
console.log("Your agents will now be namespaced as:");
|
|
8547
|
+
console.log(chalk27.cyan(` ${scope.slug}/<agent-name>`));
|
|
8548
|
+
} catch (error) {
|
|
8549
|
+
if (error instanceof Error) {
|
|
8550
|
+
if (error.message.includes("Not authenticated")) {
|
|
8551
|
+
console.error(chalk27.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8552
|
+
} else if (error.message.includes("already exists")) {
|
|
8553
|
+
console.error(
|
|
8554
|
+
chalk27.red(
|
|
8555
|
+
`\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
|
|
8556
|
+
)
|
|
8557
|
+
);
|
|
8558
|
+
} else if (error.message.includes("reserved")) {
|
|
8559
|
+
console.error(chalk27.red(`\u2717 ${error.message}`));
|
|
8560
|
+
} else if (error.message.includes("vm0")) {
|
|
8561
|
+
console.error(
|
|
8562
|
+
chalk27.red(
|
|
8563
|
+
"\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
|
|
8564
|
+
)
|
|
8565
|
+
);
|
|
8559
8566
|
} else {
|
|
8560
|
-
console.error(chalk27.red(
|
|
8567
|
+
console.error(chalk27.red(`\u2717 ${error.message}`));
|
|
8561
8568
|
}
|
|
8562
|
-
|
|
8569
|
+
} else {
|
|
8570
|
+
console.error(chalk27.red("\u2717 An unexpected error occurred"));
|
|
8563
8571
|
}
|
|
8572
|
+
process.exit(1);
|
|
8564
8573
|
}
|
|
8565
|
-
);
|
|
8574
|
+
});
|
|
8566
8575
|
|
|
8567
8576
|
// src/commands/scope/index.ts
|
|
8568
8577
|
var scopeCommand = new Command23().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand3).addCommand(setCommand);
|
|
@@ -8588,7 +8597,7 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
8588
8597
|
);
|
|
8589
8598
|
return;
|
|
8590
8599
|
}
|
|
8591
|
-
const nameWidth = Math.max(4, ...data.composes.map((
|
|
8600
|
+
const nameWidth = Math.max(4, ...data.composes.map((c20) => c20.name.length));
|
|
8592
8601
|
const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
|
|
8593
8602
|
" "
|
|
8594
8603
|
);
|
|
@@ -8981,7 +8990,7 @@ import { Command as Command34 } from "commander";
|
|
|
8981
8990
|
|
|
8982
8991
|
// src/commands/schedule/setup.ts
|
|
8983
8992
|
import { Command as Command28 } from "commander";
|
|
8984
|
-
import
|
|
8993
|
+
import chalk32 from "chalk";
|
|
8985
8994
|
|
|
8986
8995
|
// src/lib/domain/schedule-utils.ts
|
|
8987
8996
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -9122,6 +9131,127 @@ async function resolveScheduleByAgent(agentName) {
|
|
|
9122
9131
|
};
|
|
9123
9132
|
}
|
|
9124
9133
|
|
|
9134
|
+
// src/commands/schedule/gather-configuration.ts
|
|
9135
|
+
import chalk31 from "chalk";
|
|
9136
|
+
var defaultPromptDeps = {
|
|
9137
|
+
isInteractive,
|
|
9138
|
+
promptConfirm,
|
|
9139
|
+
promptPassword,
|
|
9140
|
+
promptText
|
|
9141
|
+
};
|
|
9142
|
+
function parseKeyValuePairs(pairs) {
|
|
9143
|
+
const result = {};
|
|
9144
|
+
for (const pair of pairs) {
|
|
9145
|
+
const eqIndex = pair.indexOf("=");
|
|
9146
|
+
if (eqIndex > 0) {
|
|
9147
|
+
const key = pair.slice(0, eqIndex);
|
|
9148
|
+
const value = pair.slice(eqIndex + 1);
|
|
9149
|
+
result[key] = value;
|
|
9150
|
+
}
|
|
9151
|
+
}
|
|
9152
|
+
return result;
|
|
9153
|
+
}
|
|
9154
|
+
async function handleSecrets(optionSecrets, existingSecretNames, deps) {
|
|
9155
|
+
if (optionSecrets.length > 0) {
|
|
9156
|
+
return {
|
|
9157
|
+
secrets: parseKeyValuePairs(optionSecrets),
|
|
9158
|
+
preserveExistingSecrets: false
|
|
9159
|
+
};
|
|
9160
|
+
}
|
|
9161
|
+
if (existingSecretNames.length > 0 && deps.isInteractive()) {
|
|
9162
|
+
const keepSecrets = await deps.promptConfirm(
|
|
9163
|
+
`Keep existing secrets? (${existingSecretNames.join(", ")})`,
|
|
9164
|
+
true
|
|
9165
|
+
);
|
|
9166
|
+
if (keepSecrets) {
|
|
9167
|
+
return { secrets: {}, preserveExistingSecrets: true };
|
|
9168
|
+
}
|
|
9169
|
+
console.log(chalk31.dim(" Note: You'll need to provide new secret values"));
|
|
9170
|
+
return { secrets: {}, preserveExistingSecrets: false };
|
|
9171
|
+
}
|
|
9172
|
+
return { secrets: {}, preserveExistingSecrets: false };
|
|
9173
|
+
}
|
|
9174
|
+
async function handleVars(optionVars, existingVars, deps) {
|
|
9175
|
+
if (optionVars.length > 0) {
|
|
9176
|
+
return parseKeyValuePairs(optionVars);
|
|
9177
|
+
}
|
|
9178
|
+
if (existingVars && deps.isInteractive()) {
|
|
9179
|
+
const keepVars = await deps.promptConfirm(
|
|
9180
|
+
`Keep existing variables? (${Object.keys(existingVars).join(", ")})`,
|
|
9181
|
+
true
|
|
9182
|
+
);
|
|
9183
|
+
if (keepVars) {
|
|
9184
|
+
return { ...existingVars };
|
|
9185
|
+
}
|
|
9186
|
+
}
|
|
9187
|
+
return {};
|
|
9188
|
+
}
|
|
9189
|
+
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
9190
|
+
console.log(chalk31.yellow("\nAgent requires the following configuration:"));
|
|
9191
|
+
if (missingSecrets.length > 0) {
|
|
9192
|
+
console.log(chalk31.dim(" Secrets:"));
|
|
9193
|
+
for (const name of missingSecrets) {
|
|
9194
|
+
console.log(chalk31.dim(` ${name}`));
|
|
9195
|
+
}
|
|
9196
|
+
}
|
|
9197
|
+
if (missingVars.length > 0) {
|
|
9198
|
+
console.log(chalk31.dim(" Vars:"));
|
|
9199
|
+
for (const name of missingVars) {
|
|
9200
|
+
console.log(chalk31.dim(` ${name}`));
|
|
9201
|
+
}
|
|
9202
|
+
}
|
|
9203
|
+
console.log("");
|
|
9204
|
+
}
|
|
9205
|
+
async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
9206
|
+
for (const name of missingSecrets) {
|
|
9207
|
+
const value = await deps.promptPassword(
|
|
9208
|
+
`Enter value for secret ${chalk31.cyan(name)}`
|
|
9209
|
+
);
|
|
9210
|
+
if (value) {
|
|
9211
|
+
secrets[name] = value;
|
|
9212
|
+
}
|
|
9213
|
+
}
|
|
9214
|
+
}
|
|
9215
|
+
async function promptForMissingVars(missingVars, vars, deps) {
|
|
9216
|
+
for (const name of missingVars) {
|
|
9217
|
+
const value = await deps.promptText(
|
|
9218
|
+
`Enter value for var ${chalk31.cyan(name)}`,
|
|
9219
|
+
""
|
|
9220
|
+
);
|
|
9221
|
+
if (value) {
|
|
9222
|
+
vars[name] = value;
|
|
9223
|
+
}
|
|
9224
|
+
}
|
|
9225
|
+
}
|
|
9226
|
+
async function gatherConfiguration(params, deps = defaultPromptDeps) {
|
|
9227
|
+
const { required, optionSecrets, optionVars, existingSchedule } = params;
|
|
9228
|
+
const existingSecretNames = existingSchedule?.secretNames ?? [];
|
|
9229
|
+
const existingVars = existingSchedule?.vars ?? null;
|
|
9230
|
+
const { secrets, preserveExistingSecrets } = await handleSecrets(
|
|
9231
|
+
optionSecrets,
|
|
9232
|
+
existingSecretNames,
|
|
9233
|
+
deps
|
|
9234
|
+
);
|
|
9235
|
+
const vars = await handleVars(optionVars, existingVars, deps);
|
|
9236
|
+
const effectiveExistingSecrets = preserveExistingSecrets ? existingSecretNames : [];
|
|
9237
|
+
const missingSecrets = required.secrets.filter(
|
|
9238
|
+
(name) => !Object.keys(secrets).includes(name) && !effectiveExistingSecrets.includes(name)
|
|
9239
|
+
);
|
|
9240
|
+
const missingVars = required.vars.filter(
|
|
9241
|
+
(name) => !Object.keys(vars).includes(name)
|
|
9242
|
+
);
|
|
9243
|
+
if (missingSecrets.length === 0 && missingVars.length === 0) {
|
|
9244
|
+
return { secrets, vars, preserveExistingSecrets };
|
|
9245
|
+
}
|
|
9246
|
+
if (!deps.isInteractive()) {
|
|
9247
|
+
return { secrets, vars, preserveExistingSecrets };
|
|
9248
|
+
}
|
|
9249
|
+
displayMissingRequirements(missingSecrets, missingVars);
|
|
9250
|
+
await promptForMissingSecrets(missingSecrets, secrets, deps);
|
|
9251
|
+
await promptForMissingVars(missingVars, vars, deps);
|
|
9252
|
+
return { secrets, vars, preserveExistingSecrets };
|
|
9253
|
+
}
|
|
9254
|
+
|
|
9125
9255
|
// src/commands/schedule/setup.ts
|
|
9126
9256
|
var FREQUENCY_CHOICES = [
|
|
9127
9257
|
{ title: "Daily", value: "daily", description: "Run every day" },
|
|
@@ -9175,7 +9305,7 @@ function expandEnvVars(value) {
|
|
|
9175
9305
|
const envValue = process.env[varName];
|
|
9176
9306
|
if (envValue === void 0) {
|
|
9177
9307
|
console.warn(
|
|
9178
|
-
|
|
9308
|
+
chalk32.yellow(` Warning: Environment variable ${varName} not set`)
|
|
9179
9309
|
);
|
|
9180
9310
|
return match;
|
|
9181
9311
|
}
|
|
@@ -9221,18 +9351,6 @@ function parseFrequencyFromCron(cron) {
|
|
|
9221
9351
|
function collect(value, previous) {
|
|
9222
9352
|
return previous.concat([value]);
|
|
9223
9353
|
}
|
|
9224
|
-
function parseKeyValuePairs(pairs) {
|
|
9225
|
-
const result = {};
|
|
9226
|
-
for (const pair of pairs) {
|
|
9227
|
-
const eqIndex = pair.indexOf("=");
|
|
9228
|
-
if (eqIndex > 0) {
|
|
9229
|
-
const key = pair.slice(0, eqIndex);
|
|
9230
|
-
const value = pair.slice(eqIndex + 1);
|
|
9231
|
-
result[key] = value;
|
|
9232
|
-
}
|
|
9233
|
-
}
|
|
9234
|
-
return result;
|
|
9235
|
-
}
|
|
9236
9354
|
function getExistingDefaults(existingSchedule) {
|
|
9237
9355
|
const defaults = {};
|
|
9238
9356
|
if (existingSchedule?.cronExpression) {
|
|
@@ -9254,11 +9372,11 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
|
|
|
9254
9372
|
}
|
|
9255
9373
|
if (!isInteractive()) {
|
|
9256
9374
|
console.error(
|
|
9257
|
-
|
|
9375
|
+
chalk32.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
|
|
9258
9376
|
);
|
|
9259
9377
|
process.exit(1);
|
|
9260
9378
|
}
|
|
9261
|
-
const defaultIndex = existingFrequency ? FREQUENCY_CHOICES.findIndex((
|
|
9379
|
+
const defaultIndex = existingFrequency ? FREQUENCY_CHOICES.findIndex((c20) => c20.value === existingFrequency) : 0;
|
|
9262
9380
|
frequency = await promptSelect(
|
|
9263
9381
|
"Schedule frequency",
|
|
9264
9382
|
FREQUENCY_CHOICES,
|
|
@@ -9274,7 +9392,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9274
9392
|
const day2 = parseDayOption(optionDay, frequency);
|
|
9275
9393
|
if (day2 === void 0) {
|
|
9276
9394
|
console.error(
|
|
9277
|
-
|
|
9395
|
+
chalk32.red(
|
|
9278
9396
|
`\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
9279
9397
|
)
|
|
9280
9398
|
);
|
|
@@ -9283,11 +9401,11 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9283
9401
|
return day2;
|
|
9284
9402
|
}
|
|
9285
9403
|
if (!isInteractive()) {
|
|
9286
|
-
console.error(
|
|
9404
|
+
console.error(chalk32.red("\u2717 --day is required for weekly/monthly"));
|
|
9287
9405
|
process.exit(1);
|
|
9288
9406
|
}
|
|
9289
9407
|
if (frequency === "weekly") {
|
|
9290
|
-
const defaultDayIndex = existingDay !== void 0 ? DAY_OF_WEEK_CHOICES.findIndex((
|
|
9408
|
+
const defaultDayIndex = existingDay !== void 0 ? DAY_OF_WEEK_CHOICES.findIndex((c20) => c20.value === existingDay) : 0;
|
|
9291
9409
|
const day2 = await promptSelect(
|
|
9292
9410
|
"Day of week",
|
|
9293
9411
|
DAY_OF_WEEK_CHOICES,
|
|
@@ -9302,7 +9420,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9302
9420
|
if (!dayStr) return null;
|
|
9303
9421
|
const day = parseInt(dayStr, 10);
|
|
9304
9422
|
if (isNaN(day) || day < 1 || day > 31) {
|
|
9305
|
-
console.error(
|
|
9423
|
+
console.error(chalk32.red("\u2717 Day must be between 1 and 31"));
|
|
9306
9424
|
process.exit(1);
|
|
9307
9425
|
}
|
|
9308
9426
|
return day;
|
|
@@ -9311,13 +9429,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
|
|
|
9311
9429
|
if (optionTime) {
|
|
9312
9430
|
const validation = validateTimeFormat(optionTime);
|
|
9313
9431
|
if (validation !== true) {
|
|
9314
|
-
console.error(
|
|
9432
|
+
console.error(chalk32.red(`\u2717 Invalid time: ${validation}`));
|
|
9315
9433
|
process.exit(1);
|
|
9316
9434
|
}
|
|
9317
9435
|
return optionTime;
|
|
9318
9436
|
}
|
|
9319
9437
|
if (!isInteractive()) {
|
|
9320
|
-
console.error(
|
|
9438
|
+
console.error(chalk32.red("\u2717 --time is required (HH:MM format)"));
|
|
9321
9439
|
process.exit(1);
|
|
9322
9440
|
}
|
|
9323
9441
|
return await promptText(
|
|
@@ -9330,7 +9448,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9330
9448
|
if (optionDay && optionTime) {
|
|
9331
9449
|
if (!validateDateFormat(optionDay)) {
|
|
9332
9450
|
console.error(
|
|
9333
|
-
|
|
9451
|
+
chalk32.red(
|
|
9334
9452
|
`\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
|
|
9335
9453
|
)
|
|
9336
9454
|
);
|
|
@@ -9338,16 +9456,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9338
9456
|
}
|
|
9339
9457
|
if (!validateTimeFormat(optionTime)) {
|
|
9340
9458
|
console.error(
|
|
9341
|
-
|
|
9459
|
+
chalk32.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
|
|
9342
9460
|
);
|
|
9343
9461
|
process.exit(1);
|
|
9344
9462
|
}
|
|
9345
9463
|
return `${optionDay} ${optionTime}`;
|
|
9346
9464
|
}
|
|
9347
9465
|
if (!isInteractive()) {
|
|
9348
|
-
console.error(
|
|
9466
|
+
console.error(chalk32.red("\u2717 One-time schedules require interactive mode"));
|
|
9349
9467
|
console.error(
|
|
9350
|
-
|
|
9468
|
+
chalk32.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
|
|
9351
9469
|
);
|
|
9352
9470
|
process.exit(1);
|
|
9353
9471
|
}
|
|
@@ -9378,7 +9496,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
|
|
|
9378
9496
|
async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
9379
9497
|
if (optionPrompt) return optionPrompt;
|
|
9380
9498
|
if (!isInteractive()) {
|
|
9381
|
-
console.error(
|
|
9499
|
+
console.error(chalk32.red("\u2717 --prompt is required"));
|
|
9382
9500
|
process.exit(1);
|
|
9383
9501
|
}
|
|
9384
9502
|
return await promptText(
|
|
@@ -9386,96 +9504,11 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
9386
9504
|
existingPrompt || "let's start working."
|
|
9387
9505
|
);
|
|
9388
9506
|
}
|
|
9389
|
-
async function gatherVars(optionVars, existingVars) {
|
|
9390
|
-
if (optionVars.length > 0) {
|
|
9391
|
-
return parseKeyValuePairs(optionVars);
|
|
9392
|
-
}
|
|
9393
|
-
if (isInteractive() && existingVars) {
|
|
9394
|
-
const keepVars = await promptConfirm(
|
|
9395
|
-
`Keep existing variables? (${Object.keys(existingVars).join(", ")})`,
|
|
9396
|
-
true
|
|
9397
|
-
);
|
|
9398
|
-
if (keepVars) {
|
|
9399
|
-
return existingVars;
|
|
9400
|
-
}
|
|
9401
|
-
}
|
|
9402
|
-
return void 0;
|
|
9403
|
-
}
|
|
9404
|
-
async function gatherSecrets(optionSecrets, existingSecretNames) {
|
|
9405
|
-
if (optionSecrets.length > 0) {
|
|
9406
|
-
return parseKeyValuePairs(optionSecrets);
|
|
9407
|
-
}
|
|
9408
|
-
if (isInteractive() && existingSecretNames && existingSecretNames.length > 0) {
|
|
9409
|
-
const keepSecrets = await promptConfirm(
|
|
9410
|
-
`Keep existing secrets? (${existingSecretNames.join(", ")})`,
|
|
9411
|
-
true
|
|
9412
|
-
);
|
|
9413
|
-
if (keepSecrets) {
|
|
9414
|
-
return void 0;
|
|
9415
|
-
}
|
|
9416
|
-
console.log(chalk31.dim(" Note: You'll need to provide new secret values"));
|
|
9417
|
-
return {};
|
|
9418
|
-
}
|
|
9419
|
-
return void 0;
|
|
9420
|
-
}
|
|
9421
|
-
async function gatherMissingConfiguration(required, providedSecrets, providedVars, existingSecretNames) {
|
|
9422
|
-
const secrets = { ...providedSecrets };
|
|
9423
|
-
const vars = { ...providedVars };
|
|
9424
|
-
const providedSecretNames = Object.keys(providedSecrets);
|
|
9425
|
-
const existingNames = existingSecretNames ?? [];
|
|
9426
|
-
const missingSecrets = required.secrets.filter(
|
|
9427
|
-
(name) => !providedSecretNames.includes(name) && !existingNames.includes(name)
|
|
9428
|
-
);
|
|
9429
|
-
const providedVarNames = Object.keys(providedVars);
|
|
9430
|
-
const missingVars = required.vars.filter(
|
|
9431
|
-
(name) => !providedVarNames.includes(name)
|
|
9432
|
-
);
|
|
9433
|
-
if (missingSecrets.length === 0 && missingVars.length === 0) {
|
|
9434
|
-
return { secrets, vars };
|
|
9435
|
-
}
|
|
9436
|
-
if (!isInteractive()) {
|
|
9437
|
-
return { secrets, vars };
|
|
9438
|
-
}
|
|
9439
|
-
if (missingSecrets.length > 0 || missingVars.length > 0) {
|
|
9440
|
-
console.log(chalk31.yellow("\nAgent requires the following configuration:"));
|
|
9441
|
-
if (missingSecrets.length > 0) {
|
|
9442
|
-
console.log(chalk31.dim(" Secrets:"));
|
|
9443
|
-
for (const name of missingSecrets) {
|
|
9444
|
-
console.log(chalk31.dim(` ${name}`));
|
|
9445
|
-
}
|
|
9446
|
-
}
|
|
9447
|
-
if (missingVars.length > 0) {
|
|
9448
|
-
console.log(chalk31.dim(" Vars:"));
|
|
9449
|
-
for (const name of missingVars) {
|
|
9450
|
-
console.log(chalk31.dim(` ${name}`));
|
|
9451
|
-
}
|
|
9452
|
-
}
|
|
9453
|
-
console.log("");
|
|
9454
|
-
}
|
|
9455
|
-
for (const name of missingSecrets) {
|
|
9456
|
-
const value = await promptPassword(
|
|
9457
|
-
`Enter value for secret ${chalk31.cyan(name)}`
|
|
9458
|
-
);
|
|
9459
|
-
if (value) {
|
|
9460
|
-
secrets[name] = value;
|
|
9461
|
-
}
|
|
9462
|
-
}
|
|
9463
|
-
for (const name of missingVars) {
|
|
9464
|
-
const value = await promptText(
|
|
9465
|
-
`Enter value for var ${chalk31.cyan(name)}`,
|
|
9466
|
-
""
|
|
9467
|
-
);
|
|
9468
|
-
if (value) {
|
|
9469
|
-
vars[name] = value;
|
|
9470
|
-
}
|
|
9471
|
-
}
|
|
9472
|
-
return { secrets, vars };
|
|
9473
|
-
}
|
|
9474
9507
|
async function resolveAgent(agentName) {
|
|
9475
9508
|
const compose = await getComposeByName(agentName);
|
|
9476
9509
|
if (!compose) {
|
|
9477
|
-
console.error(
|
|
9478
|
-
console.error(
|
|
9510
|
+
console.error(chalk32.red(`\u2717 Agent not found: ${agentName}`));
|
|
9511
|
+
console.error(chalk32.dim(" Make sure the agent is composed first"));
|
|
9479
9512
|
process.exit(1);
|
|
9480
9513
|
}
|
|
9481
9514
|
return {
|
|
@@ -9522,7 +9555,7 @@ async function buildAndDeploy(params) {
|
|
|
9522
9555
|
const expandedSecrets = expandEnvVarsInObject(params.secrets);
|
|
9523
9556
|
console.log(
|
|
9524
9557
|
`
|
|
9525
|
-
Deploying schedule for agent ${
|
|
9558
|
+
Deploying schedule for agent ${chalk32.cyan(params.agentName)}...`
|
|
9526
9559
|
);
|
|
9527
9560
|
const deployResult = await deploySchedule({
|
|
9528
9561
|
name: params.scheduleName,
|
|
@@ -9538,12 +9571,12 @@ Deploying schedule for agent ${chalk31.cyan(params.agentName)}...`
|
|
|
9538
9571
|
displayDeployResult(params.agentName, deployResult);
|
|
9539
9572
|
}
|
|
9540
9573
|
function handleSetupError(error) {
|
|
9541
|
-
console.error(
|
|
9574
|
+
console.error(chalk32.red("\u2717 Failed to setup schedule"));
|
|
9542
9575
|
if (error instanceof Error) {
|
|
9543
9576
|
if (error.message.includes("Not authenticated")) {
|
|
9544
|
-
console.error(
|
|
9577
|
+
console.error(chalk32.dim(" Run: vm0 auth login"));
|
|
9545
9578
|
} else {
|
|
9546
|
-
console.error(
|
|
9579
|
+
console.error(chalk32.dim(` ${error.message}`));
|
|
9547
9580
|
}
|
|
9548
9581
|
}
|
|
9549
9582
|
process.exit(1);
|
|
@@ -9551,29 +9584,35 @@ function handleSetupError(error) {
|
|
|
9551
9584
|
function displayDeployResult(agentName, deployResult) {
|
|
9552
9585
|
if (deployResult.created) {
|
|
9553
9586
|
console.log(
|
|
9554
|
-
|
|
9587
|
+
chalk32.green(`\u2713 Created schedule for agent ${chalk32.cyan(agentName)}`)
|
|
9555
9588
|
);
|
|
9556
9589
|
} else {
|
|
9557
9590
|
console.log(
|
|
9558
|
-
|
|
9591
|
+
chalk32.green(`\u2713 Updated schedule for agent ${chalk32.cyan(agentName)}`)
|
|
9559
9592
|
);
|
|
9560
9593
|
}
|
|
9561
|
-
console.log(
|
|
9594
|
+
console.log(chalk32.dim(` Timezone: ${deployResult.schedule.timezone}`));
|
|
9562
9595
|
if (deployResult.schedule.cronExpression) {
|
|
9563
|
-
console.log(
|
|
9596
|
+
console.log(chalk32.dim(` Cron: ${deployResult.schedule.cronExpression}`));
|
|
9564
9597
|
if (deployResult.schedule.nextRunAt) {
|
|
9565
9598
|
const nextRun = formatInTimezone(
|
|
9566
9599
|
deployResult.schedule.nextRunAt,
|
|
9567
9600
|
deployResult.schedule.timezone
|
|
9568
9601
|
);
|
|
9569
|
-
console.log(
|
|
9602
|
+
console.log(chalk32.dim(` Next run: ${nextRun}`));
|
|
9570
9603
|
}
|
|
9571
9604
|
} else if (deployResult.schedule.atTime) {
|
|
9572
9605
|
const atTimeFormatted = formatInTimezone(
|
|
9573
9606
|
deployResult.schedule.atTime,
|
|
9574
9607
|
deployResult.schedule.timezone
|
|
9575
9608
|
);
|
|
9576
|
-
console.log(
|
|
9609
|
+
console.log(chalk32.dim(` At: ${atTimeFormatted}`));
|
|
9610
|
+
}
|
|
9611
|
+
if (deployResult.created) {
|
|
9612
|
+
console.log();
|
|
9613
|
+
console.log(
|
|
9614
|
+
` To activate: ${chalk32.cyan(`vm0 schedule enable ${agentName}`)}`
|
|
9615
|
+
);
|
|
9577
9616
|
}
|
|
9578
9617
|
}
|
|
9579
9618
|
var setupCommand = new Command28().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").action(async (agentName, options) => {
|
|
@@ -9582,7 +9621,7 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9582
9621
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
9583
9622
|
const existingSchedule = await findExistingSchedule(agentName);
|
|
9584
9623
|
console.log(
|
|
9585
|
-
|
|
9624
|
+
chalk32.dim(
|
|
9586
9625
|
existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
|
|
9587
9626
|
)
|
|
9588
9627
|
);
|
|
@@ -9592,12 +9631,12 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9592
9631
|
defaults.frequency
|
|
9593
9632
|
);
|
|
9594
9633
|
if (!frequency) {
|
|
9595
|
-
console.log(
|
|
9634
|
+
console.log(chalk32.dim("Cancelled"));
|
|
9596
9635
|
return;
|
|
9597
9636
|
}
|
|
9598
9637
|
const timing = await gatherTiming(frequency, options, defaults);
|
|
9599
9638
|
if (!timing) {
|
|
9600
|
-
console.log(
|
|
9639
|
+
console.log(chalk32.dim("Cancelled"));
|
|
9601
9640
|
return;
|
|
9602
9641
|
}
|
|
9603
9642
|
const { day, time, atTime } = timing;
|
|
@@ -9606,7 +9645,7 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9606
9645
|
existingSchedule?.timezone
|
|
9607
9646
|
);
|
|
9608
9647
|
if (!timezone) {
|
|
9609
|
-
console.log(
|
|
9648
|
+
console.log(chalk32.dim("Cancelled"));
|
|
9610
9649
|
return;
|
|
9611
9650
|
}
|
|
9612
9651
|
const promptText_ = await gatherPromptText(
|
|
@@ -9614,24 +9653,15 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9614
9653
|
existingSchedule?.prompt
|
|
9615
9654
|
);
|
|
9616
9655
|
if (!promptText_) {
|
|
9617
|
-
console.log(
|
|
9656
|
+
console.log(chalk32.dim("Cancelled"));
|
|
9618
9657
|
return;
|
|
9619
9658
|
}
|
|
9620
|
-
const
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
existingSchedule?.secretNames
|
|
9627
|
-
);
|
|
9628
|
-
const keepExistingSecrets = initialSecrets === void 0;
|
|
9629
|
-
const { secrets, vars } = await gatherMissingConfiguration(
|
|
9630
|
-
requiredConfig,
|
|
9631
|
-
initialSecrets ?? {},
|
|
9632
|
-
initialVars ?? {},
|
|
9633
|
-
existingSchedule?.secretNames
|
|
9634
|
-
);
|
|
9659
|
+
const config = await gatherConfiguration({
|
|
9660
|
+
required: requiredConfig,
|
|
9661
|
+
optionSecrets: options.secret || [],
|
|
9662
|
+
optionVars: options.var || [],
|
|
9663
|
+
existingSchedule
|
|
9664
|
+
});
|
|
9635
9665
|
await buildAndDeploy({
|
|
9636
9666
|
scheduleName,
|
|
9637
9667
|
composeId,
|
|
@@ -9642,8 +9672,8 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9642
9672
|
atTime,
|
|
9643
9673
|
timezone,
|
|
9644
9674
|
prompt: promptText_,
|
|
9645
|
-
vars: Object.keys(vars).length > 0 ? vars : void 0,
|
|
9646
|
-
secrets:
|
|
9675
|
+
vars: Object.keys(config.vars).length > 0 ? config.vars : void 0,
|
|
9676
|
+
secrets: config.preserveExistingSecrets ? void 0 : Object.keys(config.secrets).length > 0 ? config.secrets : void 0,
|
|
9647
9677
|
artifactName: options.artifactName
|
|
9648
9678
|
});
|
|
9649
9679
|
} catch (error) {
|
|
@@ -9653,14 +9683,14 @@ var setupCommand = new Command28().name("setup").description("Create or edit a s
|
|
|
9653
9683
|
|
|
9654
9684
|
// src/commands/schedule/list.ts
|
|
9655
9685
|
import { Command as Command29 } from "commander";
|
|
9656
|
-
import
|
|
9686
|
+
import chalk33 from "chalk";
|
|
9657
9687
|
var listCommand4 = new Command29().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
9658
9688
|
try {
|
|
9659
9689
|
const result = await listSchedules();
|
|
9660
9690
|
if (result.schedules.length === 0) {
|
|
9661
|
-
console.log(
|
|
9691
|
+
console.log(chalk33.dim("No schedules found"));
|
|
9662
9692
|
console.log(
|
|
9663
|
-
|
|
9693
|
+
chalk33.dim(" Create one with: vm0 schedule setup <agent-name>")
|
|
9664
9694
|
);
|
|
9665
9695
|
return;
|
|
9666
9696
|
}
|
|
@@ -9680,10 +9710,10 @@ var listCommand4 = new Command29().name("list").alias("ls").description("List al
|
|
|
9680
9710
|
"STATUS".padEnd(8),
|
|
9681
9711
|
"NEXT RUN"
|
|
9682
9712
|
].join(" ");
|
|
9683
|
-
console.log(
|
|
9713
|
+
console.log(chalk33.dim(header));
|
|
9684
9714
|
for (const schedule of result.schedules) {
|
|
9685
9715
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
9686
|
-
const status = schedule.enabled ?
|
|
9716
|
+
const status = schedule.enabled ? chalk33.green("enabled") : chalk33.yellow("disabled");
|
|
9687
9717
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
9688
9718
|
const row = [
|
|
9689
9719
|
schedule.composeName.padEnd(agentWidth),
|
|
@@ -9695,12 +9725,12 @@ var listCommand4 = new Command29().name("list").alias("ls").description("List al
|
|
|
9695
9725
|
console.log(row);
|
|
9696
9726
|
}
|
|
9697
9727
|
} catch (error) {
|
|
9698
|
-
console.error(
|
|
9728
|
+
console.error(chalk33.red("\u2717 Failed to list schedules"));
|
|
9699
9729
|
if (error instanceof Error) {
|
|
9700
9730
|
if (error.message.includes("Not authenticated")) {
|
|
9701
|
-
console.error(
|
|
9731
|
+
console.error(chalk33.dim(" Run: vm0 auth login"));
|
|
9702
9732
|
} else {
|
|
9703
|
-
console.error(
|
|
9733
|
+
console.error(chalk33.dim(` ${error.message}`));
|
|
9704
9734
|
}
|
|
9705
9735
|
}
|
|
9706
9736
|
process.exit(1);
|
|
@@ -9709,44 +9739,44 @@ var listCommand4 = new Command29().name("list").alias("ls").description("List al
|
|
|
9709
9739
|
|
|
9710
9740
|
// src/commands/schedule/status.ts
|
|
9711
9741
|
import { Command as Command30 } from "commander";
|
|
9712
|
-
import
|
|
9742
|
+
import chalk34 from "chalk";
|
|
9713
9743
|
function formatDateTimeStyled(dateStr) {
|
|
9714
|
-
if (!dateStr) return
|
|
9744
|
+
if (!dateStr) return chalk34.dim("-");
|
|
9715
9745
|
const formatted = formatDateTime(dateStr);
|
|
9716
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
9746
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk34.dim("($1)"));
|
|
9717
9747
|
}
|
|
9718
9748
|
function formatTrigger(schedule) {
|
|
9719
9749
|
if (schedule.cronExpression) {
|
|
9720
9750
|
return schedule.cronExpression;
|
|
9721
9751
|
}
|
|
9722
9752
|
if (schedule.atTime) {
|
|
9723
|
-
return `${schedule.atTime} ${
|
|
9753
|
+
return `${schedule.atTime} ${chalk34.dim("(one-time)")}`;
|
|
9724
9754
|
}
|
|
9725
|
-
return
|
|
9755
|
+
return chalk34.dim("-");
|
|
9726
9756
|
}
|
|
9727
9757
|
function formatRunStatus(status) {
|
|
9728
9758
|
switch (status) {
|
|
9729
9759
|
case "completed":
|
|
9730
|
-
return
|
|
9760
|
+
return chalk34.green(status);
|
|
9731
9761
|
case "failed":
|
|
9732
9762
|
case "timeout":
|
|
9733
|
-
return
|
|
9763
|
+
return chalk34.red(status);
|
|
9734
9764
|
case "running":
|
|
9735
|
-
return
|
|
9765
|
+
return chalk34.blue(status);
|
|
9736
9766
|
case "pending":
|
|
9737
|
-
return
|
|
9767
|
+
return chalk34.yellow(status);
|
|
9738
9768
|
default:
|
|
9739
9769
|
return status;
|
|
9740
9770
|
}
|
|
9741
9771
|
}
|
|
9742
9772
|
function printRunConfiguration(schedule) {
|
|
9743
|
-
const statusText = schedule.enabled ?
|
|
9773
|
+
const statusText = schedule.enabled ? chalk34.green("enabled") : chalk34.yellow("disabled");
|
|
9744
9774
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
9745
9775
|
console.log(
|
|
9746
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
9776
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk34.dim(`(${schedule.scopeSlug})`)}`
|
|
9747
9777
|
);
|
|
9748
9778
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
9749
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
9779
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk34.dim(promptPreview)}`);
|
|
9750
9780
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
9751
9781
|
console.log(
|
|
9752
9782
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -9783,7 +9813,7 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
9783
9813
|
console.log();
|
|
9784
9814
|
console.log("Recent Runs:");
|
|
9785
9815
|
console.log(
|
|
9786
|
-
|
|
9816
|
+
chalk34.dim("RUN ID STATUS CREATED")
|
|
9787
9817
|
);
|
|
9788
9818
|
for (const run of runs) {
|
|
9789
9819
|
const id = run.id;
|
|
@@ -9794,19 +9824,19 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
9794
9824
|
}
|
|
9795
9825
|
} catch {
|
|
9796
9826
|
console.log();
|
|
9797
|
-
console.log(
|
|
9827
|
+
console.log(chalk34.dim("Recent Runs: (unable to fetch)"));
|
|
9798
9828
|
}
|
|
9799
9829
|
}
|
|
9800
9830
|
function handleStatusError(error, agentName) {
|
|
9801
|
-
console.error(
|
|
9831
|
+
console.error(chalk34.red("\u2717 Failed to get schedule status"));
|
|
9802
9832
|
if (error instanceof Error) {
|
|
9803
9833
|
if (error.message.includes("Not authenticated")) {
|
|
9804
|
-
console.error(
|
|
9834
|
+
console.error(chalk34.dim(" Run: vm0 auth login"));
|
|
9805
9835
|
} else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
|
|
9806
|
-
console.error(
|
|
9807
|
-
console.error(
|
|
9836
|
+
console.error(chalk34.dim(` No schedule found for agent "${agentName}"`));
|
|
9837
|
+
console.error(chalk34.dim(" Run: vm0 schedule list"));
|
|
9808
9838
|
} else {
|
|
9809
|
-
console.error(
|
|
9839
|
+
console.error(chalk34.dim(` ${error.message}`));
|
|
9810
9840
|
}
|
|
9811
9841
|
}
|
|
9812
9842
|
process.exit(1);
|
|
@@ -9821,8 +9851,8 @@ var statusCommand5 = new Command30().name("status").description("Show detailed s
|
|
|
9821
9851
|
const { name, composeId } = resolved;
|
|
9822
9852
|
const schedule = await getScheduleByName({ name, composeId });
|
|
9823
9853
|
console.log();
|
|
9824
|
-
console.log(`Schedule for agent: ${
|
|
9825
|
-
console.log(
|
|
9854
|
+
console.log(`Schedule for agent: ${chalk34.cyan(agentName)}`);
|
|
9855
|
+
console.log(chalk34.dim("\u2501".repeat(50)));
|
|
9826
9856
|
printRunConfiguration(schedule);
|
|
9827
9857
|
printTimeSchedule(schedule);
|
|
9828
9858
|
const limit = Math.min(
|
|
@@ -9838,29 +9868,23 @@ var statusCommand5 = new Command30().name("status").description("Show detailed s
|
|
|
9838
9868
|
|
|
9839
9869
|
// src/commands/schedule/delete.ts
|
|
9840
9870
|
import { Command as Command31 } from "commander";
|
|
9841
|
-
import
|
|
9842
|
-
import * as readline from "readline";
|
|
9843
|
-
async function confirm(message) {
|
|
9844
|
-
const rl = readline.createInterface({
|
|
9845
|
-
input: process.stdin,
|
|
9846
|
-
output: process.stdout
|
|
9847
|
-
});
|
|
9848
|
-
return new Promise((resolve) => {
|
|
9849
|
-
rl.question(`${message} (y/N) `, (answer) => {
|
|
9850
|
-
rl.close();
|
|
9851
|
-
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
9852
|
-
});
|
|
9853
|
-
});
|
|
9854
|
-
}
|
|
9871
|
+
import chalk35 from "chalk";
|
|
9855
9872
|
var deleteCommand = new Command31().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
|
|
9856
9873
|
try {
|
|
9857
9874
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
9858
9875
|
if (!options.force) {
|
|
9859
|
-
|
|
9860
|
-
|
|
9876
|
+
if (!isInteractive()) {
|
|
9877
|
+
console.error(
|
|
9878
|
+
chalk35.red("\u2717 --force required in non-interactive mode")
|
|
9879
|
+
);
|
|
9880
|
+
process.exit(1);
|
|
9881
|
+
}
|
|
9882
|
+
const confirmed = await promptConfirm(
|
|
9883
|
+
`Delete schedule for agent ${chalk35.cyan(agentName)}?`,
|
|
9884
|
+
false
|
|
9861
9885
|
);
|
|
9862
9886
|
if (!confirmed) {
|
|
9863
|
-
console.log(
|
|
9887
|
+
console.log(chalk35.dim("Cancelled"));
|
|
9864
9888
|
return;
|
|
9865
9889
|
}
|
|
9866
9890
|
}
|
|
@@ -9869,20 +9893,20 @@ var deleteCommand = new Command31().name("delete").alias("rm").description("Dele
|
|
|
9869
9893
|
composeId: resolved.composeId
|
|
9870
9894
|
});
|
|
9871
9895
|
console.log(
|
|
9872
|
-
|
|
9896
|
+
chalk35.green(`\u2713 Deleted schedule for agent ${chalk35.cyan(agentName)}`)
|
|
9873
9897
|
);
|
|
9874
9898
|
} catch (error) {
|
|
9875
|
-
console.error(
|
|
9899
|
+
console.error(chalk35.red("\u2717 Failed to delete schedule"));
|
|
9876
9900
|
if (error instanceof Error) {
|
|
9877
9901
|
if (error.message.includes("Not authenticated")) {
|
|
9878
|
-
console.error(
|
|
9902
|
+
console.error(chalk35.dim(" Run: vm0 auth login"));
|
|
9879
9903
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
9880
9904
|
console.error(
|
|
9881
|
-
|
|
9905
|
+
chalk35.dim(` No schedule found for agent "${agentName}"`)
|
|
9882
9906
|
);
|
|
9883
|
-
console.error(
|
|
9907
|
+
console.error(chalk35.dim(" Run: vm0 schedule list"));
|
|
9884
9908
|
} else {
|
|
9885
|
-
console.error(
|
|
9909
|
+
console.error(chalk35.dim(` ${error.message}`));
|
|
9886
9910
|
}
|
|
9887
9911
|
}
|
|
9888
9912
|
process.exit(1);
|
|
@@ -9891,7 +9915,7 @@ var deleteCommand = new Command31().name("delete").alias("rm").description("Dele
|
|
|
9891
9915
|
|
|
9892
9916
|
// src/commands/schedule/enable.ts
|
|
9893
9917
|
import { Command as Command32 } from "commander";
|
|
9894
|
-
import
|
|
9918
|
+
import chalk36 from "chalk";
|
|
9895
9919
|
var enableCommand = new Command32().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
9896
9920
|
try {
|
|
9897
9921
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
@@ -9900,20 +9924,34 @@ var enableCommand = new Command32().name("enable").description("Enable a schedul
|
|
|
9900
9924
|
composeId: resolved.composeId
|
|
9901
9925
|
});
|
|
9902
9926
|
console.log(
|
|
9903
|
-
|
|
9927
|
+
chalk36.green(`\u2713 Enabled schedule for agent ${chalk36.cyan(agentName)}`)
|
|
9904
9928
|
);
|
|
9905
9929
|
} catch (error) {
|
|
9906
|
-
console.error(
|
|
9907
|
-
if (error instanceof
|
|
9930
|
+
console.error(chalk36.red("\u2717 Failed to enable schedule"));
|
|
9931
|
+
if (error instanceof ApiRequestError) {
|
|
9932
|
+
if (error.code === "SCHEDULE_PAST") {
|
|
9933
|
+
console.error(chalk36.dim(" Scheduled time has already passed"));
|
|
9934
|
+
console.error(chalk36.dim(` Run: vm0 schedule setup ${agentName}`));
|
|
9935
|
+
} else if (error.code === "NOT_FOUND") {
|
|
9936
|
+
console.error(
|
|
9937
|
+
chalk36.dim(` No schedule found for agent "${agentName}"`)
|
|
9938
|
+
);
|
|
9939
|
+
console.error(chalk36.dim(" Run: vm0 schedule list"));
|
|
9940
|
+
} else if (error.code === "UNAUTHORIZED") {
|
|
9941
|
+
console.error(chalk36.dim(" Run: vm0 auth login"));
|
|
9942
|
+
} else {
|
|
9943
|
+
console.error(chalk36.dim(` ${error.message}`));
|
|
9944
|
+
}
|
|
9945
|
+
} else if (error instanceof Error) {
|
|
9908
9946
|
if (error.message.includes("Not authenticated")) {
|
|
9909
|
-
console.error(
|
|
9910
|
-
} else if (error.message.
|
|
9947
|
+
console.error(chalk36.dim(" Run: vm0 auth login"));
|
|
9948
|
+
} else if (error.message.includes("No schedule found")) {
|
|
9911
9949
|
console.error(
|
|
9912
|
-
|
|
9950
|
+
chalk36.dim(` No schedule found for agent "${agentName}"`)
|
|
9913
9951
|
);
|
|
9914
|
-
console.error(
|
|
9952
|
+
console.error(chalk36.dim(" Run: vm0 schedule list"));
|
|
9915
9953
|
} else {
|
|
9916
|
-
console.error(
|
|
9954
|
+
console.error(chalk36.dim(` ${error.message}`));
|
|
9917
9955
|
}
|
|
9918
9956
|
}
|
|
9919
9957
|
process.exit(1);
|
|
@@ -9922,7 +9960,7 @@ var enableCommand = new Command32().name("enable").description("Enable a schedul
|
|
|
9922
9960
|
|
|
9923
9961
|
// src/commands/schedule/disable.ts
|
|
9924
9962
|
import { Command as Command33 } from "commander";
|
|
9925
|
-
import
|
|
9963
|
+
import chalk37 from "chalk";
|
|
9926
9964
|
var disableCommand = new Command33().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
9927
9965
|
try {
|
|
9928
9966
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
@@ -9931,20 +9969,20 @@ var disableCommand = new Command33().name("disable").description("Disable a sche
|
|
|
9931
9969
|
composeId: resolved.composeId
|
|
9932
9970
|
});
|
|
9933
9971
|
console.log(
|
|
9934
|
-
|
|
9972
|
+
chalk37.green(`\u2713 Disabled schedule for agent ${chalk37.cyan(agentName)}`)
|
|
9935
9973
|
);
|
|
9936
9974
|
} catch (error) {
|
|
9937
|
-
console.error(
|
|
9975
|
+
console.error(chalk37.red("\u2717 Failed to disable schedule"));
|
|
9938
9976
|
if (error instanceof Error) {
|
|
9939
9977
|
if (error.message.includes("Not authenticated")) {
|
|
9940
|
-
console.error(
|
|
9978
|
+
console.error(chalk37.dim(" Run: vm0 auth login"));
|
|
9941
9979
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
9942
9980
|
console.error(
|
|
9943
|
-
|
|
9981
|
+
chalk37.dim(` No schedule found for agent "${agentName}"`)
|
|
9944
9982
|
);
|
|
9945
|
-
console.error(
|
|
9983
|
+
console.error(chalk37.dim(" Run: vm0 schedule list"));
|
|
9946
9984
|
} else {
|
|
9947
|
-
console.error(
|
|
9985
|
+
console.error(chalk37.dim(` ${error.message}`));
|
|
9948
9986
|
}
|
|
9949
9987
|
}
|
|
9950
9988
|
process.exit(1);
|
|
@@ -9956,7 +9994,7 @@ var scheduleCommand = new Command34().name("schedule").description("Manage agent
|
|
|
9956
9994
|
|
|
9957
9995
|
// src/commands/usage.ts
|
|
9958
9996
|
import { Command as Command35 } from "commander";
|
|
9959
|
-
import
|
|
9997
|
+
import chalk38 from "chalk";
|
|
9960
9998
|
|
|
9961
9999
|
// src/lib/utils/duration-formatter.ts
|
|
9962
10000
|
function formatDuration(ms) {
|
|
@@ -10043,8 +10081,8 @@ var usageCommand = new Command35().name("usage").description("View usage statist
|
|
|
10043
10081
|
endDate = new Date(untilMs);
|
|
10044
10082
|
} catch {
|
|
10045
10083
|
console.error(
|
|
10046
|
-
|
|
10047
|
-
"
|
|
10084
|
+
chalk38.red(
|
|
10085
|
+
"\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10048
10086
|
)
|
|
10049
10087
|
);
|
|
10050
10088
|
process.exit(1);
|
|
@@ -10058,8 +10096,8 @@ var usageCommand = new Command35().name("usage").description("View usage statist
|
|
|
10058
10096
|
startDate = new Date(sinceMs);
|
|
10059
10097
|
} catch {
|
|
10060
10098
|
console.error(
|
|
10061
|
-
|
|
10062
|
-
"
|
|
10099
|
+
chalk38.red(
|
|
10100
|
+
"\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10063
10101
|
)
|
|
10064
10102
|
);
|
|
10065
10103
|
process.exit(1);
|
|
@@ -10068,14 +10106,14 @@ var usageCommand = new Command35().name("usage").description("View usage statist
|
|
|
10068
10106
|
startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
|
|
10069
10107
|
}
|
|
10070
10108
|
if (startDate >= endDate) {
|
|
10071
|
-
console.error(
|
|
10109
|
+
console.error(chalk38.red("\u2717 --since must be before --until"));
|
|
10072
10110
|
process.exit(1);
|
|
10073
10111
|
}
|
|
10074
10112
|
const rangeMs = endDate.getTime() - startDate.getTime();
|
|
10075
10113
|
if (rangeMs > MAX_RANGE_MS) {
|
|
10076
10114
|
console.error(
|
|
10077
|
-
|
|
10078
|
-
"
|
|
10115
|
+
chalk38.red(
|
|
10116
|
+
"\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
|
|
10079
10117
|
)
|
|
10080
10118
|
);
|
|
10081
10119
|
process.exit(1);
|
|
@@ -10091,19 +10129,19 @@ var usageCommand = new Command35().name("usage").description("View usage statist
|
|
|
10091
10129
|
);
|
|
10092
10130
|
console.log();
|
|
10093
10131
|
console.log(
|
|
10094
|
-
|
|
10132
|
+
chalk38.bold(
|
|
10095
10133
|
`Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
|
|
10096
10134
|
)
|
|
10097
10135
|
);
|
|
10098
10136
|
console.log();
|
|
10099
|
-
console.log(
|
|
10137
|
+
console.log(chalk38.dim("DATE RUNS RUN TIME"));
|
|
10100
10138
|
for (const day of filledDaily) {
|
|
10101
10139
|
const dateDisplay = formatDateDisplay(day.date).padEnd(10);
|
|
10102
10140
|
const runsDisplay = String(day.run_count).padStart(6);
|
|
10103
10141
|
const timeDisplay = formatDuration(day.run_time_ms);
|
|
10104
10142
|
console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
|
|
10105
10143
|
}
|
|
10106
|
-
console.log(
|
|
10144
|
+
console.log(chalk38.dim("\u2500".repeat(29)));
|
|
10107
10145
|
const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
|
|
10108
10146
|
const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
|
|
10109
10147
|
console.log(
|
|
@@ -10113,14 +10151,13 @@ var usageCommand = new Command35().name("usage").description("View usage statist
|
|
|
10113
10151
|
} catch (error) {
|
|
10114
10152
|
if (error instanceof Error) {
|
|
10115
10153
|
if (error.message.includes("Not authenticated")) {
|
|
10116
|
-
console.error(
|
|
10117
|
-
|
|
10118
|
-
);
|
|
10154
|
+
console.error(chalk38.red("\u2717 Not authenticated"));
|
|
10155
|
+
console.error(chalk38.dim(" Run: vm0 auth login"));
|
|
10119
10156
|
} else {
|
|
10120
|
-
console.error(
|
|
10157
|
+
console.error(chalk38.red(`\u2717 ${error.message}`));
|
|
10121
10158
|
}
|
|
10122
10159
|
} else {
|
|
10123
|
-
console.error(
|
|
10160
|
+
console.error(chalk38.red("\u2717 An unexpected error occurred"));
|
|
10124
10161
|
}
|
|
10125
10162
|
process.exit(1);
|
|
10126
10163
|
}
|
|
@@ -10131,42 +10168,42 @@ import { Command as Command39 } from "commander";
|
|
|
10131
10168
|
|
|
10132
10169
|
// src/commands/credential/list.ts
|
|
10133
10170
|
import { Command as Command36 } from "commander";
|
|
10134
|
-
import
|
|
10171
|
+
import chalk39 from "chalk";
|
|
10135
10172
|
var listCommand5 = new Command36().name("list").alias("ls").description("List all credentials").action(async () => {
|
|
10136
10173
|
try {
|
|
10137
10174
|
const result = await listCredentials();
|
|
10138
10175
|
if (result.credentials.length === 0) {
|
|
10139
|
-
console.log(
|
|
10176
|
+
console.log(chalk39.dim("No credentials found"));
|
|
10140
10177
|
console.log();
|
|
10141
10178
|
console.log("To add a credential:");
|
|
10142
|
-
console.log(
|
|
10179
|
+
console.log(chalk39.cyan(" vm0 credential set MY_API_KEY <value>"));
|
|
10143
10180
|
return;
|
|
10144
10181
|
}
|
|
10145
|
-
console.log(
|
|
10182
|
+
console.log(chalk39.bold("Credentials:"));
|
|
10146
10183
|
console.log();
|
|
10147
10184
|
for (const credential of result.credentials) {
|
|
10148
|
-
const typeIndicator = credential.type === "model-provider" ?
|
|
10149
|
-
console.log(` ${
|
|
10185
|
+
const typeIndicator = credential.type === "model-provider" ? chalk39.dim(" [model-provider]") : "";
|
|
10186
|
+
console.log(` ${chalk39.cyan(credential.name)}${typeIndicator}`);
|
|
10150
10187
|
if (credential.description) {
|
|
10151
|
-
console.log(` ${
|
|
10188
|
+
console.log(` ${chalk39.dim(credential.description)}`);
|
|
10152
10189
|
}
|
|
10153
10190
|
console.log(
|
|
10154
|
-
` ${
|
|
10191
|
+
` ${chalk39.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
|
|
10155
10192
|
);
|
|
10156
10193
|
console.log();
|
|
10157
10194
|
}
|
|
10158
10195
|
console.log(
|
|
10159
|
-
|
|
10196
|
+
chalk39.dim(`Total: ${result.credentials.length} credential(s)`)
|
|
10160
10197
|
);
|
|
10161
10198
|
} catch (error) {
|
|
10162
10199
|
if (error instanceof Error) {
|
|
10163
10200
|
if (error.message.includes("Not authenticated")) {
|
|
10164
|
-
console.error(
|
|
10201
|
+
console.error(chalk39.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10165
10202
|
} else {
|
|
10166
|
-
console.error(
|
|
10203
|
+
console.error(chalk39.red(`\u2717 ${error.message}`));
|
|
10167
10204
|
}
|
|
10168
10205
|
} else {
|
|
10169
|
-
console.error(
|
|
10206
|
+
console.error(chalk39.red("\u2717 An unexpected error occurred"));
|
|
10170
10207
|
}
|
|
10171
10208
|
process.exit(1);
|
|
10172
10209
|
}
|
|
@@ -10174,7 +10211,7 @@ var listCommand5 = new Command36().name("list").alias("ls").description("List al
|
|
|
10174
10211
|
|
|
10175
10212
|
// src/commands/credential/set.ts
|
|
10176
10213
|
import { Command as Command37 } from "commander";
|
|
10177
|
-
import
|
|
10214
|
+
import chalk40 from "chalk";
|
|
10178
10215
|
var setCommand2 = new Command37().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
|
|
10179
10216
|
async (name, value, options) => {
|
|
10180
10217
|
try {
|
|
@@ -10183,29 +10220,29 @@ var setCommand2 = new Command37().name("set").description("Create or update a cr
|
|
|
10183
10220
|
value,
|
|
10184
10221
|
description: options.description
|
|
10185
10222
|
});
|
|
10186
|
-
console.log(
|
|
10223
|
+
console.log(chalk40.green(`\u2713 Credential "${credential.name}" saved`));
|
|
10187
10224
|
console.log();
|
|
10188
10225
|
console.log("Use in vm0.yaml:");
|
|
10189
|
-
console.log(
|
|
10190
|
-
console.log(
|
|
10226
|
+
console.log(chalk40.cyan(` environment:`));
|
|
10227
|
+
console.log(chalk40.cyan(` ${name}: \${{ credentials.${name} }}`));
|
|
10191
10228
|
} catch (error) {
|
|
10192
10229
|
if (error instanceof Error) {
|
|
10193
10230
|
if (error.message.includes("Not authenticated")) {
|
|
10194
10231
|
console.error(
|
|
10195
|
-
|
|
10232
|
+
chalk40.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10196
10233
|
);
|
|
10197
10234
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
10198
|
-
console.error(
|
|
10235
|
+
console.error(chalk40.red(`\u2717 ${error.message}`));
|
|
10199
10236
|
console.log();
|
|
10200
10237
|
console.log("Examples of valid credential names:");
|
|
10201
|
-
console.log(
|
|
10202
|
-
console.log(
|
|
10203
|
-
console.log(
|
|
10238
|
+
console.log(chalk40.dim(" MY_API_KEY"));
|
|
10239
|
+
console.log(chalk40.dim(" GITHUB_TOKEN"));
|
|
10240
|
+
console.log(chalk40.dim(" AWS_ACCESS_KEY_ID"));
|
|
10204
10241
|
} else {
|
|
10205
|
-
console.error(
|
|
10242
|
+
console.error(chalk40.red(`\u2717 ${error.message}`));
|
|
10206
10243
|
}
|
|
10207
10244
|
} else {
|
|
10208
|
-
console.error(
|
|
10245
|
+
console.error(chalk40.red("\u2717 An unexpected error occurred"));
|
|
10209
10246
|
}
|
|
10210
10247
|
process.exit(1);
|
|
10211
10248
|
}
|
|
@@ -10214,48 +10251,42 @@ var setCommand2 = new Command37().name("set").description("Create or update a cr
|
|
|
10214
10251
|
|
|
10215
10252
|
// src/commands/credential/delete.ts
|
|
10216
10253
|
import { Command as Command38 } from "commander";
|
|
10217
|
-
import
|
|
10254
|
+
import chalk41 from "chalk";
|
|
10218
10255
|
var deleteCommand2 = new Command38().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
10219
10256
|
try {
|
|
10220
10257
|
try {
|
|
10221
10258
|
await getCredential(name);
|
|
10222
10259
|
} catch {
|
|
10223
|
-
console.error(
|
|
10260
|
+
console.error(chalk41.red(`\u2717 Credential "${name}" not found`));
|
|
10224
10261
|
process.exit(1);
|
|
10225
10262
|
}
|
|
10226
10263
|
if (!options.yes) {
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
output: process.stdout
|
|
10231
|
-
});
|
|
10232
|
-
const confirmed = await new Promise((resolve) => {
|
|
10233
|
-
rl.question(
|
|
10234
|
-
chalk40.yellow(
|
|
10235
|
-
`Are you sure you want to delete credential "${name}"? (y/N) `
|
|
10236
|
-
),
|
|
10237
|
-
(answer) => {
|
|
10238
|
-
rl.close();
|
|
10239
|
-
resolve(answer.toLowerCase() === "y");
|
|
10240
|
-
}
|
|
10264
|
+
if (!isInteractive()) {
|
|
10265
|
+
console.error(
|
|
10266
|
+
chalk41.red("\u2717 --yes flag is required in non-interactive mode")
|
|
10241
10267
|
);
|
|
10242
|
-
|
|
10268
|
+
process.exit(1);
|
|
10269
|
+
}
|
|
10270
|
+
const confirmed = await promptConfirm(
|
|
10271
|
+
`Are you sure you want to delete credential "${name}"?`,
|
|
10272
|
+
false
|
|
10273
|
+
);
|
|
10243
10274
|
if (!confirmed) {
|
|
10244
|
-
console.log(
|
|
10275
|
+
console.log(chalk41.dim("Cancelled"));
|
|
10245
10276
|
return;
|
|
10246
10277
|
}
|
|
10247
10278
|
}
|
|
10248
10279
|
await deleteCredential(name);
|
|
10249
|
-
console.log(
|
|
10280
|
+
console.log(chalk41.green(`\u2713 Credential "${name}" deleted`));
|
|
10250
10281
|
} catch (error) {
|
|
10251
10282
|
if (error instanceof Error) {
|
|
10252
10283
|
if (error.message.includes("Not authenticated")) {
|
|
10253
|
-
console.error(
|
|
10284
|
+
console.error(chalk41.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10254
10285
|
} else {
|
|
10255
|
-
console.error(
|
|
10286
|
+
console.error(chalk41.red(`\u2717 ${error.message}`));
|
|
10256
10287
|
}
|
|
10257
10288
|
} else {
|
|
10258
|
-
console.error(
|
|
10289
|
+
console.error(chalk41.red("\u2717 An unexpected error occurred"));
|
|
10259
10290
|
}
|
|
10260
10291
|
process.exit(1);
|
|
10261
10292
|
}
|
|
@@ -10269,15 +10300,15 @@ import { Command as Command44 } from "commander";
|
|
|
10269
10300
|
|
|
10270
10301
|
// src/commands/model-provider/list.ts
|
|
10271
10302
|
import { Command as Command40 } from "commander";
|
|
10272
|
-
import
|
|
10303
|
+
import chalk42 from "chalk";
|
|
10273
10304
|
var listCommand6 = new Command40().name("list").alias("ls").description("List all model providers").action(async () => {
|
|
10274
10305
|
try {
|
|
10275
10306
|
const result = await listModelProviders();
|
|
10276
10307
|
if (result.modelProviders.length === 0) {
|
|
10277
|
-
console.log(
|
|
10308
|
+
console.log(chalk42.dim("No model providers configured"));
|
|
10278
10309
|
console.log();
|
|
10279
10310
|
console.log("To add a model provider:");
|
|
10280
|
-
console.log(
|
|
10311
|
+
console.log(chalk42.cyan(" vm0 model-provider setup"));
|
|
10281
10312
|
return;
|
|
10282
10313
|
}
|
|
10283
10314
|
const byFramework = result.modelProviders.reduce(
|
|
@@ -10291,15 +10322,15 @@ var listCommand6 = new Command40().name("list").alias("ls").description("List al
|
|
|
10291
10322
|
},
|
|
10292
10323
|
{}
|
|
10293
10324
|
);
|
|
10294
|
-
console.log(
|
|
10325
|
+
console.log(chalk42.bold("Model Providers:"));
|
|
10295
10326
|
console.log();
|
|
10296
10327
|
for (const [framework, providers] of Object.entries(byFramework)) {
|
|
10297
|
-
console.log(` ${
|
|
10328
|
+
console.log(` ${chalk42.cyan(framework)}:`);
|
|
10298
10329
|
for (const provider of providers) {
|
|
10299
|
-
const defaultTag = provider.isDefault ?
|
|
10330
|
+
const defaultTag = provider.isDefault ? chalk42.green(" (default)") : "";
|
|
10300
10331
|
console.log(` ${provider.type}${defaultTag}`);
|
|
10301
10332
|
console.log(
|
|
10302
|
-
|
|
10333
|
+
chalk42.dim(
|
|
10303
10334
|
` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
|
|
10304
10335
|
)
|
|
10305
10336
|
);
|
|
@@ -10307,17 +10338,17 @@ var listCommand6 = new Command40().name("list").alias("ls").description("List al
|
|
|
10307
10338
|
console.log();
|
|
10308
10339
|
}
|
|
10309
10340
|
console.log(
|
|
10310
|
-
|
|
10341
|
+
chalk42.dim(`Total: ${result.modelProviders.length} provider(s)`)
|
|
10311
10342
|
);
|
|
10312
10343
|
} catch (error) {
|
|
10313
10344
|
if (error instanceof Error) {
|
|
10314
10345
|
if (error.message.includes("Not authenticated")) {
|
|
10315
|
-
console.error(
|
|
10346
|
+
console.error(chalk42.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10316
10347
|
} else {
|
|
10317
|
-
console.error(
|
|
10348
|
+
console.error(chalk42.red(`\u2717 ${error.message}`));
|
|
10318
10349
|
}
|
|
10319
10350
|
} else {
|
|
10320
|
-
console.error(
|
|
10351
|
+
console.error(chalk42.red("\u2717 An unexpected error occurred"));
|
|
10321
10352
|
}
|
|
10322
10353
|
process.exit(1);
|
|
10323
10354
|
}
|
|
@@ -10325,8 +10356,8 @@ var listCommand6 = new Command40().name("list").alias("ls").description("List al
|
|
|
10325
10356
|
|
|
10326
10357
|
// src/commands/model-provider/setup.ts
|
|
10327
10358
|
import { Command as Command41 } from "commander";
|
|
10328
|
-
import
|
|
10329
|
-
import
|
|
10359
|
+
import chalk43 from "chalk";
|
|
10360
|
+
import prompts2 from "prompts";
|
|
10330
10361
|
var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
10331
10362
|
([type, config]) => ({
|
|
10332
10363
|
title: config.label,
|
|
@@ -10344,11 +10375,11 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10344
10375
|
const shouldConvert = options.convert ?? false;
|
|
10345
10376
|
if (options.type && options.credential) {
|
|
10346
10377
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(options.type)) {
|
|
10347
|
-
console.error(
|
|
10378
|
+
console.error(chalk43.red(`\u2717 Invalid type "${options.type}"`));
|
|
10348
10379
|
console.log();
|
|
10349
10380
|
console.log("Valid types:");
|
|
10350
10381
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10351
|
-
console.log(` ${
|
|
10382
|
+
console.log(` ${chalk43.cyan(t)} - ${config.label}`);
|
|
10352
10383
|
}
|
|
10353
10384
|
process.exit(1);
|
|
10354
10385
|
}
|
|
@@ -10356,22 +10387,22 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10356
10387
|
credential = options.credential;
|
|
10357
10388
|
} else if (options.type || options.credential) {
|
|
10358
10389
|
console.error(
|
|
10359
|
-
|
|
10390
|
+
chalk43.red("\u2717 Both --type and --credential are required")
|
|
10360
10391
|
);
|
|
10361
10392
|
process.exit(1);
|
|
10362
10393
|
} else {
|
|
10363
10394
|
if (!isInteractive()) {
|
|
10364
|
-
console.error(
|
|
10395
|
+
console.error(chalk43.red("\u2717 Interactive mode requires a TTY"));
|
|
10365
10396
|
console.log();
|
|
10366
10397
|
console.log("Use non-interactive mode:");
|
|
10367
10398
|
console.log(
|
|
10368
|
-
|
|
10399
|
+
chalk43.cyan(
|
|
10369
10400
|
' vm0 model-provider setup --type <type> --credential "<value>"'
|
|
10370
10401
|
)
|
|
10371
10402
|
);
|
|
10372
10403
|
process.exit(1);
|
|
10373
10404
|
}
|
|
10374
|
-
const typeResponse = await
|
|
10405
|
+
const typeResponse = await prompts2(
|
|
10375
10406
|
{
|
|
10376
10407
|
type: "select",
|
|
10377
10408
|
name: "type",
|
|
@@ -10383,7 +10414,7 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10383
10414
|
type = typeResponse.type;
|
|
10384
10415
|
const checkResult = await checkModelProviderCredential(type);
|
|
10385
10416
|
if (checkResult.exists && checkResult.currentType === "user") {
|
|
10386
|
-
const convertResponse = await
|
|
10417
|
+
const convertResponse = await prompts2(
|
|
10387
10418
|
{
|
|
10388
10419
|
type: "confirm",
|
|
10389
10420
|
name: "convert",
|
|
@@ -10396,21 +10427,21 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10396
10427
|
const provider2 = await convertModelProviderCredential(type);
|
|
10397
10428
|
const defaultNote2 = provider2.isDefault ? ` (default for ${provider2.framework})` : "";
|
|
10398
10429
|
console.log(
|
|
10399
|
-
|
|
10400
|
-
|
|
10430
|
+
chalk43.green(
|
|
10431
|
+
`\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote2}`
|
|
10401
10432
|
)
|
|
10402
10433
|
);
|
|
10403
10434
|
return;
|
|
10404
10435
|
} else {
|
|
10405
|
-
console.log(
|
|
10436
|
+
console.log(chalk43.dim("Aborted"));
|
|
10406
10437
|
process.exit(0);
|
|
10407
10438
|
}
|
|
10408
10439
|
}
|
|
10409
10440
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
10410
10441
|
console.log();
|
|
10411
|
-
console.log(
|
|
10442
|
+
console.log(chalk43.dim(config.helpText));
|
|
10412
10443
|
console.log();
|
|
10413
|
-
const credentialResponse = await
|
|
10444
|
+
const credentialResponse = await prompts2(
|
|
10414
10445
|
{
|
|
10415
10446
|
type: "password",
|
|
10416
10447
|
name: "credential",
|
|
@@ -10429,24 +10460,24 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10429
10460
|
const action = created ? "created" : "updated";
|
|
10430
10461
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
10431
10462
|
console.log(
|
|
10432
|
-
|
|
10463
|
+
chalk43.green(`\u2713 Model provider "${type}" ${action}${defaultNote}`)
|
|
10433
10464
|
);
|
|
10434
10465
|
} catch (error) {
|
|
10435
10466
|
if (error instanceof Error) {
|
|
10436
10467
|
if (error.message.includes("already exists")) {
|
|
10437
|
-
console.error(
|
|
10468
|
+
console.error(chalk43.red(`\u2717 ${error.message}`));
|
|
10438
10469
|
console.log();
|
|
10439
10470
|
console.log("To convert the existing credential, run:");
|
|
10440
|
-
console.log(
|
|
10471
|
+
console.log(chalk43.cyan(" vm0 model-provider setup --convert"));
|
|
10441
10472
|
} else if (error.message.includes("Not authenticated")) {
|
|
10442
10473
|
console.error(
|
|
10443
|
-
|
|
10474
|
+
chalk43.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10444
10475
|
);
|
|
10445
10476
|
} else {
|
|
10446
|
-
console.error(
|
|
10477
|
+
console.error(chalk43.red(`\u2717 ${error.message}`));
|
|
10447
10478
|
}
|
|
10448
10479
|
} else {
|
|
10449
|
-
console.error(
|
|
10480
|
+
console.error(chalk43.red("\u2717 An unexpected error occurred"));
|
|
10450
10481
|
}
|
|
10451
10482
|
process.exit(1);
|
|
10452
10483
|
}
|
|
@@ -10455,31 +10486,31 @@ var setupCommand2 = new Command41().name("setup").description("Configure a model
|
|
|
10455
10486
|
|
|
10456
10487
|
// src/commands/model-provider/delete.ts
|
|
10457
10488
|
import { Command as Command42 } from "commander";
|
|
10458
|
-
import
|
|
10489
|
+
import chalk44 from "chalk";
|
|
10459
10490
|
var deleteCommand3 = new Command42().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
|
|
10460
10491
|
try {
|
|
10461
10492
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10462
|
-
console.error(
|
|
10493
|
+
console.error(chalk44.red(`\u2717 Invalid type "${type}"`));
|
|
10463
10494
|
console.log();
|
|
10464
10495
|
console.log("Valid types:");
|
|
10465
10496
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10466
|
-
console.log(` ${
|
|
10497
|
+
console.log(` ${chalk44.cyan(t)} - ${config.label}`);
|
|
10467
10498
|
}
|
|
10468
10499
|
process.exit(1);
|
|
10469
10500
|
}
|
|
10470
10501
|
await deleteModelProvider(type);
|
|
10471
|
-
console.log(
|
|
10502
|
+
console.log(chalk44.green(`\u2713 Model provider "${type}" deleted`));
|
|
10472
10503
|
} catch (error) {
|
|
10473
10504
|
if (error instanceof Error) {
|
|
10474
10505
|
if (error.message.includes("not found")) {
|
|
10475
|
-
console.error(
|
|
10506
|
+
console.error(chalk44.red(`\u2717 Model provider "${type}" not found`));
|
|
10476
10507
|
} else if (error.message.includes("Not authenticated")) {
|
|
10477
|
-
console.error(
|
|
10508
|
+
console.error(chalk44.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10478
10509
|
} else {
|
|
10479
|
-
console.error(
|
|
10510
|
+
console.error(chalk44.red(`\u2717 ${error.message}`));
|
|
10480
10511
|
}
|
|
10481
10512
|
} else {
|
|
10482
|
-
console.error(
|
|
10513
|
+
console.error(chalk44.red("\u2717 An unexpected error occurred"));
|
|
10483
10514
|
}
|
|
10484
10515
|
process.exit(1);
|
|
10485
10516
|
}
|
|
@@ -10487,35 +10518,35 @@ var deleteCommand3 = new Command42().name("delete").description("Delete a model
|
|
|
10487
10518
|
|
|
10488
10519
|
// src/commands/model-provider/set-default.ts
|
|
10489
10520
|
import { Command as Command43 } from "commander";
|
|
10490
|
-
import
|
|
10521
|
+
import chalk45 from "chalk";
|
|
10491
10522
|
var setDefaultCommand = new Command43().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
|
|
10492
10523
|
try {
|
|
10493
10524
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10494
|
-
console.error(
|
|
10525
|
+
console.error(chalk45.red(`\u2717 Invalid type "${type}"`));
|
|
10495
10526
|
console.log();
|
|
10496
10527
|
console.log("Valid types:");
|
|
10497
10528
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10498
|
-
console.log(` ${
|
|
10529
|
+
console.log(` ${chalk45.cyan(t)} - ${config.label}`);
|
|
10499
10530
|
}
|
|
10500
10531
|
process.exit(1);
|
|
10501
10532
|
}
|
|
10502
10533
|
const provider = await setModelProviderDefault(type);
|
|
10503
10534
|
console.log(
|
|
10504
|
-
|
|
10505
|
-
|
|
10535
|
+
chalk45.green(
|
|
10536
|
+
`\u2713 Default for ${provider.framework} set to "${provider.type}"`
|
|
10506
10537
|
)
|
|
10507
10538
|
);
|
|
10508
10539
|
} catch (error) {
|
|
10509
10540
|
if (error instanceof Error) {
|
|
10510
10541
|
if (error.message.includes("not found")) {
|
|
10511
|
-
console.error(
|
|
10542
|
+
console.error(chalk45.red(`\u2717 Model provider "${type}" not found`));
|
|
10512
10543
|
} else if (error.message.includes("Not authenticated")) {
|
|
10513
|
-
console.error(
|
|
10544
|
+
console.error(chalk45.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10514
10545
|
} else {
|
|
10515
|
-
console.error(
|
|
10546
|
+
console.error(chalk45.red(`\u2717 ${error.message}`));
|
|
10516
10547
|
}
|
|
10517
10548
|
} else {
|
|
10518
|
-
console.error(
|
|
10549
|
+
console.error(chalk45.red("\u2717 An unexpected error occurred"));
|
|
10519
10550
|
}
|
|
10520
10551
|
process.exit(1);
|
|
10521
10552
|
}
|
|
@@ -10526,9 +10557,9 @@ var modelProviderCommand = new Command44().name("model-provider").description("M
|
|
|
10526
10557
|
|
|
10527
10558
|
// src/index.ts
|
|
10528
10559
|
var program = new Command45();
|
|
10529
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("8.
|
|
10560
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("8.1.1");
|
|
10530
10561
|
program.command("info").description("Display environment information").action(async () => {
|
|
10531
|
-
console.log(
|
|
10562
|
+
console.log(chalk46.bold("System Information:"));
|
|
10532
10563
|
console.log(`Node Version: ${process.version}`);
|
|
10533
10564
|
console.log(`Platform: ${process.platform}`);
|
|
10534
10565
|
console.log(`Architecture: ${process.arch}`);
|