@vm0/cli 9.4.0 → 9.4.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 +890 -848
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
|
|
4
|
+
import { Command as Command58 } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/commands/auth/index.ts
|
|
7
|
+
import { Command as Command5 } from "commander";
|
|
8
|
+
|
|
9
|
+
// src/commands/auth/login.ts
|
|
10
|
+
import { Command } from "commander";
|
|
6
11
|
|
|
7
12
|
// src/lib/api/auth.ts
|
|
8
13
|
import chalk from "chalk";
|
|
@@ -191,14 +196,46 @@ async function setupToken() {
|
|
|
191
196
|
}
|
|
192
197
|
|
|
193
198
|
// src/commands/auth/login.ts
|
|
194
|
-
import { Command } from "commander";
|
|
195
199
|
var loginCommand = new Command().name("login").description("Log in to VM0 (use VM0_API_URL env var to set API URL)").action(async () => {
|
|
196
200
|
await authenticate();
|
|
197
201
|
});
|
|
198
202
|
|
|
199
|
-
// src/commands/
|
|
203
|
+
// src/commands/auth/logout.ts
|
|
200
204
|
import { Command as Command2 } from "commander";
|
|
205
|
+
var logoutCommand = new Command2().name("logout").description("Log out of VM0").action(async () => {
|
|
206
|
+
await logout();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// src/commands/auth/status.ts
|
|
210
|
+
import { Command as Command3 } from "commander";
|
|
211
|
+
var statusCommand = new Command3().name("status").description("Show current authentication status").action(async () => {
|
|
212
|
+
await checkAuthStatus();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// src/commands/auth/setup-token.ts
|
|
216
|
+
import { Command as Command4 } from "commander";
|
|
217
|
+
var setupTokenCommand = new Command4().name("setup-token").description("Output auth token for CI/CD environments").action(async () => {
|
|
218
|
+
await setupToken();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// src/commands/auth/index.ts
|
|
222
|
+
var authCommand = new Command5().name("auth").description("Authenticate vm0").addCommand(loginCommand).addCommand(logoutCommand).addCommand(statusCommand).addCommand(setupTokenCommand);
|
|
223
|
+
|
|
224
|
+
// src/commands/info/index.ts
|
|
225
|
+
import { Command as Command6 } from "commander";
|
|
201
226
|
import chalk2 from "chalk";
|
|
227
|
+
var infoCommand = new Command6().name("info").description("Display environment information").action(async () => {
|
|
228
|
+
console.log(chalk2.bold("System Information:"));
|
|
229
|
+
console.log(`Node Version: ${process.version}`);
|
|
230
|
+
console.log(`Platform: ${process.platform}`);
|
|
231
|
+
console.log(`Architecture: ${process.arch}`);
|
|
232
|
+
const apiUrl = await getApiUrl();
|
|
233
|
+
console.log(`API Host: ${apiUrl}`);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// src/commands/compose/index.ts
|
|
237
|
+
import { Command as Command7 } from "commander";
|
|
238
|
+
import chalk3 from "chalk";
|
|
202
239
|
import { readFile as readFile4 } from "fs/promises";
|
|
203
240
|
import { existsSync as existsSync3 } from "fs";
|
|
204
241
|
import { dirname as dirname2 } from "path";
|
|
@@ -3209,10 +3246,10 @@ async function getRawHeaders() {
|
|
|
3209
3246
|
}
|
|
3210
3247
|
return headers;
|
|
3211
3248
|
}
|
|
3212
|
-
async function httpGet(
|
|
3249
|
+
async function httpGet(path17) {
|
|
3213
3250
|
const baseUrl = await getBaseUrl();
|
|
3214
3251
|
const headers = await getRawHeaders();
|
|
3215
|
-
return fetch(`${baseUrl}${
|
|
3252
|
+
return fetch(`${baseUrl}${path17}`, {
|
|
3216
3253
|
method: "GET",
|
|
3217
3254
|
headers
|
|
3218
3255
|
});
|
|
@@ -3717,49 +3754,49 @@ var cliComposeSchema = z24.object({
|
|
|
3717
3754
|
function formatZodError(error) {
|
|
3718
3755
|
const issue = error.issues[0];
|
|
3719
3756
|
if (!issue) return "Validation failed";
|
|
3720
|
-
const
|
|
3757
|
+
const path17 = issue.path.join(".");
|
|
3721
3758
|
const message = issue.message;
|
|
3722
|
-
if (!
|
|
3759
|
+
if (!path17) return message;
|
|
3723
3760
|
if (issue.code === "invalid_type") {
|
|
3724
3761
|
const received = issue.received;
|
|
3725
3762
|
const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
|
|
3726
|
-
if (
|
|
3763
|
+
if (path17 === "version" && isMissing) {
|
|
3727
3764
|
return "Missing config.version";
|
|
3728
3765
|
}
|
|
3729
|
-
if (
|
|
3766
|
+
if (path17 === "agents" && isMissing) {
|
|
3730
3767
|
return "Missing agents object in config";
|
|
3731
3768
|
}
|
|
3732
|
-
if (
|
|
3733
|
-
const volumeKey =
|
|
3769
|
+
if (path17.startsWith("volumes.") && path17.endsWith(".name")) {
|
|
3770
|
+
const volumeKey = path17.split(".")[1];
|
|
3734
3771
|
return `Volume "${volumeKey}" must have a 'name' field (string)`;
|
|
3735
3772
|
}
|
|
3736
|
-
if (
|
|
3737
|
-
const volumeKey =
|
|
3773
|
+
if (path17.startsWith("volumes.") && path17.endsWith(".version")) {
|
|
3774
|
+
const volumeKey = path17.split(".")[1];
|
|
3738
3775
|
return `Volume "${volumeKey}" must have a 'version' field (string)`;
|
|
3739
3776
|
}
|
|
3740
3777
|
if (issue.expected === "array") {
|
|
3741
|
-
const fieldName =
|
|
3778
|
+
const fieldName = path17.replace(/^agents\.[^.]+\./, "agent.");
|
|
3742
3779
|
return `${fieldName} must be an array`;
|
|
3743
3780
|
}
|
|
3744
3781
|
if (issue.expected === "string" && received === "number") {
|
|
3745
|
-
const fieldName =
|
|
3782
|
+
const fieldName = path17.replace(/^agents\.[^.]+\./, "agent.");
|
|
3746
3783
|
const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
|
|
3747
3784
|
if (match) {
|
|
3748
3785
|
return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
|
|
3749
3786
|
}
|
|
3750
3787
|
}
|
|
3751
3788
|
}
|
|
3752
|
-
if (issue.code === "invalid_key" &&
|
|
3789
|
+
if (issue.code === "invalid_key" && path17.startsWith("agents.")) {
|
|
3753
3790
|
return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
|
|
3754
3791
|
}
|
|
3755
|
-
if (message === "Invalid key in record" &&
|
|
3792
|
+
if (message === "Invalid key in record" && path17.startsWith("agents.")) {
|
|
3756
3793
|
return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
|
|
3757
3794
|
}
|
|
3758
3795
|
if (issue.code === "custom") {
|
|
3759
3796
|
return message;
|
|
3760
3797
|
}
|
|
3761
|
-
if (
|
|
3762
|
-
const cleanPath =
|
|
3798
|
+
if (path17.startsWith("agents.")) {
|
|
3799
|
+
const cleanPath = path17.replace(/^agents\.[^.]+\./, "agent.");
|
|
3763
3800
|
if (message.startsWith("Invalid input:")) {
|
|
3764
3801
|
const match = message.match(/expected (\w+), received (\w+)/);
|
|
3765
3802
|
if (match && match[1] === "string" && match[2] === "number") {
|
|
@@ -3771,7 +3808,7 @@ function formatZodError(error) {
|
|
|
3771
3808
|
}
|
|
3772
3809
|
return `${cleanPath}: ${message}`;
|
|
3773
3810
|
}
|
|
3774
|
-
return `${
|
|
3811
|
+
return `${path17}: ${message}`;
|
|
3775
3812
|
}
|
|
3776
3813
|
function validateAgentName(name) {
|
|
3777
3814
|
return cliAgentNameSchema.safeParse(name).success;
|
|
@@ -4339,16 +4376,16 @@ async function promptPassword(message) {
|
|
|
4339
4376
|
return response.value;
|
|
4340
4377
|
}
|
|
4341
4378
|
|
|
4342
|
-
// src/commands/compose.ts
|
|
4379
|
+
// src/commands/compose/index.ts
|
|
4343
4380
|
function getSecretsFromComposeContent(content) {
|
|
4344
4381
|
const refs = extractVariableReferences(content);
|
|
4345
4382
|
const grouped = groupVariablesBySource(refs);
|
|
4346
4383
|
return new Set(grouped.secrets.map((r) => r.name));
|
|
4347
4384
|
}
|
|
4348
|
-
var composeCommand = new
|
|
4385
|
+
var composeCommand = new Command7().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument("<agent-yaml>", "Path to agent YAML file").option("-y, --yes", "Skip confirmation prompts for skill requirements").action(async (configFile, options) => {
|
|
4349
4386
|
try {
|
|
4350
4387
|
if (!existsSync3(configFile)) {
|
|
4351
|
-
console.error(
|
|
4388
|
+
console.error(chalk3.red(`\u2717 Config file not found: ${configFile}`));
|
|
4352
4389
|
process.exit(1);
|
|
4353
4390
|
}
|
|
4354
4391
|
const content = await readFile4(configFile, "utf8");
|
|
@@ -4356,15 +4393,15 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4356
4393
|
try {
|
|
4357
4394
|
config = parseYaml2(content);
|
|
4358
4395
|
} catch (error) {
|
|
4359
|
-
console.error(
|
|
4396
|
+
console.error(chalk3.red("\u2717 Invalid YAML format"));
|
|
4360
4397
|
if (error instanceof Error) {
|
|
4361
|
-
console.error(
|
|
4398
|
+
console.error(chalk3.dim(` ${error.message}`));
|
|
4362
4399
|
}
|
|
4363
4400
|
process.exit(1);
|
|
4364
4401
|
}
|
|
4365
4402
|
const validation = validateAgentCompose(config);
|
|
4366
4403
|
if (!validation.valid) {
|
|
4367
|
-
console.error(
|
|
4404
|
+
console.error(chalk3.red(`\u2717 ${validation.error}`));
|
|
4368
4405
|
process.exit(1);
|
|
4369
4406
|
}
|
|
4370
4407
|
const cfg = config;
|
|
@@ -4373,13 +4410,13 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4373
4410
|
const image = agentConfig.image;
|
|
4374
4411
|
if (image) {
|
|
4375
4412
|
console.log(
|
|
4376
|
-
|
|
4413
|
+
chalk3.yellow(
|
|
4377
4414
|
`\u26A0 Agent "${name}": 'image' field is deprecated. Use 'apps' field for pre-installed tools.`
|
|
4378
4415
|
)
|
|
4379
4416
|
);
|
|
4380
4417
|
const warning = getLegacySystemTemplateWarning(image);
|
|
4381
4418
|
if (warning) {
|
|
4382
|
-
console.log(
|
|
4419
|
+
console.log(chalk3.yellow(` ${warning}`));
|
|
4383
4420
|
}
|
|
4384
4421
|
}
|
|
4385
4422
|
}
|
|
@@ -4398,7 +4435,7 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4398
4435
|
framework
|
|
4399
4436
|
);
|
|
4400
4437
|
console.log(
|
|
4401
|
-
|
|
4438
|
+
chalk3.green(
|
|
4402
4439
|
`\u2713 Instructions ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
4403
4440
|
)
|
|
4404
4441
|
);
|
|
@@ -4408,11 +4445,11 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4408
4445
|
const skillUrls = agent.skills;
|
|
4409
4446
|
console.log(`Uploading ${skillUrls.length} skill(s)...`);
|
|
4410
4447
|
for (const skillUrl of skillUrls) {
|
|
4411
|
-
console.log(
|
|
4448
|
+
console.log(chalk3.dim(` Downloading: ${skillUrl}`));
|
|
4412
4449
|
const result = await uploadSkill(skillUrl);
|
|
4413
4450
|
skillResults.push(result);
|
|
4414
4451
|
console.log(
|
|
4415
|
-
|
|
4452
|
+
chalk3.green(
|
|
4416
4453
|
` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.skillName} (${result.versionId.slice(0, 8)})`
|
|
4417
4454
|
)
|
|
4418
4455
|
);
|
|
@@ -4455,21 +4492,21 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4455
4492
|
if (newSecrets.length > 0 || newVars.length > 0) {
|
|
4456
4493
|
console.log();
|
|
4457
4494
|
console.log(
|
|
4458
|
-
|
|
4495
|
+
chalk3.bold("Skills require the following environment variables:")
|
|
4459
4496
|
);
|
|
4460
4497
|
console.log();
|
|
4461
4498
|
if (newSecrets.length > 0) {
|
|
4462
|
-
console.log(
|
|
4499
|
+
console.log(chalk3.cyan(" Secrets:"));
|
|
4463
4500
|
for (const [name, skills] of newSecrets) {
|
|
4464
4501
|
const isNew = trulyNewSecrets.includes(name);
|
|
4465
|
-
const newMarker = isNew ?
|
|
4502
|
+
const newMarker = isNew ? chalk3.yellow(" (new)") : "";
|
|
4466
4503
|
console.log(
|
|
4467
4504
|
` ${name.padEnd(24)}${newMarker} <- ${skills.join(", ")}`
|
|
4468
4505
|
);
|
|
4469
4506
|
}
|
|
4470
4507
|
}
|
|
4471
4508
|
if (newVars.length > 0) {
|
|
4472
|
-
console.log(
|
|
4509
|
+
console.log(chalk3.cyan(" Vars:"));
|
|
4473
4510
|
for (const [name, skills] of newVars) {
|
|
4474
4511
|
console.log(` ${name.padEnd(24)} <- ${skills.join(", ")}`);
|
|
4475
4512
|
}
|
|
@@ -4479,12 +4516,12 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4479
4516
|
if (!options.yes) {
|
|
4480
4517
|
if (!isInteractive()) {
|
|
4481
4518
|
console.error(
|
|
4482
|
-
|
|
4519
|
+
chalk3.red(
|
|
4483
4520
|
`\u2717 New secrets detected: ${trulyNewSecrets.join(", ")}`
|
|
4484
4521
|
)
|
|
4485
4522
|
);
|
|
4486
4523
|
console.error(
|
|
4487
|
-
|
|
4524
|
+
chalk3.dim(
|
|
4488
4525
|
" Use --yes flag to approve new secrets in non-interactive mode."
|
|
4489
4526
|
)
|
|
4490
4527
|
);
|
|
@@ -4495,7 +4532,7 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4495
4532
|
true
|
|
4496
4533
|
);
|
|
4497
4534
|
if (!confirmed) {
|
|
4498
|
-
console.log(
|
|
4535
|
+
console.log(chalk3.yellow("Compose cancelled"));
|
|
4499
4536
|
process.exit(0);
|
|
4500
4537
|
}
|
|
4501
4538
|
}
|
|
@@ -4518,54 +4555,54 @@ var composeCommand = new Command2().name("compose").description("Create or updat
|
|
|
4518
4555
|
const shortVersionId = response.versionId.slice(0, 8);
|
|
4519
4556
|
const displayName = `${scopeResponse.slug}/${response.name}`;
|
|
4520
4557
|
if (response.action === "created") {
|
|
4521
|
-
console.log(
|
|
4558
|
+
console.log(chalk3.green(`\u2713 Compose created: ${displayName}`));
|
|
4522
4559
|
} else {
|
|
4523
|
-
console.log(
|
|
4560
|
+
console.log(chalk3.green(`\u2713 Compose version exists: ${displayName}`));
|
|
4524
4561
|
}
|
|
4525
|
-
console.log(
|
|
4562
|
+
console.log(chalk3.dim(` Version: ${shortVersionId}`));
|
|
4526
4563
|
console.log();
|
|
4527
4564
|
console.log(" Run your agent:");
|
|
4528
4565
|
console.log(
|
|
4529
|
-
|
|
4566
|
+
chalk3.cyan(
|
|
4530
4567
|
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
4531
4568
|
)
|
|
4532
4569
|
);
|
|
4533
4570
|
} catch (error) {
|
|
4534
4571
|
if (error instanceof Error) {
|
|
4535
4572
|
if (error.message.includes("Not authenticated")) {
|
|
4536
|
-
console.error(
|
|
4573
|
+
console.error(chalk3.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
4537
4574
|
} else if (error.message.includes("Failed to create compose")) {
|
|
4538
|
-
console.error(
|
|
4539
|
-
console.error(
|
|
4575
|
+
console.error(chalk3.red("\u2717 Failed to create compose"));
|
|
4576
|
+
console.error(chalk3.dim(` ${error.message}`));
|
|
4540
4577
|
} else {
|
|
4541
|
-
console.error(
|
|
4542
|
-
console.error(
|
|
4578
|
+
console.error(chalk3.red("\u2717 Failed to create compose"));
|
|
4579
|
+
console.error(chalk3.dim(` ${error.message}`));
|
|
4543
4580
|
}
|
|
4544
4581
|
} else {
|
|
4545
|
-
console.error(
|
|
4582
|
+
console.error(chalk3.red("\u2717 An unexpected error occurred"));
|
|
4546
4583
|
}
|
|
4547
4584
|
process.exit(1);
|
|
4548
4585
|
}
|
|
4549
4586
|
});
|
|
4550
4587
|
|
|
4551
4588
|
// src/commands/run/run.ts
|
|
4552
|
-
import { Command as
|
|
4553
|
-
import
|
|
4589
|
+
import { Command as Command8, Option } from "commander";
|
|
4590
|
+
import chalk7 from "chalk";
|
|
4554
4591
|
|
|
4555
4592
|
// src/lib/events/event-renderer.ts
|
|
4556
|
-
import
|
|
4593
|
+
import chalk4 from "chalk";
|
|
4557
4594
|
var EventRenderer = class {
|
|
4558
4595
|
/**
|
|
4559
4596
|
* Render run started info
|
|
4560
4597
|
* Called immediately after run is created, before polling events
|
|
4561
4598
|
*/
|
|
4562
4599
|
static renderRunStarted(info) {
|
|
4563
|
-
console.log(
|
|
4564
|
-
console.log(` Run ID: ${
|
|
4600
|
+
console.log(chalk4.bold("\u25B6 Run started"));
|
|
4601
|
+
console.log(` Run ID: ${chalk4.dim(info.runId)}`);
|
|
4565
4602
|
if (info.sandboxId) {
|
|
4566
|
-
console.log(` Sandbox: ${
|
|
4603
|
+
console.log(` Sandbox: ${chalk4.dim(info.sandboxId)}`);
|
|
4567
4604
|
}
|
|
4568
|
-
console.log(
|
|
4605
|
+
console.log(chalk4.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
|
|
4569
4606
|
console.log();
|
|
4570
4607
|
}
|
|
4571
4608
|
/**
|
|
@@ -4603,21 +4640,21 @@ var EventRenderer = class {
|
|
|
4603
4640
|
*/
|
|
4604
4641
|
static renderRunCompleted(result) {
|
|
4605
4642
|
console.log("");
|
|
4606
|
-
console.log(
|
|
4643
|
+
console.log(chalk4.green("\u2713 Run completed successfully"));
|
|
4607
4644
|
if (result) {
|
|
4608
|
-
console.log(` Checkpoint: ${
|
|
4609
|
-
console.log(` Session: ${
|
|
4610
|
-
console.log(` Conversation: ${
|
|
4645
|
+
console.log(` Checkpoint: ${chalk4.dim(result.checkpointId)}`);
|
|
4646
|
+
console.log(` Session: ${chalk4.dim(result.agentSessionId)}`);
|
|
4647
|
+
console.log(` Conversation: ${chalk4.dim(result.conversationId)}`);
|
|
4611
4648
|
if (result.artifact && Object.keys(result.artifact).length > 0) {
|
|
4612
4649
|
console.log(` Artifact:`);
|
|
4613
4650
|
for (const [name, version] of Object.entries(result.artifact)) {
|
|
4614
|
-
console.log(` ${name}: ${
|
|
4651
|
+
console.log(` ${name}: ${chalk4.dim(this.formatVersion(version))}`);
|
|
4615
4652
|
}
|
|
4616
4653
|
}
|
|
4617
4654
|
if (result.volumes && Object.keys(result.volumes).length > 0) {
|
|
4618
4655
|
console.log(` Volumes:`);
|
|
4619
4656
|
for (const [name, version] of Object.entries(result.volumes)) {
|
|
4620
|
-
console.log(` ${name}: ${
|
|
4657
|
+
console.log(` ${name}: ${chalk4.dim(this.formatVersion(version))}`);
|
|
4621
4658
|
}
|
|
4622
4659
|
}
|
|
4623
4660
|
}
|
|
@@ -4628,22 +4665,22 @@ var EventRenderer = class {
|
|
|
4628
4665
|
*/
|
|
4629
4666
|
static renderRunFailed(error, runId) {
|
|
4630
4667
|
console.log("");
|
|
4631
|
-
console.log(
|
|
4632
|
-
console.log(` Error: ${
|
|
4668
|
+
console.log(chalk4.red("\u2717 Run failed"));
|
|
4669
|
+
console.log(` Error: ${chalk4.red(error || "Unknown error")}`);
|
|
4633
4670
|
console.log(
|
|
4634
|
-
|
|
4671
|
+
chalk4.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
4635
4672
|
);
|
|
4636
4673
|
}
|
|
4637
4674
|
static renderInit(event, prefix) {
|
|
4638
4675
|
const frameworkStr = String(event.data.framework || "claude-code");
|
|
4639
4676
|
const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
|
|
4640
4677
|
console.log(prefix + `[init] Starting ${displayName} agent`);
|
|
4641
|
-
console.log(` Session: ${
|
|
4678
|
+
console.log(` Session: ${chalk4.dim(String(event.data.sessionId || ""))}`);
|
|
4642
4679
|
if (event.data.model) {
|
|
4643
|
-
console.log(` Model: ${
|
|
4680
|
+
console.log(` Model: ${chalk4.dim(String(event.data.model))}`);
|
|
4644
4681
|
}
|
|
4645
4682
|
console.log(
|
|
4646
|
-
` Tools: ${
|
|
4683
|
+
` Tools: ${chalk4.dim(
|
|
4647
4684
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
4648
4685
|
)}`
|
|
4649
4686
|
);
|
|
@@ -4660,7 +4697,7 @@ var EventRenderer = class {
|
|
|
4660
4697
|
for (const [key, value] of Object.entries(input)) {
|
|
4661
4698
|
if (value !== void 0 && value !== null) {
|
|
4662
4699
|
const displayValue = typeof value === "object" ? JSON.stringify(value, null, 2) : String(value);
|
|
4663
|
-
console.log(` ${key}: ${
|
|
4700
|
+
console.log(` ${key}: ${chalk4.dim(displayValue)}`);
|
|
4664
4701
|
}
|
|
4665
4702
|
}
|
|
4666
4703
|
}
|
|
@@ -4670,7 +4707,7 @@ var EventRenderer = class {
|
|
|
4670
4707
|
const status = isError ? "Error" : "Completed";
|
|
4671
4708
|
console.log(prefix + "[tool_result] " + status);
|
|
4672
4709
|
const result = String(event.data.result || "");
|
|
4673
|
-
console.log(` ${
|
|
4710
|
+
console.log(` ${chalk4.dim(result)}`);
|
|
4674
4711
|
}
|
|
4675
4712
|
static renderResult(event, prefix) {
|
|
4676
4713
|
const success = Boolean(event.data.success);
|
|
@@ -4678,11 +4715,11 @@ var EventRenderer = class {
|
|
|
4678
4715
|
console.log(prefix + "[result] " + status);
|
|
4679
4716
|
const durationMs = Number(event.data.durationMs || 0);
|
|
4680
4717
|
const durationSec = (durationMs / 1e3).toFixed(1);
|
|
4681
|
-
console.log(` Duration: ${
|
|
4718
|
+
console.log(` Duration: ${chalk4.dim(durationSec + "s")}`);
|
|
4682
4719
|
const cost = Number(event.data.cost || 0);
|
|
4683
|
-
console.log(` Cost: ${
|
|
4720
|
+
console.log(` Cost: ${chalk4.dim("$" + cost.toFixed(4))}`);
|
|
4684
4721
|
const numTurns = Number(event.data.numTurns || 0);
|
|
4685
|
-
console.log(` Turns: ${
|
|
4722
|
+
console.log(` Turns: ${chalk4.dim(String(numTurns))}`);
|
|
4686
4723
|
const usage = event.data.usage;
|
|
4687
4724
|
if (usage && typeof usage === "object") {
|
|
4688
4725
|
const inputTokens = Number(usage.input_tokens || 0);
|
|
@@ -4694,7 +4731,7 @@ var EventRenderer = class {
|
|
|
4694
4731
|
return String(count);
|
|
4695
4732
|
};
|
|
4696
4733
|
console.log(
|
|
4697
|
-
` Tokens: ${
|
|
4734
|
+
` Tokens: ${chalk4.dim(
|
|
4698
4735
|
`input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
|
|
4699
4736
|
)}`
|
|
4700
4737
|
);
|
|
@@ -4712,7 +4749,7 @@ var EventRenderer = class {
|
|
|
4712
4749
|
};
|
|
4713
4750
|
|
|
4714
4751
|
// src/commands/run/shared.ts
|
|
4715
|
-
import
|
|
4752
|
+
import chalk6 from "chalk";
|
|
4716
4753
|
import * as fs5 from "fs";
|
|
4717
4754
|
import { config as dotenvConfig } from "dotenv";
|
|
4718
4755
|
|
|
@@ -5038,7 +5075,7 @@ function parseEvent(rawEvent, framework) {
|
|
|
5038
5075
|
}
|
|
5039
5076
|
|
|
5040
5077
|
// src/lib/events/codex-event-renderer.ts
|
|
5041
|
-
import
|
|
5078
|
+
import chalk5 from "chalk";
|
|
5042
5079
|
var CodexEventRenderer = class {
|
|
5043
5080
|
/**
|
|
5044
5081
|
* Check if an event is a Codex event
|
|
@@ -5085,13 +5122,13 @@ var CodexEventRenderer = class {
|
|
|
5085
5122
|
const cached = event.usage.cached_input_tokens || 0;
|
|
5086
5123
|
const cachedStr = cached ? ` (${cached} cached)` : "";
|
|
5087
5124
|
console.log(
|
|
5088
|
-
"[turn.completed]" +
|
|
5125
|
+
"[turn.completed]" + chalk5.dim(` ${input} in / ${output} out${cachedStr}`)
|
|
5089
5126
|
);
|
|
5090
5127
|
}
|
|
5091
5128
|
}
|
|
5092
5129
|
static renderTurnFailed(event) {
|
|
5093
5130
|
console.log(
|
|
5094
|
-
|
|
5131
|
+
chalk5.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
|
|
5095
5132
|
);
|
|
5096
5133
|
}
|
|
5097
5134
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
@@ -5117,15 +5154,15 @@ var CodexEventRenderer = class {
|
|
|
5117
5154
|
if (output) {
|
|
5118
5155
|
const lines = output.split("\n").filter((l) => l.trim());
|
|
5119
5156
|
const preview = lines.slice(0, 3).join("\n ");
|
|
5120
|
-
const more = lines.length > 3 ?
|
|
5157
|
+
const more = lines.length > 3 ? chalk5.dim(` ... (${lines.length - 3} more lines)`) : "";
|
|
5121
5158
|
console.log(
|
|
5122
|
-
"[output]" + (exitCode !== 0 ?
|
|
5159
|
+
"[output]" + (exitCode !== 0 ? chalk5.red(` exit=${exitCode}`) : "")
|
|
5123
5160
|
);
|
|
5124
5161
|
if (preview) {
|
|
5125
5162
|
console.log(" " + preview + more);
|
|
5126
5163
|
}
|
|
5127
5164
|
} else if (exitCode !== 0) {
|
|
5128
|
-
console.log(
|
|
5165
|
+
console.log(chalk5.red("[output]") + chalk5.red(` exit=${exitCode}`));
|
|
5129
5166
|
}
|
|
5130
5167
|
}
|
|
5131
5168
|
return;
|
|
@@ -5135,7 +5172,7 @@ var CodexEventRenderer = class {
|
|
|
5135
5172
|
const icon = c20.kind === "add" ? "+" : c20.kind === "delete" ? "-" : "~";
|
|
5136
5173
|
return `${icon}${c20.path}`;
|
|
5137
5174
|
}).join(", ");
|
|
5138
|
-
console.log(
|
|
5175
|
+
console.log(chalk5.green("[files]") + ` ${summary}`);
|
|
5139
5176
|
return;
|
|
5140
5177
|
}
|
|
5141
5178
|
if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
|
|
@@ -5148,7 +5185,7 @@ var CodexEventRenderer = class {
|
|
|
5148
5185
|
}
|
|
5149
5186
|
static renderError(event) {
|
|
5150
5187
|
console.log(
|
|
5151
|
-
|
|
5188
|
+
chalk5.red("[error]") + ` ${event.message || event.error || "Unknown error"}`
|
|
5152
5189
|
);
|
|
5153
5190
|
}
|
|
5154
5191
|
};
|
|
@@ -5947,7 +5984,7 @@ var ApiClient = class {
|
|
|
5947
5984
|
/**
|
|
5948
5985
|
* Generic GET request
|
|
5949
5986
|
*/
|
|
5950
|
-
async get(
|
|
5987
|
+
async get(path17) {
|
|
5951
5988
|
const baseUrl = await this.getBaseUrl();
|
|
5952
5989
|
const token = await getToken();
|
|
5953
5990
|
if (!token) {
|
|
@@ -5960,7 +5997,7 @@ var ApiClient = class {
|
|
|
5960
5997
|
if (bypassSecret) {
|
|
5961
5998
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
5962
5999
|
}
|
|
5963
|
-
return fetch(`${baseUrl}${
|
|
6000
|
+
return fetch(`${baseUrl}${path17}`, {
|
|
5964
6001
|
method: "GET",
|
|
5965
6002
|
headers
|
|
5966
6003
|
});
|
|
@@ -5968,7 +6005,7 @@ var ApiClient = class {
|
|
|
5968
6005
|
/**
|
|
5969
6006
|
* Generic POST request
|
|
5970
6007
|
*/
|
|
5971
|
-
async post(
|
|
6008
|
+
async post(path17, options) {
|
|
5972
6009
|
const baseUrl = await this.getBaseUrl();
|
|
5973
6010
|
const token = await getToken();
|
|
5974
6011
|
if (!token) {
|
|
@@ -5984,7 +6021,7 @@ var ApiClient = class {
|
|
|
5984
6021
|
if (bypassSecret) {
|
|
5985
6022
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
5986
6023
|
}
|
|
5987
|
-
return fetch(`${baseUrl}${
|
|
6024
|
+
return fetch(`${baseUrl}${path17}`, {
|
|
5988
6025
|
method: "POST",
|
|
5989
6026
|
headers,
|
|
5990
6027
|
body: options?.body
|
|
@@ -5993,7 +6030,7 @@ var ApiClient = class {
|
|
|
5993
6030
|
/**
|
|
5994
6031
|
* Generic DELETE request
|
|
5995
6032
|
*/
|
|
5996
|
-
async delete(
|
|
6033
|
+
async delete(path17) {
|
|
5997
6034
|
const baseUrl = await this.getBaseUrl();
|
|
5998
6035
|
const token = await getToken();
|
|
5999
6036
|
if (!token) {
|
|
@@ -6006,7 +6043,7 @@ var ApiClient = class {
|
|
|
6006
6043
|
if (bypassSecret) {
|
|
6007
6044
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
6008
6045
|
}
|
|
6009
|
-
return fetch(`${baseUrl}${
|
|
6046
|
+
return fetch(`${baseUrl}${path17}`, {
|
|
6010
6047
|
method: "DELETE",
|
|
6011
6048
|
headers
|
|
6012
6049
|
});
|
|
@@ -6207,9 +6244,9 @@ async function streamRealtimeEvents(runId) {
|
|
|
6207
6244
|
EventRenderer.renderRunFailed(error, rid);
|
|
6208
6245
|
},
|
|
6209
6246
|
onTimeout: (rid) => {
|
|
6210
|
-
console.error(
|
|
6247
|
+
console.error(chalk6.red("\n\u2717 Run timed out"));
|
|
6211
6248
|
console.error(
|
|
6212
|
-
|
|
6249
|
+
chalk6.dim(` (use "vm0 logs ${rid} --system" to view system logs)`)
|
|
6213
6250
|
);
|
|
6214
6251
|
}
|
|
6215
6252
|
});
|
|
@@ -6251,9 +6288,9 @@ async function pollEvents(runId) {
|
|
|
6251
6288
|
result = { succeeded: false, runId };
|
|
6252
6289
|
} else if (runStatus === "timeout") {
|
|
6253
6290
|
complete = true;
|
|
6254
|
-
console.error(
|
|
6291
|
+
console.error(chalk6.red("\n\u2717 Run timed out"));
|
|
6255
6292
|
console.error(
|
|
6256
|
-
|
|
6293
|
+
chalk6.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
6257
6294
|
);
|
|
6258
6295
|
result = { succeeded: false, runId };
|
|
6259
6296
|
}
|
|
@@ -6267,11 +6304,11 @@ function showNextSteps(result) {
|
|
|
6267
6304
|
const { runId, sessionId, checkpointId } = result;
|
|
6268
6305
|
console.log();
|
|
6269
6306
|
console.log(" View agent logs:");
|
|
6270
|
-
console.log(
|
|
6307
|
+
console.log(chalk6.cyan(` vm0 logs ${runId}`));
|
|
6271
6308
|
if (sessionId) {
|
|
6272
6309
|
console.log(" Continue with session (latest conversation and artifact):");
|
|
6273
6310
|
console.log(
|
|
6274
|
-
|
|
6311
|
+
chalk6.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
6275
6312
|
);
|
|
6276
6313
|
}
|
|
6277
6314
|
if (checkpointId) {
|
|
@@ -6279,27 +6316,27 @@ function showNextSteps(result) {
|
|
|
6279
6316
|
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
6280
6317
|
);
|
|
6281
6318
|
console.log(
|
|
6282
|
-
|
|
6319
|
+
chalk6.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
6283
6320
|
);
|
|
6284
6321
|
}
|
|
6285
6322
|
}
|
|
6286
6323
|
function handleGenericRunError(error, commandLabel) {
|
|
6287
6324
|
if (error instanceof ApiRequestError && error.code === "concurrent_run_limit_exceeded") {
|
|
6288
|
-
console.error(
|
|
6289
|
-
console.error(
|
|
6325
|
+
console.error(chalk6.red(`\u2717 ${commandLabel} failed`));
|
|
6326
|
+
console.error(chalk6.dim(` ${error.message}`));
|
|
6290
6327
|
console.log();
|
|
6291
6328
|
console.log(" To view active runs:");
|
|
6292
|
-
console.log(
|
|
6329
|
+
console.log(chalk6.cyan(" vm0 run list"));
|
|
6293
6330
|
console.log(" To cancel a run:");
|
|
6294
|
-
console.log(
|
|
6331
|
+
console.log(chalk6.cyan(" vm0 run kill <run-id>"));
|
|
6295
6332
|
} else {
|
|
6296
|
-
console.error(
|
|
6297
|
-
console.error(
|
|
6333
|
+
console.error(chalk6.red(`\u2717 ${commandLabel} failed`));
|
|
6334
|
+
console.error(chalk6.dim(` ${error.message}`));
|
|
6298
6335
|
}
|
|
6299
6336
|
}
|
|
6300
6337
|
|
|
6301
6338
|
// src/commands/run/run.ts
|
|
6302
|
-
var mainRunCommand = new
|
|
6339
|
+
var mainRunCommand = new Command8().name("run").description("Run an agent").argument(
|
|
6303
6340
|
"<agent-name>",
|
|
6304
6341
|
"Agent reference: [scope/]name[:version] (e.g., 'my-agent', 'lancy/my-agent:abc123', 'my-agent:latest')"
|
|
6305
6342
|
).argument("<prompt>", "Prompt for the agent").option(
|
|
@@ -6345,9 +6382,9 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
|
|
|
6345
6382
|
} else {
|
|
6346
6383
|
const compose = await getComposeByName(name, scope);
|
|
6347
6384
|
if (!compose) {
|
|
6348
|
-
console.error(
|
|
6385
|
+
console.error(chalk7.red(`\u2717 Agent not found: ${identifier}`));
|
|
6349
6386
|
console.error(
|
|
6350
|
-
|
|
6387
|
+
chalk7.dim(
|
|
6351
6388
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6352
6389
|
)
|
|
6353
6390
|
);
|
|
@@ -6387,9 +6424,9 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
|
|
|
6387
6424
|
debugNoMockClaude: options.debugNoMockClaude || void 0
|
|
6388
6425
|
});
|
|
6389
6426
|
if (response.status === "failed") {
|
|
6390
|
-
console.error(
|
|
6427
|
+
console.error(chalk7.red("\u2717 Run preparation failed"));
|
|
6391
6428
|
if (response.error) {
|
|
6392
|
-
console.error(
|
|
6429
|
+
console.error(chalk7.dim(` ${response.error}`));
|
|
6393
6430
|
}
|
|
6394
6431
|
process.exit(1);
|
|
6395
6432
|
}
|
|
@@ -6406,23 +6443,23 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
|
|
|
6406
6443
|
if (error instanceof Error) {
|
|
6407
6444
|
if (error.message.includes("Not authenticated")) {
|
|
6408
6445
|
console.error(
|
|
6409
|
-
|
|
6446
|
+
chalk7.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
6410
6447
|
);
|
|
6411
6448
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6412
|
-
console.error(
|
|
6413
|
-
console.error(
|
|
6449
|
+
console.error(chalk7.red("\u2717 Realtime streaming failed"));
|
|
6450
|
+
console.error(chalk7.dim(` ${error.message}`));
|
|
6414
6451
|
console.error(
|
|
6415
|
-
|
|
6452
|
+
chalk7.dim(" Try running without --experimental-realtime")
|
|
6416
6453
|
);
|
|
6417
6454
|
} else if (error.message.startsWith("Version not found:")) {
|
|
6418
|
-
console.error(
|
|
6419
|
-
console.error(
|
|
6455
|
+
console.error(chalk7.red(`\u2717 ${error.message}`));
|
|
6456
|
+
console.error(chalk7.dim(" Make sure the version hash is correct"));
|
|
6420
6457
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6421
|
-
console.error(
|
|
6458
|
+
console.error(chalk7.red(`\u2717 ${error.message}`));
|
|
6422
6459
|
} else if (error.message.includes("not found")) {
|
|
6423
|
-
console.error(
|
|
6460
|
+
console.error(chalk7.red(`\u2717 Agent not found: ${identifier}`));
|
|
6424
6461
|
console.error(
|
|
6425
|
-
|
|
6462
|
+
chalk7.dim(
|
|
6426
6463
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6427
6464
|
)
|
|
6428
6465
|
);
|
|
@@ -6430,7 +6467,7 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
|
|
|
6430
6467
|
handleGenericRunError(error, "Run");
|
|
6431
6468
|
}
|
|
6432
6469
|
} else {
|
|
6433
|
-
console.error(
|
|
6470
|
+
console.error(chalk7.red("\u2717 An unexpected error occurred"));
|
|
6434
6471
|
}
|
|
6435
6472
|
process.exit(1);
|
|
6436
6473
|
}
|
|
@@ -6438,9 +6475,9 @@ var mainRunCommand = new Command3().name("run").description("Run an agent").argu
|
|
|
6438
6475
|
);
|
|
6439
6476
|
|
|
6440
6477
|
// src/commands/run/resume.ts
|
|
6441
|
-
import { Command as
|
|
6442
|
-
import
|
|
6443
|
-
var resumeCommand = new
|
|
6478
|
+
import { Command as Command9, Option as Option2 } from "commander";
|
|
6479
|
+
import chalk8 from "chalk";
|
|
6480
|
+
var resumeCommand = new Command9().name("resume").description("Resume an agent run from a checkpoint (uses all snapshot data)").argument("<checkpointId>", "Checkpoint ID to resume from").argument("<prompt>", "Prompt for the resumed agent").option(
|
|
6444
6481
|
"--env-file <path>",
|
|
6445
6482
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
6446
6483
|
).option(
|
|
@@ -6472,9 +6509,9 @@ var resumeCommand = new Command4().name("resume").description("Resume an agent r
|
|
|
6472
6509
|
try {
|
|
6473
6510
|
if (!isUUID(checkpointId)) {
|
|
6474
6511
|
console.error(
|
|
6475
|
-
|
|
6512
|
+
chalk8.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
6476
6513
|
);
|
|
6477
|
-
console.error(
|
|
6514
|
+
console.error(chalk8.dim(" Checkpoint ID must be a valid UUID"));
|
|
6478
6515
|
process.exit(1);
|
|
6479
6516
|
}
|
|
6480
6517
|
const checkpointInfo = await getCheckpoint(checkpointId);
|
|
@@ -6491,9 +6528,9 @@ var resumeCommand = new Command4().name("resume").description("Resume an agent r
|
|
|
6491
6528
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6492
6529
|
});
|
|
6493
6530
|
if (response.status === "failed") {
|
|
6494
|
-
console.error(
|
|
6531
|
+
console.error(chalk8.red("\u2717 Run preparation failed"));
|
|
6495
6532
|
if (response.error) {
|
|
6496
|
-
console.error(
|
|
6533
|
+
console.error(chalk8.dim(` ${response.error}`));
|
|
6497
6534
|
}
|
|
6498
6535
|
process.exit(1);
|
|
6499
6536
|
}
|
|
@@ -6511,23 +6548,23 @@ var resumeCommand = new Command4().name("resume").description("Resume an agent r
|
|
|
6511
6548
|
if (error instanceof Error) {
|
|
6512
6549
|
if (error.message.includes("Not authenticated")) {
|
|
6513
6550
|
console.error(
|
|
6514
|
-
|
|
6551
|
+
chalk8.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
6515
6552
|
);
|
|
6516
6553
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6517
|
-
console.error(
|
|
6518
|
-
console.error(
|
|
6554
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6555
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6519
6556
|
console.error(
|
|
6520
|
-
|
|
6557
|
+
chalk8.dim(" Try running without --experimental-realtime")
|
|
6521
6558
|
);
|
|
6522
6559
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6523
|
-
console.error(
|
|
6560
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6524
6561
|
} else if (error.message.includes("not found")) {
|
|
6525
|
-
console.error(
|
|
6562
|
+
console.error(chalk8.red(`\u2717 Checkpoint not found: ${checkpointId}`));
|
|
6526
6563
|
} else {
|
|
6527
6564
|
handleGenericRunError(error, "Resume");
|
|
6528
6565
|
}
|
|
6529
6566
|
} else {
|
|
6530
|
-
console.error(
|
|
6567
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6531
6568
|
}
|
|
6532
6569
|
process.exit(1);
|
|
6533
6570
|
}
|
|
@@ -6535,9 +6572,9 @@ var resumeCommand = new Command4().name("resume").description("Resume an agent r
|
|
|
6535
6572
|
);
|
|
6536
6573
|
|
|
6537
6574
|
// src/commands/run/continue.ts
|
|
6538
|
-
import { Command as
|
|
6539
|
-
import
|
|
6540
|
-
var continueCommand = new
|
|
6575
|
+
import { Command as Command10, Option as Option3 } from "commander";
|
|
6576
|
+
import chalk9 from "chalk";
|
|
6577
|
+
var continueCommand = new Command10().name("continue").description(
|
|
6541
6578
|
"Continue an agent run from a session (uses latest artifact version)"
|
|
6542
6579
|
).argument("<agentSessionId>", "Agent session ID to continue from").argument("<prompt>", "Prompt for the continued agent").option(
|
|
6543
6580
|
"--env-file <path>",
|
|
@@ -6571,9 +6608,9 @@ var continueCommand = new Command5().name("continue").description(
|
|
|
6571
6608
|
try {
|
|
6572
6609
|
if (!isUUID(agentSessionId)) {
|
|
6573
6610
|
console.error(
|
|
6574
|
-
|
|
6611
|
+
chalk9.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
6575
6612
|
);
|
|
6576
|
-
console.error(
|
|
6613
|
+
console.error(chalk9.dim(" Agent session ID must be a valid UUID"));
|
|
6577
6614
|
process.exit(1);
|
|
6578
6615
|
}
|
|
6579
6616
|
const sessionInfo = await getSession(agentSessionId);
|
|
@@ -6590,9 +6627,9 @@ var continueCommand = new Command5().name("continue").description(
|
|
|
6590
6627
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6591
6628
|
});
|
|
6592
6629
|
if (response.status === "failed") {
|
|
6593
|
-
console.error(
|
|
6630
|
+
console.error(chalk9.red("\u2717 Run preparation failed"));
|
|
6594
6631
|
if (response.error) {
|
|
6595
|
-
console.error(
|
|
6632
|
+
console.error(chalk9.dim(` ${response.error}`));
|
|
6596
6633
|
}
|
|
6597
6634
|
process.exit(1);
|
|
6598
6635
|
}
|
|
@@ -6610,25 +6647,25 @@ var continueCommand = new Command5().name("continue").description(
|
|
|
6610
6647
|
if (error instanceof Error) {
|
|
6611
6648
|
if (error.message.includes("Not authenticated")) {
|
|
6612
6649
|
console.error(
|
|
6613
|
-
|
|
6650
|
+
chalk9.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
6614
6651
|
);
|
|
6615
6652
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6616
|
-
console.error(
|
|
6617
|
-
console.error(
|
|
6653
|
+
console.error(chalk9.red("\u2717 Realtime streaming failed"));
|
|
6654
|
+
console.error(chalk9.dim(` ${error.message}`));
|
|
6618
6655
|
console.error(
|
|
6619
|
-
|
|
6656
|
+
chalk9.dim(" Try running without --experimental-realtime")
|
|
6620
6657
|
);
|
|
6621
6658
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6622
|
-
console.error(
|
|
6659
|
+
console.error(chalk9.red(`\u2717 ${error.message}`));
|
|
6623
6660
|
} else if (error.message.includes("not found")) {
|
|
6624
6661
|
console.error(
|
|
6625
|
-
|
|
6662
|
+
chalk9.red(`\u2717 Agent session not found: ${agentSessionId}`)
|
|
6626
6663
|
);
|
|
6627
6664
|
} else {
|
|
6628
6665
|
handleGenericRunError(error, "Continue");
|
|
6629
6666
|
}
|
|
6630
6667
|
} else {
|
|
6631
|
-
console.error(
|
|
6668
|
+
console.error(chalk9.red("\u2717 An unexpected error occurred"));
|
|
6632
6669
|
}
|
|
6633
6670
|
process.exit(1);
|
|
6634
6671
|
}
|
|
@@ -6636,31 +6673,31 @@ var continueCommand = new Command5().name("continue").description(
|
|
|
6636
6673
|
);
|
|
6637
6674
|
|
|
6638
6675
|
// src/commands/run/list.ts
|
|
6639
|
-
import { Command as
|
|
6640
|
-
import
|
|
6676
|
+
import { Command as Command11 } from "commander";
|
|
6677
|
+
import chalk10 from "chalk";
|
|
6641
6678
|
var UUID_LENGTH = 36;
|
|
6642
6679
|
function formatRunStatus(status, width) {
|
|
6643
6680
|
const paddedStatus = width ? status.padEnd(width) : status;
|
|
6644
6681
|
switch (status) {
|
|
6645
6682
|
case "running":
|
|
6646
|
-
return
|
|
6683
|
+
return chalk10.green(paddedStatus);
|
|
6647
6684
|
case "pending":
|
|
6648
|
-
return
|
|
6685
|
+
return chalk10.yellow(paddedStatus);
|
|
6649
6686
|
case "completed":
|
|
6650
|
-
return
|
|
6687
|
+
return chalk10.blue(paddedStatus);
|
|
6651
6688
|
case "failed":
|
|
6652
6689
|
case "timeout":
|
|
6653
|
-
return
|
|
6690
|
+
return chalk10.red(paddedStatus);
|
|
6654
6691
|
default:
|
|
6655
6692
|
return paddedStatus;
|
|
6656
6693
|
}
|
|
6657
6694
|
}
|
|
6658
|
-
var listCommand = new
|
|
6695
|
+
var listCommand = new Command11().name("list").alias("ls").description("List active runs (pending and running)").action(async () => {
|
|
6659
6696
|
try {
|
|
6660
6697
|
const response = await listRuns({ limit: 100 });
|
|
6661
6698
|
const activeRuns = response.runs;
|
|
6662
6699
|
if (activeRuns.length === 0) {
|
|
6663
|
-
console.log(
|
|
6700
|
+
console.log(chalk10.dim("No active runs"));
|
|
6664
6701
|
return;
|
|
6665
6702
|
}
|
|
6666
6703
|
const agentWidth = Math.max(
|
|
@@ -6674,7 +6711,7 @@ var listCommand = new Command6().name("list").alias("ls").description("List acti
|
|
|
6674
6711
|
"STATUS".padEnd(statusWidth),
|
|
6675
6712
|
"CREATED"
|
|
6676
6713
|
].join(" ");
|
|
6677
|
-
console.log(
|
|
6714
|
+
console.log(chalk10.dim(header));
|
|
6678
6715
|
for (const run of activeRuns) {
|
|
6679
6716
|
const row = [
|
|
6680
6717
|
run.id.padEnd(UUID_LENGTH),
|
|
@@ -6685,12 +6722,12 @@ var listCommand = new Command6().name("list").alias("ls").description("List acti
|
|
|
6685
6722
|
console.log(row);
|
|
6686
6723
|
}
|
|
6687
6724
|
} catch (error) {
|
|
6688
|
-
console.error(
|
|
6725
|
+
console.error(chalk10.red("\u2717 Failed to list runs"));
|
|
6689
6726
|
if (error instanceof Error) {
|
|
6690
6727
|
if (error.message.includes("Not authenticated")) {
|
|
6691
|
-
console.error(
|
|
6728
|
+
console.error(chalk10.dim(" Run: vm0 auth login"));
|
|
6692
6729
|
} else {
|
|
6693
|
-
console.error(
|
|
6730
|
+
console.error(chalk10.dim(` ${error.message}`));
|
|
6694
6731
|
}
|
|
6695
6732
|
}
|
|
6696
6733
|
process.exit(1);
|
|
@@ -6698,23 +6735,23 @@ var listCommand = new Command6().name("list").alias("ls").description("List acti
|
|
|
6698
6735
|
});
|
|
6699
6736
|
|
|
6700
6737
|
// src/commands/run/kill.ts
|
|
6701
|
-
import { Command as
|
|
6702
|
-
import
|
|
6703
|
-
var killCommand = new
|
|
6738
|
+
import { Command as Command12 } from "commander";
|
|
6739
|
+
import chalk11 from "chalk";
|
|
6740
|
+
var killCommand = new Command12().name("kill").description("Kill (cancel) a pending or running run").argument("<run-id>", "Run ID to kill").action(async (runId) => {
|
|
6704
6741
|
try {
|
|
6705
6742
|
await cancelRun(runId);
|
|
6706
|
-
console.log(
|
|
6743
|
+
console.log(chalk11.green(`\u2713 Run ${runId} cancelled`));
|
|
6707
6744
|
} catch (error) {
|
|
6708
|
-
console.error(
|
|
6745
|
+
console.error(chalk11.red("\u2717 Failed to kill run"));
|
|
6709
6746
|
if (error instanceof Error) {
|
|
6710
6747
|
if (error.message.includes("Not authenticated")) {
|
|
6711
|
-
console.error(
|
|
6748
|
+
console.error(chalk11.dim(" Run: vm0 auth login"));
|
|
6712
6749
|
} else if (error.message.includes("not found") || error.message.includes("No such run")) {
|
|
6713
|
-
console.error(
|
|
6750
|
+
console.error(chalk11.dim(` Run not found: ${runId}`));
|
|
6714
6751
|
} else if (error.message.includes("cannot be cancelled")) {
|
|
6715
|
-
console.error(
|
|
6752
|
+
console.error(chalk11.dim(` ${error.message}`));
|
|
6716
6753
|
} else {
|
|
6717
|
-
console.error(
|
|
6754
|
+
console.error(chalk11.dim(` ${error.message}`));
|
|
6718
6755
|
}
|
|
6719
6756
|
}
|
|
6720
6757
|
process.exit(1);
|
|
@@ -6729,11 +6766,11 @@ mainRunCommand.addCommand(killCommand);
|
|
|
6729
6766
|
var runCommand = mainRunCommand;
|
|
6730
6767
|
|
|
6731
6768
|
// src/commands/volume/index.ts
|
|
6732
|
-
import { Command as
|
|
6769
|
+
import { Command as Command19 } from "commander";
|
|
6733
6770
|
|
|
6734
6771
|
// src/commands/volume/init.ts
|
|
6735
|
-
import { Command as
|
|
6736
|
-
import
|
|
6772
|
+
import { Command as Command13 } from "commander";
|
|
6773
|
+
import chalk12 from "chalk";
|
|
6737
6774
|
import path6 from "path";
|
|
6738
6775
|
|
|
6739
6776
|
// src/lib/storage/storage-utils.ts
|
|
@@ -6784,17 +6821,17 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type =
|
|
|
6784
6821
|
}
|
|
6785
6822
|
|
|
6786
6823
|
// src/commands/volume/init.ts
|
|
6787
|
-
var initCommand = new
|
|
6824
|
+
var initCommand = new Command13().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(async (options) => {
|
|
6788
6825
|
try {
|
|
6789
6826
|
const cwd = process.cwd();
|
|
6790
6827
|
const dirName = path6.basename(cwd);
|
|
6791
6828
|
const existingConfig = await readStorageConfig(cwd);
|
|
6792
6829
|
if (existingConfig) {
|
|
6793
6830
|
console.log(
|
|
6794
|
-
|
|
6831
|
+
chalk12.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
6795
6832
|
);
|
|
6796
6833
|
console.log(
|
|
6797
|
-
|
|
6834
|
+
chalk12.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
6798
6835
|
);
|
|
6799
6836
|
return;
|
|
6800
6837
|
}
|
|
@@ -6803,10 +6840,10 @@ var initCommand = new Command8().name("init").description("Initialize a volume i
|
|
|
6803
6840
|
volumeName = options.name;
|
|
6804
6841
|
} else if (!isInteractive()) {
|
|
6805
6842
|
console.error(
|
|
6806
|
-
|
|
6843
|
+
chalk12.red("\u2717 --name flag is required in non-interactive mode")
|
|
6807
6844
|
);
|
|
6808
6845
|
console.error(
|
|
6809
|
-
|
|
6846
|
+
chalk12.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
6810
6847
|
);
|
|
6811
6848
|
process.exit(1);
|
|
6812
6849
|
} else {
|
|
@@ -6822,43 +6859,43 @@ var initCommand = new Command8().name("init").description("Initialize a volume i
|
|
|
6822
6859
|
}
|
|
6823
6860
|
);
|
|
6824
6861
|
if (name === void 0) {
|
|
6825
|
-
console.log(
|
|
6862
|
+
console.log(chalk12.dim("Cancelled"));
|
|
6826
6863
|
return;
|
|
6827
6864
|
}
|
|
6828
6865
|
volumeName = name;
|
|
6829
6866
|
}
|
|
6830
6867
|
if (!isValidStorageName(volumeName)) {
|
|
6831
|
-
console.error(
|
|
6868
|
+
console.error(chalk12.red(`\u2717 Invalid volume name: "${volumeName}"`));
|
|
6832
6869
|
console.error(
|
|
6833
|
-
|
|
6870
|
+
chalk12.dim(
|
|
6834
6871
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
6835
6872
|
)
|
|
6836
6873
|
);
|
|
6837
6874
|
console.error(
|
|
6838
|
-
|
|
6875
|
+
chalk12.dim(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
6839
6876
|
);
|
|
6840
6877
|
process.exit(1);
|
|
6841
6878
|
}
|
|
6842
6879
|
await writeStorageConfig(volumeName, cwd);
|
|
6843
|
-
console.log(
|
|
6880
|
+
console.log(chalk12.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
6844
6881
|
console.log(
|
|
6845
|
-
|
|
6882
|
+
chalk12.dim(
|
|
6846
6883
|
` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
|
|
6847
6884
|
)
|
|
6848
6885
|
);
|
|
6849
6886
|
} catch (error) {
|
|
6850
|
-
console.error(
|
|
6887
|
+
console.error(chalk12.red("\u2717 Failed to initialize volume"));
|
|
6851
6888
|
if (error instanceof Error) {
|
|
6852
|
-
console.error(
|
|
6889
|
+
console.error(chalk12.dim(` ${error.message}`));
|
|
6853
6890
|
}
|
|
6854
6891
|
process.exit(1);
|
|
6855
6892
|
}
|
|
6856
6893
|
});
|
|
6857
6894
|
|
|
6858
6895
|
// src/commands/volume/push.ts
|
|
6859
|
-
import { Command as
|
|
6860
|
-
import
|
|
6861
|
-
var pushCommand = new
|
|
6896
|
+
import { Command as Command14 } from "commander";
|
|
6897
|
+
import chalk13 from "chalk";
|
|
6898
|
+
var pushCommand = new Command14().name("push").description("Push local files to cloud volume").option(
|
|
6862
6899
|
"-f, --force",
|
|
6863
6900
|
"Force upload even if content unchanged (recreate archive)"
|
|
6864
6901
|
).action(async (options) => {
|
|
@@ -6866,35 +6903,35 @@ var pushCommand = new Command9().name("push").description("Push local files to c
|
|
|
6866
6903
|
const cwd = process.cwd();
|
|
6867
6904
|
const config = await readStorageConfig(cwd);
|
|
6868
6905
|
if (!config) {
|
|
6869
|
-
console.error(
|
|
6870
|
-
console.error(
|
|
6906
|
+
console.error(chalk13.red("\u2717 No volume initialized in this directory"));
|
|
6907
|
+
console.error(chalk13.dim(" Run: vm0 volume init"));
|
|
6871
6908
|
process.exit(1);
|
|
6872
6909
|
}
|
|
6873
6910
|
console.log(`Pushing volume: ${config.name}`);
|
|
6874
6911
|
const result = await directUpload(config.name, "volume", cwd, {
|
|
6875
6912
|
onProgress: (message) => {
|
|
6876
|
-
console.log(
|
|
6913
|
+
console.log(chalk13.dim(message));
|
|
6877
6914
|
},
|
|
6878
6915
|
force: options.force
|
|
6879
6916
|
});
|
|
6880
6917
|
const shortVersion = result.versionId.slice(0, 8);
|
|
6881
6918
|
if (result.empty) {
|
|
6882
|
-
console.log(
|
|
6919
|
+
console.log(chalk13.dim("No files found (empty volume)"));
|
|
6883
6920
|
} else if (result.deduplicated) {
|
|
6884
|
-
console.log(
|
|
6921
|
+
console.log(chalk13.green("\u2713 Content unchanged (deduplicated)"));
|
|
6885
6922
|
} else {
|
|
6886
|
-
console.log(
|
|
6923
|
+
console.log(chalk13.green("\u2713 Upload complete"));
|
|
6887
6924
|
}
|
|
6888
|
-
console.log(
|
|
6889
|
-
console.log(
|
|
6890
|
-
console.log(
|
|
6925
|
+
console.log(chalk13.dim(` Version: ${shortVersion}`));
|
|
6926
|
+
console.log(chalk13.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
6927
|
+
console.log(chalk13.dim(` Size: ${formatBytes(result.size)}`));
|
|
6891
6928
|
} catch (error) {
|
|
6892
|
-
console.error(
|
|
6929
|
+
console.error(chalk13.red("\u2717 Push failed"));
|
|
6893
6930
|
if (error instanceof Error) {
|
|
6894
6931
|
if (error.message.includes("Not authenticated")) {
|
|
6895
|
-
console.error(
|
|
6932
|
+
console.error(chalk13.dim(" Run: vm0 auth login"));
|
|
6896
6933
|
} else {
|
|
6897
|
-
console.error(
|
|
6934
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
6898
6935
|
}
|
|
6899
6936
|
}
|
|
6900
6937
|
process.exit(1);
|
|
@@ -6902,33 +6939,33 @@ var pushCommand = new Command9().name("push").description("Push local files to c
|
|
|
6902
6939
|
});
|
|
6903
6940
|
|
|
6904
6941
|
// src/commands/volume/pull.ts
|
|
6905
|
-
import { Command as
|
|
6906
|
-
import
|
|
6942
|
+
import { Command as Command15 } from "commander";
|
|
6943
|
+
import chalk15 from "chalk";
|
|
6907
6944
|
import path7 from "path";
|
|
6908
6945
|
import * as fs6 from "fs";
|
|
6909
6946
|
import * as os4 from "os";
|
|
6910
6947
|
import * as tar3 from "tar";
|
|
6911
6948
|
|
|
6912
6949
|
// src/lib/storage/pull-utils.ts
|
|
6913
|
-
import
|
|
6950
|
+
import chalk14 from "chalk";
|
|
6914
6951
|
async function handleEmptyStorageResponse(cwd) {
|
|
6915
|
-
console.log(
|
|
6952
|
+
console.log(chalk14.dim("Syncing local files..."));
|
|
6916
6953
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
6917
6954
|
if (removedCount > 0) {
|
|
6918
|
-
console.log(
|
|
6955
|
+
console.log(chalk14.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
6919
6956
|
}
|
|
6920
|
-
console.log(
|
|
6957
|
+
console.log(chalk14.green("\u2713 Synced (0 files)"));
|
|
6921
6958
|
return { removedCount };
|
|
6922
6959
|
}
|
|
6923
6960
|
|
|
6924
6961
|
// src/commands/volume/pull.ts
|
|
6925
|
-
var pullCommand = new
|
|
6962
|
+
var pullCommand = new Command15().name("pull").description("Pull cloud files to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
|
|
6926
6963
|
try {
|
|
6927
6964
|
const cwd = process.cwd();
|
|
6928
6965
|
const config = await readStorageConfig(cwd);
|
|
6929
6966
|
if (!config) {
|
|
6930
|
-
console.error(
|
|
6931
|
-
console.error(
|
|
6967
|
+
console.error(chalk15.red("\u2717 No volume initialized in this directory"));
|
|
6968
|
+
console.error(chalk15.dim(" Run: vm0 volume init"));
|
|
6932
6969
|
process.exit(1);
|
|
6933
6970
|
}
|
|
6934
6971
|
if (versionId) {
|
|
@@ -6936,7 +6973,7 @@ var pullCommand = new Command10().name("pull").description("Pull cloud files to
|
|
|
6936
6973
|
} else {
|
|
6937
6974
|
console.log(`Pulling volume: ${config.name}`);
|
|
6938
6975
|
}
|
|
6939
|
-
console.log(
|
|
6976
|
+
console.log(chalk15.dim("Getting download URL..."));
|
|
6940
6977
|
const downloadInfo = await getStorageDownload({
|
|
6941
6978
|
name: config.name,
|
|
6942
6979
|
type: "volume",
|
|
@@ -6950,18 +6987,18 @@ var pullCommand = new Command10().name("pull").description("Pull cloud files to
|
|
|
6950
6987
|
if (!downloadUrl) {
|
|
6951
6988
|
throw new Error("No download URL returned");
|
|
6952
6989
|
}
|
|
6953
|
-
console.log(
|
|
6990
|
+
console.log(chalk15.dim("Downloading from S3..."));
|
|
6954
6991
|
const s3Response = await fetch(downloadUrl);
|
|
6955
6992
|
if (!s3Response.ok) {
|
|
6956
6993
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
6957
6994
|
}
|
|
6958
6995
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
6959
6996
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
6960
|
-
console.log(
|
|
6997
|
+
console.log(chalk15.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
6961
6998
|
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
|
|
6962
6999
|
const tarPath = path7.join(tmpDir, "volume.tar.gz");
|
|
6963
7000
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
6964
|
-
console.log(
|
|
7001
|
+
console.log(chalk15.dim("Syncing local files..."));
|
|
6965
7002
|
const remoteFiles = await listTarFiles(tarPath);
|
|
6966
7003
|
const remoteFilesSet = new Set(
|
|
6967
7004
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -6969,10 +7006,10 @@ var pullCommand = new Command10().name("pull").description("Pull cloud files to
|
|
|
6969
7006
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
6970
7007
|
if (removedCount > 0) {
|
|
6971
7008
|
console.log(
|
|
6972
|
-
|
|
7009
|
+
chalk15.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
6973
7010
|
);
|
|
6974
7011
|
}
|
|
6975
|
-
console.log(
|
|
7012
|
+
console.log(chalk15.dim("Extracting files..."));
|
|
6976
7013
|
await tar3.extract({
|
|
6977
7014
|
file: tarPath,
|
|
6978
7015
|
cwd,
|
|
@@ -6980,14 +7017,14 @@ var pullCommand = new Command10().name("pull").description("Pull cloud files to
|
|
|
6980
7017
|
});
|
|
6981
7018
|
await fs6.promises.unlink(tarPath);
|
|
6982
7019
|
await fs6.promises.rmdir(tmpDir);
|
|
6983
|
-
console.log(
|
|
7020
|
+
console.log(chalk15.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
6984
7021
|
} catch (error) {
|
|
6985
|
-
console.error(
|
|
7022
|
+
console.error(chalk15.red("\u2717 Pull failed"));
|
|
6986
7023
|
if (error instanceof Error) {
|
|
6987
7024
|
if (error.message.includes("Not authenticated")) {
|
|
6988
|
-
console.error(
|
|
7025
|
+
console.error(chalk15.dim(" Run: vm0 auth login"));
|
|
6989
7026
|
} else {
|
|
6990
|
-
console.error(
|
|
7027
|
+
console.error(chalk15.dim(` ${error.message}`));
|
|
6991
7028
|
}
|
|
6992
7029
|
}
|
|
6993
7030
|
process.exit(1);
|
|
@@ -6995,24 +7032,24 @@ var pullCommand = new Command10().name("pull").description("Pull cloud files to
|
|
|
6995
7032
|
});
|
|
6996
7033
|
|
|
6997
7034
|
// src/commands/volume/status.ts
|
|
6998
|
-
import { Command as
|
|
6999
|
-
import
|
|
7000
|
-
var
|
|
7035
|
+
import { Command as Command16 } from "commander";
|
|
7036
|
+
import chalk16 from "chalk";
|
|
7037
|
+
var statusCommand2 = new Command16().name("status").description("Show status of cloud volume").action(async () => {
|
|
7001
7038
|
try {
|
|
7002
7039
|
const cwd = process.cwd();
|
|
7003
7040
|
const config = await readStorageConfig(cwd);
|
|
7004
7041
|
if (!config) {
|
|
7005
|
-
console.error(
|
|
7006
|
-
console.error(
|
|
7042
|
+
console.error(chalk16.red("\u2717 No volume initialized in this directory"));
|
|
7043
|
+
console.error(chalk16.dim(" Run: vm0 volume init"));
|
|
7007
7044
|
process.exit(1);
|
|
7008
7045
|
}
|
|
7009
7046
|
if (config.type !== "volume") {
|
|
7010
7047
|
console.error(
|
|
7011
|
-
|
|
7048
|
+
chalk16.red(
|
|
7012
7049
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
7013
7050
|
)
|
|
7014
7051
|
);
|
|
7015
|
-
console.error(
|
|
7052
|
+
console.error(chalk16.dim(" Use: vm0 artifact status"));
|
|
7016
7053
|
process.exit(1);
|
|
7017
7054
|
}
|
|
7018
7055
|
console.log(`Checking volume: ${config.name}`);
|
|
@@ -7022,25 +7059,25 @@ var statusCommand = new Command11().name("status").description("Show status of c
|
|
|
7022
7059
|
});
|
|
7023
7060
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7024
7061
|
if ("empty" in info) {
|
|
7025
|
-
console.log(
|
|
7026
|
-
console.log(
|
|
7062
|
+
console.log(chalk16.green("\u2713 Found (empty)"));
|
|
7063
|
+
console.log(chalk16.dim(` Version: ${shortVersion}`));
|
|
7027
7064
|
} else {
|
|
7028
|
-
console.log(
|
|
7029
|
-
console.log(
|
|
7030
|
-
console.log(
|
|
7031
|
-
console.log(
|
|
7065
|
+
console.log(chalk16.green("\u2713 Found"));
|
|
7066
|
+
console.log(chalk16.dim(` Version: ${shortVersion}`));
|
|
7067
|
+
console.log(chalk16.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7068
|
+
console.log(chalk16.dim(` Size: ${formatBytes(info.size)}`));
|
|
7032
7069
|
}
|
|
7033
7070
|
} catch (error) {
|
|
7034
7071
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7035
|
-
console.error(
|
|
7036
|
-
console.error(
|
|
7072
|
+
console.error(chalk16.red("\u2717 Not found on remote"));
|
|
7073
|
+
console.error(chalk16.dim(" Run: vm0 volume push"));
|
|
7037
7074
|
} else {
|
|
7038
|
-
console.error(
|
|
7075
|
+
console.error(chalk16.red("\u2717 Status check failed"));
|
|
7039
7076
|
if (error instanceof Error) {
|
|
7040
7077
|
if (error.message.includes("Not authenticated")) {
|
|
7041
|
-
console.error(
|
|
7078
|
+
console.error(chalk16.dim(" Run: vm0 auth login"));
|
|
7042
7079
|
} else {
|
|
7043
|
-
console.error(
|
|
7080
|
+
console.error(chalk16.dim(` ${error.message}`));
|
|
7044
7081
|
}
|
|
7045
7082
|
}
|
|
7046
7083
|
}
|
|
@@ -7049,15 +7086,15 @@ var statusCommand = new Command11().name("status").description("Show status of c
|
|
|
7049
7086
|
});
|
|
7050
7087
|
|
|
7051
7088
|
// src/commands/volume/list.ts
|
|
7052
|
-
import { Command as
|
|
7053
|
-
import
|
|
7054
|
-
var listCommand2 = new
|
|
7089
|
+
import { Command as Command17 } from "commander";
|
|
7090
|
+
import chalk17 from "chalk";
|
|
7091
|
+
var listCommand2 = new Command17().name("list").alias("ls").description("List all remote volumes").action(async () => {
|
|
7055
7092
|
try {
|
|
7056
7093
|
const items = await listStorages({ type: "volume" });
|
|
7057
7094
|
if (items.length === 0) {
|
|
7058
|
-
console.log(
|
|
7095
|
+
console.log(chalk17.dim("No volumes found"));
|
|
7059
7096
|
console.log(
|
|
7060
|
-
|
|
7097
|
+
chalk17.dim(" Create one with: vm0 volume init && vm0 volume push")
|
|
7061
7098
|
);
|
|
7062
7099
|
return;
|
|
7063
7100
|
}
|
|
@@ -7076,7 +7113,7 @@ var listCommand2 = new Command12().name("list").alias("ls").description("List al
|
|
|
7076
7113
|
"FILES".padStart(filesWidth),
|
|
7077
7114
|
"UPDATED"
|
|
7078
7115
|
].join(" ");
|
|
7079
|
-
console.log(
|
|
7116
|
+
console.log(chalk17.dim(header));
|
|
7080
7117
|
for (const item of items) {
|
|
7081
7118
|
const row = [
|
|
7082
7119
|
item.name.padEnd(nameWidth),
|
|
@@ -7087,12 +7124,12 @@ var listCommand2 = new Command12().name("list").alias("ls").description("List al
|
|
|
7087
7124
|
console.log(row);
|
|
7088
7125
|
}
|
|
7089
7126
|
} catch (error) {
|
|
7090
|
-
console.error(
|
|
7127
|
+
console.error(chalk17.red("\u2717 Failed to list volumes"));
|
|
7091
7128
|
if (error instanceof Error) {
|
|
7092
7129
|
if (error.message.includes("Not authenticated")) {
|
|
7093
|
-
console.error(
|
|
7130
|
+
console.error(chalk17.dim(" Run: vm0 auth login"));
|
|
7094
7131
|
} else {
|
|
7095
|
-
console.error(
|
|
7132
|
+
console.error(chalk17.dim(` ${error.message}`));
|
|
7096
7133
|
}
|
|
7097
7134
|
}
|
|
7098
7135
|
process.exit(1);
|
|
@@ -7100,11 +7137,11 @@ var listCommand2 = new Command12().name("list").alias("ls").description("List al
|
|
|
7100
7137
|
});
|
|
7101
7138
|
|
|
7102
7139
|
// src/commands/volume/clone.ts
|
|
7103
|
-
import { Command as
|
|
7104
|
-
import
|
|
7140
|
+
import { Command as Command18 } from "commander";
|
|
7141
|
+
import chalk19 from "chalk";
|
|
7105
7142
|
|
|
7106
7143
|
// src/lib/storage/clone-utils.ts
|
|
7107
|
-
import
|
|
7144
|
+
import chalk18 from "chalk";
|
|
7108
7145
|
import path8 from "path";
|
|
7109
7146
|
import * as fs7 from "fs";
|
|
7110
7147
|
import * as os5 from "os";
|
|
@@ -7114,18 +7151,18 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7114
7151
|
if (fs7.existsSync(destination)) {
|
|
7115
7152
|
throw new Error(`Directory "${destination}" already exists`);
|
|
7116
7153
|
}
|
|
7117
|
-
console.log(
|
|
7154
|
+
console.log(chalk18.dim(`Checking remote ${typeLabel}...`));
|
|
7118
7155
|
const downloadInfo = await getStorageDownload({
|
|
7119
7156
|
name,
|
|
7120
7157
|
type,
|
|
7121
7158
|
version: options.version
|
|
7122
7159
|
});
|
|
7123
|
-
console.log(
|
|
7160
|
+
console.log(chalk18.dim(`Creating directory: ${destination}/`));
|
|
7124
7161
|
await fs7.promises.mkdir(destination, { recursive: true });
|
|
7125
7162
|
if ("empty" in downloadInfo) {
|
|
7126
7163
|
await writeStorageConfig(name, destination, type);
|
|
7127
|
-
console.log(
|
|
7128
|
-
console.log(
|
|
7164
|
+
console.log(chalk18.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
|
|
7165
|
+
console.log(chalk18.dim(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7129
7166
|
return {
|
|
7130
7167
|
success: true,
|
|
7131
7168
|
fileCount: 0,
|
|
@@ -7137,7 +7174,7 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7137
7174
|
if (!downloadUrl) {
|
|
7138
7175
|
throw new Error("No download URL returned");
|
|
7139
7176
|
}
|
|
7140
|
-
console.log(
|
|
7177
|
+
console.log(chalk18.dim("Downloading from S3..."));
|
|
7141
7178
|
const s3Response = await fetch(downloadUrl);
|
|
7142
7179
|
if (!s3Response.ok) {
|
|
7143
7180
|
await fs7.promises.rm(destination, { recursive: true, force: true });
|
|
@@ -7145,12 +7182,12 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7145
7182
|
}
|
|
7146
7183
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7147
7184
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7148
|
-
console.log(
|
|
7185
|
+
console.log(chalk18.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7149
7186
|
const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-clone-"));
|
|
7150
7187
|
const tarPath = path8.join(tmpDir, "archive.tar.gz");
|
|
7151
7188
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
7152
7189
|
const files = await listTarFiles(tarPath);
|
|
7153
|
-
console.log(
|
|
7190
|
+
console.log(chalk18.dim("Extracting files..."));
|
|
7154
7191
|
await tar4.extract({
|
|
7155
7192
|
file: tarPath,
|
|
7156
7193
|
cwd: destination,
|
|
@@ -7158,9 +7195,9 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7158
7195
|
});
|
|
7159
7196
|
await fs7.promises.unlink(tarPath);
|
|
7160
7197
|
await fs7.promises.rmdir(tmpDir);
|
|
7161
|
-
console.log(
|
|
7198
|
+
console.log(chalk18.green(`\u2713 Extracted ${files.length} files`));
|
|
7162
7199
|
await writeStorageConfig(name, destination, type);
|
|
7163
|
-
console.log(
|
|
7200
|
+
console.log(chalk18.green(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7164
7201
|
return {
|
|
7165
7202
|
success: true,
|
|
7166
7203
|
fileCount: downloadInfo.fileCount,
|
|
@@ -7170,22 +7207,22 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7170
7207
|
}
|
|
7171
7208
|
|
|
7172
7209
|
// src/commands/volume/clone.ts
|
|
7173
|
-
var cloneCommand = new
|
|
7210
|
+
var cloneCommand = new Command18().name("clone").description("Clone a remote volume to local directory (latest version)").argument("<name>", "Volume name to clone").argument("[destination]", "Destination directory (default: volume name)").action(async (name, destination) => {
|
|
7174
7211
|
try {
|
|
7175
7212
|
const targetDir = destination || name;
|
|
7176
7213
|
console.log(`Cloning volume: ${name}`);
|
|
7177
7214
|
const result = await cloneStorage(name, "volume", targetDir);
|
|
7178
|
-
console.log(
|
|
7215
|
+
console.log(chalk19.green(`
|
|
7179
7216
|
\u2713 Successfully cloned volume: ${name}`));
|
|
7180
|
-
console.log(
|
|
7181
|
-
console.log(
|
|
7217
|
+
console.log(chalk19.dim(` Location: ${targetDir}/`));
|
|
7218
|
+
console.log(chalk19.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7182
7219
|
} catch (error) {
|
|
7183
|
-
console.error(
|
|
7220
|
+
console.error(chalk19.red("\u2717 Clone failed"));
|
|
7184
7221
|
if (error instanceof Error) {
|
|
7185
7222
|
if (error.message.includes("Not authenticated")) {
|
|
7186
|
-
console.error(
|
|
7223
|
+
console.error(chalk19.dim(" Run: vm0 auth login"));
|
|
7187
7224
|
} else {
|
|
7188
|
-
console.error(
|
|
7225
|
+
console.error(chalk19.dim(` ${error.message}`));
|
|
7189
7226
|
}
|
|
7190
7227
|
}
|
|
7191
7228
|
process.exit(1);
|
|
@@ -7193,16 +7230,16 @@ var cloneCommand = new Command13().name("clone").description("Clone a remote vol
|
|
|
7193
7230
|
});
|
|
7194
7231
|
|
|
7195
7232
|
// src/commands/volume/index.ts
|
|
7196
|
-
var volumeCommand = new
|
|
7233
|
+
var volumeCommand = new Command19().name("volume").description("Manage volumes (defined in compose, not versioned after run)").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand2).addCommand(listCommand2).addCommand(cloneCommand);
|
|
7197
7234
|
|
|
7198
7235
|
// src/commands/artifact/index.ts
|
|
7199
|
-
import { Command as
|
|
7236
|
+
import { Command as Command26 } from "commander";
|
|
7200
7237
|
|
|
7201
7238
|
// src/commands/artifact/init.ts
|
|
7202
|
-
import { Command as
|
|
7203
|
-
import
|
|
7239
|
+
import { Command as Command20 } from "commander";
|
|
7240
|
+
import chalk20 from "chalk";
|
|
7204
7241
|
import path9 from "path";
|
|
7205
|
-
var initCommand2 = new
|
|
7242
|
+
var initCommand2 = new Command20().name("init").description("Initialize an artifact in the current directory").option(
|
|
7206
7243
|
"-n, --name <name>",
|
|
7207
7244
|
"Artifact name (required in non-interactive mode)"
|
|
7208
7245
|
).action(async (options) => {
|
|
@@ -7213,24 +7250,24 @@ var initCommand2 = new Command15().name("init").description("Initialize an artif
|
|
|
7213
7250
|
if (existingConfig) {
|
|
7214
7251
|
if (existingConfig.type === "artifact") {
|
|
7215
7252
|
console.log(
|
|
7216
|
-
|
|
7253
|
+
chalk20.yellow(
|
|
7217
7254
|
`Artifact already initialized: ${existingConfig.name}`
|
|
7218
7255
|
)
|
|
7219
7256
|
);
|
|
7220
7257
|
} else {
|
|
7221
7258
|
console.log(
|
|
7222
|
-
|
|
7259
|
+
chalk20.yellow(
|
|
7223
7260
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
7224
7261
|
)
|
|
7225
7262
|
);
|
|
7226
7263
|
console.log(
|
|
7227
|
-
|
|
7264
|
+
chalk20.dim(
|
|
7228
7265
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
7229
7266
|
)
|
|
7230
7267
|
);
|
|
7231
7268
|
}
|
|
7232
7269
|
console.log(
|
|
7233
|
-
|
|
7270
|
+
chalk20.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7234
7271
|
);
|
|
7235
7272
|
return;
|
|
7236
7273
|
}
|
|
@@ -7239,10 +7276,10 @@ var initCommand2 = new Command15().name("init").description("Initialize an artif
|
|
|
7239
7276
|
artifactName = options.name;
|
|
7240
7277
|
} else if (!isInteractive()) {
|
|
7241
7278
|
console.error(
|
|
7242
|
-
|
|
7279
|
+
chalk20.red("\u2717 --name flag is required in non-interactive mode")
|
|
7243
7280
|
);
|
|
7244
7281
|
console.error(
|
|
7245
|
-
|
|
7282
|
+
chalk20.dim(" Usage: vm0 artifact init --name <artifact-name>")
|
|
7246
7283
|
);
|
|
7247
7284
|
process.exit(1);
|
|
7248
7285
|
} else {
|
|
@@ -7258,43 +7295,43 @@ var initCommand2 = new Command15().name("init").description("Initialize an artif
|
|
|
7258
7295
|
}
|
|
7259
7296
|
);
|
|
7260
7297
|
if (name === void 0) {
|
|
7261
|
-
console.log(
|
|
7298
|
+
console.log(chalk20.dim("Cancelled"));
|
|
7262
7299
|
return;
|
|
7263
7300
|
}
|
|
7264
7301
|
artifactName = name;
|
|
7265
7302
|
}
|
|
7266
7303
|
if (!isValidStorageName(artifactName)) {
|
|
7267
|
-
console.error(
|
|
7304
|
+
console.error(chalk20.red(`\u2717 Invalid artifact name: "${artifactName}"`));
|
|
7268
7305
|
console.error(
|
|
7269
|
-
|
|
7306
|
+
chalk20.dim(
|
|
7270
7307
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7271
7308
|
)
|
|
7272
7309
|
);
|
|
7273
7310
|
console.error(
|
|
7274
|
-
|
|
7311
|
+
chalk20.dim(" Example: my-project, user-workspace, code-artifact")
|
|
7275
7312
|
);
|
|
7276
7313
|
process.exit(1);
|
|
7277
7314
|
}
|
|
7278
7315
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
7279
|
-
console.log(
|
|
7316
|
+
console.log(chalk20.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
7280
7317
|
console.log(
|
|
7281
|
-
|
|
7318
|
+
chalk20.dim(
|
|
7282
7319
|
` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
7283
7320
|
)
|
|
7284
7321
|
);
|
|
7285
7322
|
} catch (error) {
|
|
7286
|
-
console.error(
|
|
7323
|
+
console.error(chalk20.red("\u2717 Failed to initialize artifact"));
|
|
7287
7324
|
if (error instanceof Error) {
|
|
7288
|
-
console.error(
|
|
7325
|
+
console.error(chalk20.dim(` ${error.message}`));
|
|
7289
7326
|
}
|
|
7290
7327
|
process.exit(1);
|
|
7291
7328
|
}
|
|
7292
7329
|
});
|
|
7293
7330
|
|
|
7294
7331
|
// src/commands/artifact/push.ts
|
|
7295
|
-
import { Command as
|
|
7296
|
-
import
|
|
7297
|
-
var pushCommand2 = new
|
|
7332
|
+
import { Command as Command21 } from "commander";
|
|
7333
|
+
import chalk21 from "chalk";
|
|
7334
|
+
var pushCommand2 = new Command21().name("push").description("Push local files to cloud artifact").option(
|
|
7298
7335
|
"-f, --force",
|
|
7299
7336
|
"Force upload even if content unchanged (recreate archive)"
|
|
7300
7337
|
).action(async (options) => {
|
|
@@ -7302,69 +7339,69 @@ var pushCommand2 = new Command16().name("push").description("Push local files to
|
|
|
7302
7339
|
const cwd = process.cwd();
|
|
7303
7340
|
const config = await readStorageConfig(cwd);
|
|
7304
7341
|
if (!config) {
|
|
7305
|
-
console.error(
|
|
7306
|
-
console.error(
|
|
7342
|
+
console.error(chalk21.red("\u2717 No artifact initialized in this directory"));
|
|
7343
|
+
console.error(chalk21.dim(" Run: vm0 artifact init"));
|
|
7307
7344
|
process.exit(1);
|
|
7308
7345
|
}
|
|
7309
7346
|
if (config.type !== "artifact") {
|
|
7310
7347
|
console.error(
|
|
7311
|
-
|
|
7348
|
+
chalk21.red(
|
|
7312
7349
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7313
7350
|
)
|
|
7314
7351
|
);
|
|
7315
|
-
console.error(
|
|
7352
|
+
console.error(chalk21.dim(" Use: vm0 volume push"));
|
|
7316
7353
|
process.exit(1);
|
|
7317
7354
|
}
|
|
7318
7355
|
console.log(`Pushing artifact: ${config.name}`);
|
|
7319
7356
|
const result = await directUpload(config.name, "artifact", cwd, {
|
|
7320
7357
|
onProgress: (message) => {
|
|
7321
|
-
console.log(
|
|
7358
|
+
console.log(chalk21.dim(message));
|
|
7322
7359
|
},
|
|
7323
7360
|
force: options.force
|
|
7324
7361
|
});
|
|
7325
7362
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7326
7363
|
if (result.empty) {
|
|
7327
|
-
console.log(
|
|
7364
|
+
console.log(chalk21.dim("No files found (empty artifact)"));
|
|
7328
7365
|
} else if (result.deduplicated) {
|
|
7329
|
-
console.log(
|
|
7366
|
+
console.log(chalk21.green("\u2713 Content unchanged (deduplicated)"));
|
|
7330
7367
|
} else {
|
|
7331
|
-
console.log(
|
|
7368
|
+
console.log(chalk21.green("\u2713 Upload complete"));
|
|
7332
7369
|
}
|
|
7333
|
-
console.log(
|
|
7334
|
-
console.log(
|
|
7335
|
-
console.log(
|
|
7370
|
+
console.log(chalk21.dim(` Version: ${shortVersion}`));
|
|
7371
|
+
console.log(chalk21.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7372
|
+
console.log(chalk21.dim(` Size: ${formatBytes(result.size)}`));
|
|
7336
7373
|
} catch (error) {
|
|
7337
|
-
console.error(
|
|
7374
|
+
console.error(chalk21.red("\u2717 Push failed"));
|
|
7338
7375
|
if (error instanceof Error) {
|
|
7339
|
-
console.error(
|
|
7376
|
+
console.error(chalk21.dim(` ${error.message}`));
|
|
7340
7377
|
}
|
|
7341
7378
|
process.exit(1);
|
|
7342
7379
|
}
|
|
7343
7380
|
});
|
|
7344
7381
|
|
|
7345
7382
|
// src/commands/artifact/pull.ts
|
|
7346
|
-
import { Command as
|
|
7347
|
-
import
|
|
7383
|
+
import { Command as Command22 } from "commander";
|
|
7384
|
+
import chalk22 from "chalk";
|
|
7348
7385
|
import path10 from "path";
|
|
7349
7386
|
import * as fs8 from "fs";
|
|
7350
7387
|
import * as os6 from "os";
|
|
7351
7388
|
import * as tar5 from "tar";
|
|
7352
|
-
var pullCommand2 = new
|
|
7389
|
+
var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
|
|
7353
7390
|
try {
|
|
7354
7391
|
const cwd = process.cwd();
|
|
7355
7392
|
const config = await readStorageConfig(cwd);
|
|
7356
7393
|
if (!config) {
|
|
7357
|
-
console.error(
|
|
7358
|
-
console.error(
|
|
7394
|
+
console.error(chalk22.red("\u2717 No artifact initialized in this directory"));
|
|
7395
|
+
console.error(chalk22.dim(" Run: vm0 artifact init"));
|
|
7359
7396
|
process.exit(1);
|
|
7360
7397
|
}
|
|
7361
7398
|
if (config.type !== "artifact") {
|
|
7362
7399
|
console.error(
|
|
7363
|
-
|
|
7400
|
+
chalk22.red(
|
|
7364
7401
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7365
7402
|
)
|
|
7366
7403
|
);
|
|
7367
|
-
console.error(
|
|
7404
|
+
console.error(chalk22.dim(" Use: vm0 volume pull"));
|
|
7368
7405
|
process.exit(1);
|
|
7369
7406
|
}
|
|
7370
7407
|
if (versionId) {
|
|
@@ -7372,7 +7409,7 @@ var pullCommand2 = new Command17().name("pull").description("Pull cloud artifact
|
|
|
7372
7409
|
} else {
|
|
7373
7410
|
console.log(`Pulling artifact: ${config.name}`);
|
|
7374
7411
|
}
|
|
7375
|
-
console.log(
|
|
7412
|
+
console.log(chalk22.dim("Getting download URL..."));
|
|
7376
7413
|
const downloadInfo = await getStorageDownload({
|
|
7377
7414
|
name: config.name,
|
|
7378
7415
|
type: "artifact",
|
|
@@ -7386,18 +7423,18 @@ var pullCommand2 = new Command17().name("pull").description("Pull cloud artifact
|
|
|
7386
7423
|
if (!downloadUrl) {
|
|
7387
7424
|
throw new Error("No download URL returned");
|
|
7388
7425
|
}
|
|
7389
|
-
console.log(
|
|
7426
|
+
console.log(chalk22.dim("Downloading from S3..."));
|
|
7390
7427
|
const s3Response = await fetch(downloadUrl);
|
|
7391
7428
|
if (!s3Response.ok) {
|
|
7392
7429
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7393
7430
|
}
|
|
7394
7431
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7395
7432
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7396
|
-
console.log(
|
|
7433
|
+
console.log(chalk22.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7397
7434
|
const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
|
|
7398
7435
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
7399
7436
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
7400
|
-
console.log(
|
|
7437
|
+
console.log(chalk22.dim("Syncing local files..."));
|
|
7401
7438
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7402
7439
|
const remoteFilesSet = new Set(
|
|
7403
7440
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7405,10 +7442,10 @@ var pullCommand2 = new Command17().name("pull").description("Pull cloud artifact
|
|
|
7405
7442
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7406
7443
|
if (removedCount > 0) {
|
|
7407
7444
|
console.log(
|
|
7408
|
-
|
|
7445
|
+
chalk22.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7409
7446
|
);
|
|
7410
7447
|
}
|
|
7411
|
-
console.log(
|
|
7448
|
+
console.log(chalk22.dim("Extracting files..."));
|
|
7412
7449
|
await tar5.extract({
|
|
7413
7450
|
file: tarPath,
|
|
7414
7451
|
cwd,
|
|
@@ -7416,35 +7453,35 @@ var pullCommand2 = new Command17().name("pull").description("Pull cloud artifact
|
|
|
7416
7453
|
});
|
|
7417
7454
|
await fs8.promises.unlink(tarPath);
|
|
7418
7455
|
await fs8.promises.rmdir(tmpDir);
|
|
7419
|
-
console.log(
|
|
7456
|
+
console.log(chalk22.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7420
7457
|
} catch (error) {
|
|
7421
|
-
console.error(
|
|
7458
|
+
console.error(chalk22.red("\u2717 Pull failed"));
|
|
7422
7459
|
if (error instanceof Error) {
|
|
7423
|
-
console.error(
|
|
7460
|
+
console.error(chalk22.dim(` ${error.message}`));
|
|
7424
7461
|
}
|
|
7425
7462
|
process.exit(1);
|
|
7426
7463
|
}
|
|
7427
7464
|
});
|
|
7428
7465
|
|
|
7429
7466
|
// src/commands/artifact/status.ts
|
|
7430
|
-
import { Command as
|
|
7431
|
-
import
|
|
7432
|
-
var
|
|
7467
|
+
import { Command as Command23 } from "commander";
|
|
7468
|
+
import chalk23 from "chalk";
|
|
7469
|
+
var statusCommand3 = new Command23().name("status").description("Show status of cloud artifact").action(async () => {
|
|
7433
7470
|
try {
|
|
7434
7471
|
const cwd = process.cwd();
|
|
7435
7472
|
const config = await readStorageConfig(cwd);
|
|
7436
7473
|
if (!config) {
|
|
7437
|
-
console.error(
|
|
7438
|
-
console.error(
|
|
7474
|
+
console.error(chalk23.red("\u2717 No artifact initialized in this directory"));
|
|
7475
|
+
console.error(chalk23.dim(" Run: vm0 artifact init"));
|
|
7439
7476
|
process.exit(1);
|
|
7440
7477
|
}
|
|
7441
7478
|
if (config.type !== "artifact") {
|
|
7442
7479
|
console.error(
|
|
7443
|
-
|
|
7480
|
+
chalk23.red(
|
|
7444
7481
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
7445
7482
|
)
|
|
7446
7483
|
);
|
|
7447
|
-
console.error(
|
|
7484
|
+
console.error(chalk23.dim(" Use: vm0 volume status"));
|
|
7448
7485
|
process.exit(1);
|
|
7449
7486
|
}
|
|
7450
7487
|
console.log(`Checking artifact: ${config.name}`);
|
|
@@ -7454,22 +7491,22 @@ var statusCommand2 = new Command18().name("status").description("Show status of
|
|
|
7454
7491
|
});
|
|
7455
7492
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7456
7493
|
if ("empty" in info) {
|
|
7457
|
-
console.log(
|
|
7458
|
-
console.log(
|
|
7494
|
+
console.log(chalk23.green("\u2713 Found (empty)"));
|
|
7495
|
+
console.log(chalk23.dim(` Version: ${shortVersion}`));
|
|
7459
7496
|
} else {
|
|
7460
|
-
console.log(
|
|
7461
|
-
console.log(
|
|
7462
|
-
console.log(
|
|
7463
|
-
console.log(
|
|
7497
|
+
console.log(chalk23.green("\u2713 Found"));
|
|
7498
|
+
console.log(chalk23.dim(` Version: ${shortVersion}`));
|
|
7499
|
+
console.log(chalk23.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7500
|
+
console.log(chalk23.dim(` Size: ${formatBytes(info.size)}`));
|
|
7464
7501
|
}
|
|
7465
7502
|
} catch (error) {
|
|
7466
7503
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7467
|
-
console.error(
|
|
7468
|
-
console.error(
|
|
7504
|
+
console.error(chalk23.red("\u2717 Not found on remote"));
|
|
7505
|
+
console.error(chalk23.dim(" Run: vm0 artifact push"));
|
|
7469
7506
|
} else {
|
|
7470
|
-
console.error(
|
|
7507
|
+
console.error(chalk23.red("\u2717 Status check failed"));
|
|
7471
7508
|
if (error instanceof Error) {
|
|
7472
|
-
console.error(
|
|
7509
|
+
console.error(chalk23.dim(` ${error.message}`));
|
|
7473
7510
|
}
|
|
7474
7511
|
}
|
|
7475
7512
|
process.exit(1);
|
|
@@ -7477,15 +7514,15 @@ var statusCommand2 = new Command18().name("status").description("Show status of
|
|
|
7477
7514
|
});
|
|
7478
7515
|
|
|
7479
7516
|
// src/commands/artifact/list.ts
|
|
7480
|
-
import { Command as
|
|
7481
|
-
import
|
|
7482
|
-
var listCommand3 = new
|
|
7517
|
+
import { Command as Command24 } from "commander";
|
|
7518
|
+
import chalk24 from "chalk";
|
|
7519
|
+
var listCommand3 = new Command24().name("list").alias("ls").description("List all remote artifacts").action(async () => {
|
|
7483
7520
|
try {
|
|
7484
7521
|
const items = await listStorages({ type: "artifact" });
|
|
7485
7522
|
if (items.length === 0) {
|
|
7486
|
-
console.log(
|
|
7523
|
+
console.log(chalk24.dim("No artifacts found"));
|
|
7487
7524
|
console.log(
|
|
7488
|
-
|
|
7525
|
+
chalk24.dim(
|
|
7489
7526
|
" Create one with: vm0 artifact init && vm0 artifact push"
|
|
7490
7527
|
)
|
|
7491
7528
|
);
|
|
@@ -7506,7 +7543,7 @@ var listCommand3 = new Command19().name("list").alias("ls").description("List al
|
|
|
7506
7543
|
"FILES".padStart(filesWidth),
|
|
7507
7544
|
"UPDATED"
|
|
7508
7545
|
].join(" ");
|
|
7509
|
-
console.log(
|
|
7546
|
+
console.log(chalk24.dim(header));
|
|
7510
7547
|
for (const item of items) {
|
|
7511
7548
|
const row = [
|
|
7512
7549
|
item.name.padEnd(nameWidth),
|
|
@@ -7517,12 +7554,12 @@ var listCommand3 = new Command19().name("list").alias("ls").description("List al
|
|
|
7517
7554
|
console.log(row);
|
|
7518
7555
|
}
|
|
7519
7556
|
} catch (error) {
|
|
7520
|
-
console.error(
|
|
7557
|
+
console.error(chalk24.red("\u2717 Failed to list artifacts"));
|
|
7521
7558
|
if (error instanceof Error) {
|
|
7522
7559
|
if (error.message.includes("Not authenticated")) {
|
|
7523
|
-
console.error(
|
|
7560
|
+
console.error(chalk24.dim(" Run: vm0 auth login"));
|
|
7524
7561
|
} else {
|
|
7525
|
-
console.error(
|
|
7562
|
+
console.error(chalk24.dim(` ${error.message}`));
|
|
7526
7563
|
}
|
|
7527
7564
|
}
|
|
7528
7565
|
process.exit(1);
|
|
@@ -7530,24 +7567,24 @@ var listCommand3 = new Command19().name("list").alias("ls").description("List al
|
|
|
7530
7567
|
});
|
|
7531
7568
|
|
|
7532
7569
|
// src/commands/artifact/clone.ts
|
|
7533
|
-
import { Command as
|
|
7534
|
-
import
|
|
7535
|
-
var cloneCommand2 = new
|
|
7570
|
+
import { Command as Command25 } from "commander";
|
|
7571
|
+
import chalk25 from "chalk";
|
|
7572
|
+
var cloneCommand2 = new Command25().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
|
|
7536
7573
|
try {
|
|
7537
7574
|
const targetDir = destination || name;
|
|
7538
7575
|
console.log(`Cloning artifact: ${name}`);
|
|
7539
7576
|
const result = await cloneStorage(name, "artifact", targetDir);
|
|
7540
|
-
console.log(
|
|
7577
|
+
console.log(chalk25.green(`
|
|
7541
7578
|
\u2713 Successfully cloned artifact: ${name}`));
|
|
7542
|
-
console.log(
|
|
7543
|
-
console.log(
|
|
7579
|
+
console.log(chalk25.dim(` Location: ${targetDir}/`));
|
|
7580
|
+
console.log(chalk25.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7544
7581
|
} catch (error) {
|
|
7545
|
-
console.error(
|
|
7582
|
+
console.error(chalk25.red("\u2717 Clone failed"));
|
|
7546
7583
|
if (error instanceof Error) {
|
|
7547
7584
|
if (error.message.includes("Not authenticated")) {
|
|
7548
|
-
console.error(
|
|
7585
|
+
console.error(chalk25.dim(" Run: vm0 auth login"));
|
|
7549
7586
|
} else {
|
|
7550
|
-
console.error(
|
|
7587
|
+
console.error(chalk25.dim(` ${error.message}`));
|
|
7551
7588
|
}
|
|
7552
7589
|
}
|
|
7553
7590
|
process.exit(1);
|
|
@@ -7555,21 +7592,20 @@ var cloneCommand2 = new Command20().name("clone").description("Clone a remote ar
|
|
|
7555
7592
|
});
|
|
7556
7593
|
|
|
7557
7594
|
// src/commands/artifact/index.ts
|
|
7558
|
-
var artifactCommand = new
|
|
7595
|
+
var artifactCommand = new Command26().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand3).addCommand(listCommand3).addCommand(cloneCommand2);
|
|
7559
7596
|
|
|
7560
|
-
// src/commands/cook.ts
|
|
7561
|
-
import { Command as
|
|
7562
|
-
import
|
|
7597
|
+
// src/commands/cook/cook.ts
|
|
7598
|
+
import { Command as Command27, Option as Option4 } from "commander";
|
|
7599
|
+
import chalk28 from "chalk";
|
|
7563
7600
|
import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
|
|
7564
|
-
import { existsSync as
|
|
7601
|
+
import { existsSync as existsSync9 } from "fs";
|
|
7565
7602
|
import path11 from "path";
|
|
7566
|
-
import { spawn as spawn2 } from "child_process";
|
|
7567
7603
|
import { parse as parseYaml4 } from "yaml";
|
|
7568
7604
|
import { config as dotenvConfig2 } from "dotenv";
|
|
7569
7605
|
|
|
7570
7606
|
// src/lib/utils/update-checker.ts
|
|
7571
7607
|
import { spawn } from "child_process";
|
|
7572
|
-
import
|
|
7608
|
+
import chalk26 from "chalk";
|
|
7573
7609
|
var PACKAGE_NAME = "@vm0/cli";
|
|
7574
7610
|
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
7575
7611
|
var TIMEOUT_MS = 5e3;
|
|
@@ -7653,21 +7689,21 @@ function performUpgrade(packageManager) {
|
|
|
7653
7689
|
async function checkAndUpgrade(currentVersion, prompt) {
|
|
7654
7690
|
const latestVersion = await getLatestVersion();
|
|
7655
7691
|
if (latestVersion === null) {
|
|
7656
|
-
console.log(
|
|
7692
|
+
console.log(chalk26.yellow("Warning: Could not check for updates"));
|
|
7657
7693
|
console.log();
|
|
7658
7694
|
return false;
|
|
7659
7695
|
}
|
|
7660
7696
|
if (latestVersion === currentVersion) {
|
|
7661
7697
|
return false;
|
|
7662
7698
|
}
|
|
7663
|
-
console.log(
|
|
7699
|
+
console.log(chalk26.yellow("vm0 is currently in Early Access (EA)."));
|
|
7664
7700
|
console.log(
|
|
7665
|
-
|
|
7701
|
+
chalk26.yellow(
|
|
7666
7702
|
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
7667
7703
|
)
|
|
7668
7704
|
);
|
|
7669
7705
|
console.log(
|
|
7670
|
-
|
|
7706
|
+
chalk26.yellow(
|
|
7671
7707
|
"Please always use the latest version for best compatibility."
|
|
7672
7708
|
)
|
|
7673
7709
|
);
|
|
@@ -7676,33 +7712,33 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
7676
7712
|
if (!isAutoUpgradeSupported(packageManager)) {
|
|
7677
7713
|
if (packageManager === "unknown") {
|
|
7678
7714
|
console.log(
|
|
7679
|
-
|
|
7715
|
+
chalk26.yellow("Could not detect your package manager for auto-upgrade.")
|
|
7680
7716
|
);
|
|
7681
7717
|
} else {
|
|
7682
7718
|
console.log(
|
|
7683
|
-
|
|
7719
|
+
chalk26.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
|
|
7684
7720
|
);
|
|
7685
7721
|
}
|
|
7686
|
-
console.log(
|
|
7687
|
-
console.log(
|
|
7722
|
+
console.log(chalk26.yellow("Please upgrade manually:"));
|
|
7723
|
+
console.log(chalk26.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
7688
7724
|
console.log();
|
|
7689
7725
|
return false;
|
|
7690
7726
|
}
|
|
7691
7727
|
console.log(`Upgrading via ${packageManager}...`);
|
|
7692
7728
|
const success = await performUpgrade(packageManager);
|
|
7693
7729
|
if (success) {
|
|
7694
|
-
console.log(
|
|
7730
|
+
console.log(chalk26.green(`Upgraded to ${latestVersion}`));
|
|
7695
7731
|
console.log();
|
|
7696
7732
|
console.log("To continue, run:");
|
|
7697
|
-
console.log(
|
|
7733
|
+
console.log(chalk26.cyan(` ${buildRerunCommand(prompt)}`));
|
|
7698
7734
|
return true;
|
|
7699
7735
|
}
|
|
7700
7736
|
console.log();
|
|
7701
|
-
console.log(
|
|
7702
|
-
console.log(
|
|
7737
|
+
console.log(chalk26.red("Upgrade failed. Please run manually:"));
|
|
7738
|
+
console.log(chalk26.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
7703
7739
|
console.log();
|
|
7704
7740
|
console.log("Then re-run:");
|
|
7705
|
-
console.log(
|
|
7741
|
+
console.log(chalk26.cyan(` ${buildRerunCommand(prompt)}`));
|
|
7706
7742
|
return true;
|
|
7707
7743
|
}
|
|
7708
7744
|
|
|
@@ -7771,11 +7807,14 @@ async function saveCookState(state) {
|
|
|
7771
7807
|
await writeFile5(COOK_STATE_FILE, JSON.stringify(file, null, 2), "utf8");
|
|
7772
7808
|
}
|
|
7773
7809
|
|
|
7774
|
-
// src/commands/cook.ts
|
|
7810
|
+
// src/commands/cook/utils.ts
|
|
7811
|
+
import chalk27 from "chalk";
|
|
7812
|
+
import { spawn as spawn2 } from "child_process";
|
|
7813
|
+
import { existsSync as existsSync8 } from "fs";
|
|
7775
7814
|
var CONFIG_FILE2 = "vm0.yaml";
|
|
7776
7815
|
var ARTIFACT_DIR = "artifact";
|
|
7777
7816
|
function printCommand(cmd) {
|
|
7778
|
-
console.log(
|
|
7817
|
+
console.log(chalk27.dim(`> ${cmd}`));
|
|
7779
7818
|
}
|
|
7780
7819
|
function execVm0Command(args, options = {}) {
|
|
7781
7820
|
return new Promise((resolve, reject) => {
|
|
@@ -7867,6 +7906,32 @@ function parseRunIdsFromOutput(output) {
|
|
|
7867
7906
|
checkpointId: stripped.match(/vm0 run resume ([0-9a-f-]{36})/)?.[1]
|
|
7868
7907
|
};
|
|
7869
7908
|
}
|
|
7909
|
+
async function autoPullArtifact(runOutput, artifactDir) {
|
|
7910
|
+
const serverVersion = parseArtifactVersionFromCompletion(
|
|
7911
|
+
runOutput,
|
|
7912
|
+
ARTIFACT_DIR
|
|
7913
|
+
);
|
|
7914
|
+
if (serverVersion && existsSync8(artifactDir)) {
|
|
7915
|
+
console.log();
|
|
7916
|
+
console.log(chalk27.bold("Pulling updated artifact:"));
|
|
7917
|
+
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
7918
|
+
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
7919
|
+
try {
|
|
7920
|
+
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
7921
|
+
cwd: artifactDir,
|
|
7922
|
+
silent: true
|
|
7923
|
+
});
|
|
7924
|
+
printCommand("cd ..");
|
|
7925
|
+
} catch (error) {
|
|
7926
|
+
console.error(chalk27.red(`\u2717 Artifact pull failed`));
|
|
7927
|
+
if (error instanceof Error) {
|
|
7928
|
+
console.error(chalk27.dim(` ${error.message}`));
|
|
7929
|
+
}
|
|
7930
|
+
}
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
|
|
7934
|
+
// src/commands/cook/cook.ts
|
|
7870
7935
|
function extractRequiredVarNames(config) {
|
|
7871
7936
|
const refs = extractVariableReferences(config);
|
|
7872
7937
|
const grouped = groupVariablesBySource(refs);
|
|
@@ -7877,7 +7942,7 @@ function extractRequiredVarNames(config) {
|
|
|
7877
7942
|
function checkMissingVariables(varNames, envFilePath) {
|
|
7878
7943
|
let fileValues = {};
|
|
7879
7944
|
if (envFilePath) {
|
|
7880
|
-
if (!
|
|
7945
|
+
if (!existsSync9(envFilePath)) {
|
|
7881
7946
|
throw new Error(`Environment file not found: ${envFilePath}`);
|
|
7882
7947
|
}
|
|
7883
7948
|
const result = dotenvConfig2({ path: envFilePath, quiet: true });
|
|
@@ -7895,47 +7960,22 @@ function checkMissingVariables(varNames, envFilePath) {
|
|
|
7895
7960
|
}
|
|
7896
7961
|
return missing;
|
|
7897
7962
|
}
|
|
7898
|
-
|
|
7899
|
-
const serverVersion = parseArtifactVersionFromCompletion(
|
|
7900
|
-
runOutput,
|
|
7901
|
-
ARTIFACT_DIR
|
|
7902
|
-
);
|
|
7903
|
-
if (serverVersion && existsSync8(artifactDir)) {
|
|
7904
|
-
console.log();
|
|
7905
|
-
console.log(chalk26.bold("Pulling updated artifact:"));
|
|
7906
|
-
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
7907
|
-
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
7908
|
-
try {
|
|
7909
|
-
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
7910
|
-
cwd: artifactDir,
|
|
7911
|
-
silent: true
|
|
7912
|
-
});
|
|
7913
|
-
printCommand("cd ..");
|
|
7914
|
-
} catch (error) {
|
|
7915
|
-
console.error(chalk26.red(`\u2717 Artifact pull failed`));
|
|
7916
|
-
if (error instanceof Error) {
|
|
7917
|
-
console.error(chalk26.dim(` ${error.message}`));
|
|
7918
|
-
}
|
|
7919
|
-
}
|
|
7920
|
-
}
|
|
7921
|
-
}
|
|
7922
|
-
var cookCmd = new Command22().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml");
|
|
7923
|
-
cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
7963
|
+
var cookAction = new Command27().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml").argument("[prompt]", "Prompt for the agent").option(
|
|
7924
7964
|
"--env-file <path>",
|
|
7925
7965
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
7926
7966
|
).option("-y, --yes", "Skip confirmation prompts").addOption(new Option4("--debug-no-mock-claude").hideHelp()).addOption(new Option4("--no-auto-update").hideHelp()).action(
|
|
7927
7967
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
7928
7968
|
async (prompt, options) => {
|
|
7929
7969
|
if (!options.noAutoUpdate) {
|
|
7930
|
-
const shouldExit = await checkAndUpgrade("9.4.
|
|
7970
|
+
const shouldExit = await checkAndUpgrade("9.4.1", prompt);
|
|
7931
7971
|
if (shouldExit) {
|
|
7932
7972
|
process.exit(0);
|
|
7933
7973
|
}
|
|
7934
7974
|
}
|
|
7935
7975
|
const cwd = process.cwd();
|
|
7936
|
-
console.log(
|
|
7937
|
-
if (!
|
|
7938
|
-
console.error(
|
|
7976
|
+
console.log(chalk28.bold(`Reading config: ${CONFIG_FILE2}`));
|
|
7977
|
+
if (!existsSync9(CONFIG_FILE2)) {
|
|
7978
|
+
console.error(chalk28.red(`\u2717 Config file not found: ${CONFIG_FILE2}`));
|
|
7939
7979
|
process.exit(1);
|
|
7940
7980
|
}
|
|
7941
7981
|
let config;
|
|
@@ -7943,22 +7983,22 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7943
7983
|
const content = await readFile7(CONFIG_FILE2, "utf8");
|
|
7944
7984
|
config = parseYaml4(content);
|
|
7945
7985
|
} catch (error) {
|
|
7946
|
-
console.error(
|
|
7986
|
+
console.error(chalk28.red("\u2717 Invalid YAML format"));
|
|
7947
7987
|
if (error instanceof Error) {
|
|
7948
|
-
console.error(
|
|
7988
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
7949
7989
|
}
|
|
7950
7990
|
process.exit(1);
|
|
7951
7991
|
}
|
|
7952
7992
|
const validation = validateAgentCompose(config);
|
|
7953
7993
|
if (!validation.valid) {
|
|
7954
|
-
console.error(
|
|
7994
|
+
console.error(chalk28.red(`\u2717 ${validation.error}`));
|
|
7955
7995
|
process.exit(1);
|
|
7956
7996
|
}
|
|
7957
7997
|
const agentNames = Object.keys(config.agents);
|
|
7958
7998
|
const agentName = agentNames[0];
|
|
7959
7999
|
const volumeCount = config.volumes ? Object.keys(config.volumes).length : 0;
|
|
7960
8000
|
console.log(
|
|
7961
|
-
|
|
8001
|
+
chalk28.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
7962
8002
|
);
|
|
7963
8003
|
const requiredVarNames = extractRequiredVarNames(config);
|
|
7964
8004
|
if (requiredVarNames.length > 0) {
|
|
@@ -7969,12 +8009,12 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7969
8009
|
);
|
|
7970
8010
|
if (missingVars.length > 0) {
|
|
7971
8011
|
console.log();
|
|
7972
|
-
console.error(
|
|
8012
|
+
console.error(chalk28.red("\u2717 Missing required variables:"));
|
|
7973
8013
|
for (const varName of missingVars) {
|
|
7974
|
-
console.error(
|
|
8014
|
+
console.error(chalk28.red(` ${varName}`));
|
|
7975
8015
|
}
|
|
7976
8016
|
console.error(
|
|
7977
|
-
|
|
8017
|
+
chalk28.dim(
|
|
7978
8018
|
"\n Provide via --env-file, or set as environment variables"
|
|
7979
8019
|
)
|
|
7980
8020
|
);
|
|
@@ -7982,22 +8022,22 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
7982
8022
|
}
|
|
7983
8023
|
} catch (error) {
|
|
7984
8024
|
if (error instanceof Error) {
|
|
7985
|
-
console.error(
|
|
8025
|
+
console.error(chalk28.red(`\u2717 ${error.message}`));
|
|
7986
8026
|
}
|
|
7987
8027
|
process.exit(1);
|
|
7988
8028
|
}
|
|
7989
8029
|
}
|
|
7990
8030
|
if (config.volumes && Object.keys(config.volumes).length > 0) {
|
|
7991
8031
|
console.log();
|
|
7992
|
-
console.log(
|
|
8032
|
+
console.log(chalk28.bold("Processing volumes:"));
|
|
7993
8033
|
for (const volumeConfig of Object.values(config.volumes)) {
|
|
7994
8034
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
7995
|
-
if (!
|
|
8035
|
+
if (!existsSync9(volumeDir)) {
|
|
7996
8036
|
console.error(
|
|
7997
|
-
|
|
8037
|
+
chalk28.red(`\u2717 Directory not found: ${volumeConfig.name}`)
|
|
7998
8038
|
);
|
|
7999
8039
|
console.error(
|
|
8000
|
-
|
|
8040
|
+
chalk28.dim(" Create the directory and add files first")
|
|
8001
8041
|
);
|
|
8002
8042
|
process.exit(1);
|
|
8003
8043
|
}
|
|
@@ -8021,19 +8061,19 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
8021
8061
|
});
|
|
8022
8062
|
printCommand("cd ..");
|
|
8023
8063
|
} catch (error) {
|
|
8024
|
-
console.error(
|
|
8064
|
+
console.error(chalk28.red(`\u2717 Failed`));
|
|
8025
8065
|
if (error instanceof Error) {
|
|
8026
|
-
console.error(
|
|
8066
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
8027
8067
|
}
|
|
8028
8068
|
process.exit(1);
|
|
8029
8069
|
}
|
|
8030
8070
|
}
|
|
8031
8071
|
}
|
|
8032
8072
|
console.log();
|
|
8033
|
-
console.log(
|
|
8073
|
+
console.log(chalk28.bold("Processing artifact:"));
|
|
8034
8074
|
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
8035
8075
|
try {
|
|
8036
|
-
if (!
|
|
8076
|
+
if (!existsSync9(artifactDir)) {
|
|
8037
8077
|
printCommand(`mkdir ${ARTIFACT_DIR}`);
|
|
8038
8078
|
await mkdir6(artifactDir, { recursive: true });
|
|
8039
8079
|
}
|
|
@@ -8053,14 +8093,14 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
8053
8093
|
});
|
|
8054
8094
|
printCommand("cd ..");
|
|
8055
8095
|
} catch (error) {
|
|
8056
|
-
console.error(
|
|
8096
|
+
console.error(chalk28.red(`\u2717 Failed`));
|
|
8057
8097
|
if (error instanceof Error) {
|
|
8058
|
-
console.error(
|
|
8098
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
8059
8099
|
}
|
|
8060
8100
|
process.exit(1);
|
|
8061
8101
|
}
|
|
8062
8102
|
console.log();
|
|
8063
|
-
console.log(
|
|
8103
|
+
console.log(chalk28.bold("Composing agent:"));
|
|
8064
8104
|
const composeArgs = options.yes ? ["compose", "--yes", CONFIG_FILE2] : ["compose", CONFIG_FILE2];
|
|
8065
8105
|
printCommand(`vm0 ${composeArgs.join(" ")}`);
|
|
8066
8106
|
try {
|
|
@@ -8068,15 +8108,15 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
8068
8108
|
cwd
|
|
8069
8109
|
});
|
|
8070
8110
|
} catch (error) {
|
|
8071
|
-
console.error(
|
|
8111
|
+
console.error(chalk28.red(`\u2717 Compose failed`));
|
|
8072
8112
|
if (error instanceof Error) {
|
|
8073
|
-
console.error(
|
|
8113
|
+
console.error(chalk28.dim(` ${error.message}`));
|
|
8074
8114
|
}
|
|
8075
8115
|
process.exit(1);
|
|
8076
8116
|
}
|
|
8077
8117
|
if (prompt) {
|
|
8078
8118
|
console.log();
|
|
8079
|
-
console.log(
|
|
8119
|
+
console.log(chalk28.bold("Running agent:"));
|
|
8080
8120
|
printCommand(
|
|
8081
8121
|
`vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "${prompt}"`
|
|
8082
8122
|
);
|
|
@@ -8113,15 +8153,19 @@ cookCmd.argument("[prompt]", "Prompt for the agent").option(
|
|
|
8113
8153
|
}
|
|
8114
8154
|
}
|
|
8115
8155
|
);
|
|
8116
|
-
|
|
8156
|
+
|
|
8157
|
+
// src/commands/cook/logs.ts
|
|
8158
|
+
import { Command as Command28 } from "commander";
|
|
8159
|
+
import chalk29 from "chalk";
|
|
8160
|
+
var logsCommand = new Command28().name("logs").description("View logs from the last cook run").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
|
|
8117
8161
|
"--since <time>",
|
|
8118
8162
|
"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z)"
|
|
8119
8163
|
).option("--tail <n>", "Show last N entries (default: 5, max: 100)").option("--head <n>", "Show first N entries (max: 100)").action(
|
|
8120
8164
|
async (options) => {
|
|
8121
8165
|
const state = await loadCookState();
|
|
8122
8166
|
if (!state.lastRunId) {
|
|
8123
|
-
console.error(
|
|
8124
|
-
console.error(
|
|
8167
|
+
console.error(chalk29.red("\u2717 No previous run found"));
|
|
8168
|
+
console.error(chalk29.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8125
8169
|
process.exit(1);
|
|
8126
8170
|
}
|
|
8127
8171
|
const args = ["logs", state.lastRunId];
|
|
@@ -8158,21 +8202,26 @@ cookCmd.command("logs").description("View logs from the last cook run").option("
|
|
|
8158
8202
|
await execVm0Command(args);
|
|
8159
8203
|
}
|
|
8160
8204
|
);
|
|
8161
|
-
|
|
8205
|
+
|
|
8206
|
+
// src/commands/cook/continue.ts
|
|
8207
|
+
import { Command as Command29, Option as Option5 } from "commander";
|
|
8208
|
+
import chalk30 from "chalk";
|
|
8209
|
+
import path12 from "path";
|
|
8210
|
+
var continueCommand2 = new Command29().name("continue").description(
|
|
8162
8211
|
"Continue from the last session (latest conversation and artifact)"
|
|
8163
8212
|
).argument("<prompt>", "Prompt for the continued agent").option(
|
|
8164
8213
|
"--env-file <path>",
|
|
8165
8214
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8166
|
-
).addOption(new
|
|
8215
|
+
).addOption(new Option5("--debug-no-mock-claude").hideHelp()).action(
|
|
8167
8216
|
async (prompt, options) => {
|
|
8168
8217
|
const state = await loadCookState();
|
|
8169
8218
|
if (!state.lastSessionId) {
|
|
8170
|
-
console.error(
|
|
8171
|
-
console.error(
|
|
8219
|
+
console.error(chalk30.red("\u2717 No previous session found"));
|
|
8220
|
+
console.error(chalk30.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8172
8221
|
process.exit(1);
|
|
8173
8222
|
}
|
|
8174
8223
|
const cwd = process.cwd();
|
|
8175
|
-
const artifactDir =
|
|
8224
|
+
const artifactDir = path12.join(cwd, ARTIFACT_DIR);
|
|
8176
8225
|
const envFileArg = options.envFile ? ` --env-file ${options.envFile}` : "";
|
|
8177
8226
|
printCommand(
|
|
8178
8227
|
`vm0 run continue${envFileArg} ${state.lastSessionId} "${prompt}"`
|
|
@@ -8205,21 +8254,26 @@ cookCmd.command("continue").description(
|
|
|
8205
8254
|
await autoPullArtifact(runOutput, artifactDir);
|
|
8206
8255
|
}
|
|
8207
8256
|
);
|
|
8208
|
-
|
|
8257
|
+
|
|
8258
|
+
// src/commands/cook/resume.ts
|
|
8259
|
+
import { Command as Command30, Option as Option6 } from "commander";
|
|
8260
|
+
import chalk31 from "chalk";
|
|
8261
|
+
import path13 from "path";
|
|
8262
|
+
var resumeCommand2 = new Command30().name("resume").description(
|
|
8209
8263
|
"Resume from the last checkpoint (snapshotted conversation and artifact)"
|
|
8210
8264
|
).argument("<prompt>", "Prompt for the resumed agent").option(
|
|
8211
8265
|
"--env-file <path>",
|
|
8212
8266
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8213
|
-
).addOption(new
|
|
8267
|
+
).addOption(new Option6("--debug-no-mock-claude").hideHelp()).action(
|
|
8214
8268
|
async (prompt, options) => {
|
|
8215
8269
|
const state = await loadCookState();
|
|
8216
8270
|
if (!state.lastCheckpointId) {
|
|
8217
|
-
console.error(
|
|
8218
|
-
console.error(
|
|
8271
|
+
console.error(chalk31.red("\u2717 No previous checkpoint found"));
|
|
8272
|
+
console.error(chalk31.dim(" Run 'vm0 cook <prompt>' first"));
|
|
8219
8273
|
process.exit(1);
|
|
8220
8274
|
}
|
|
8221
8275
|
const cwd = process.cwd();
|
|
8222
|
-
const artifactDir =
|
|
8276
|
+
const artifactDir = path13.join(cwd, ARTIFACT_DIR);
|
|
8223
8277
|
const envFileArg = options.envFile ? ` --env-file ${options.envFile}` : "";
|
|
8224
8278
|
printCommand(
|
|
8225
8279
|
`vm0 run resume${envFileArg} ${state.lastCheckpointId} "${prompt}"`
|
|
@@ -8252,11 +8306,16 @@ cookCmd.command("resume").description(
|
|
|
8252
8306
|
await autoPullArtifact(runOutput, artifactDir);
|
|
8253
8307
|
}
|
|
8254
8308
|
);
|
|
8255
|
-
|
|
8309
|
+
|
|
8310
|
+
// src/commands/cook/index.ts
|
|
8311
|
+
cookAction.addCommand(logsCommand);
|
|
8312
|
+
cookAction.addCommand(continueCommand2);
|
|
8313
|
+
cookAction.addCommand(resumeCommand2);
|
|
8314
|
+
var cookCommand = cookAction;
|
|
8256
8315
|
|
|
8257
8316
|
// src/commands/logs/index.ts
|
|
8258
|
-
import { Command as
|
|
8259
|
-
import
|
|
8317
|
+
import { Command as Command31 } from "commander";
|
|
8318
|
+
import chalk32 from "chalk";
|
|
8260
8319
|
|
|
8261
8320
|
// src/lib/utils/time-parser.ts
|
|
8262
8321
|
function parseTime(timeStr) {
|
|
@@ -8310,36 +8369,36 @@ function formatMetric(metric) {
|
|
|
8310
8369
|
}
|
|
8311
8370
|
function formatNetworkLog(entry) {
|
|
8312
8371
|
if (entry.mode === "sni" || !entry.method) {
|
|
8313
|
-
const actionColor = entry.action === "ALLOW" ?
|
|
8372
|
+
const actionColor = entry.action === "ALLOW" ? chalk32.green : chalk32.red;
|
|
8314
8373
|
const host = entry.host || "unknown";
|
|
8315
8374
|
const port = entry.port || 443;
|
|
8316
|
-
return `[${entry.timestamp}] ${
|
|
8375
|
+
return `[${entry.timestamp}] ${chalk32.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk32.dim(entry.rule_matched || "")}`;
|
|
8317
8376
|
}
|
|
8318
8377
|
let statusColor;
|
|
8319
8378
|
const status = entry.status || 0;
|
|
8320
8379
|
if (status >= 200 && status < 300) {
|
|
8321
|
-
statusColor =
|
|
8380
|
+
statusColor = chalk32.green;
|
|
8322
8381
|
} else if (status >= 300 && status < 400) {
|
|
8323
|
-
statusColor =
|
|
8382
|
+
statusColor = chalk32.yellow;
|
|
8324
8383
|
} else if (status >= 400) {
|
|
8325
|
-
statusColor =
|
|
8384
|
+
statusColor = chalk32.red;
|
|
8326
8385
|
} else {
|
|
8327
|
-
statusColor =
|
|
8386
|
+
statusColor = chalk32.gray;
|
|
8328
8387
|
}
|
|
8329
8388
|
let latencyColor;
|
|
8330
8389
|
const latencyMs = entry.latency_ms || 0;
|
|
8331
8390
|
if (latencyMs < 500) {
|
|
8332
|
-
latencyColor =
|
|
8391
|
+
latencyColor = chalk32.green;
|
|
8333
8392
|
} else if (latencyMs < 2e3) {
|
|
8334
|
-
latencyColor =
|
|
8393
|
+
latencyColor = chalk32.yellow;
|
|
8335
8394
|
} else {
|
|
8336
|
-
latencyColor =
|
|
8395
|
+
latencyColor = chalk32.red;
|
|
8337
8396
|
}
|
|
8338
8397
|
const method = entry.method || "???";
|
|
8339
8398
|
const requestSize = entry.request_size || 0;
|
|
8340
8399
|
const responseSize = entry.response_size || 0;
|
|
8341
8400
|
const url = entry.url || entry.host || "unknown";
|
|
8342
|
-
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${
|
|
8401
|
+
return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk32.dim(url)}`;
|
|
8343
8402
|
}
|
|
8344
8403
|
function renderAgentEvent(event, provider) {
|
|
8345
8404
|
const eventData = event.eventData;
|
|
@@ -8362,7 +8421,7 @@ function getLogType(options) {
|
|
|
8362
8421
|
].filter(Boolean).length;
|
|
8363
8422
|
if (selected > 1) {
|
|
8364
8423
|
console.error(
|
|
8365
|
-
|
|
8424
|
+
chalk32.red(
|
|
8366
8425
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
8367
8426
|
)
|
|
8368
8427
|
);
|
|
@@ -8373,7 +8432,7 @@ function getLogType(options) {
|
|
|
8373
8432
|
if (options.network) return "network";
|
|
8374
8433
|
return "agent";
|
|
8375
8434
|
}
|
|
8376
|
-
var
|
|
8435
|
+
var logsCommand2 = new Command31().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
|
|
8377
8436
|
"--since <time>",
|
|
8378
8437
|
"Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
|
|
8379
8438
|
).option("--tail <n>", "Show last N entries (default: 5, max: 100)").option("--head <n>", "Show first N entries (max: 100)").action(
|
|
@@ -8382,7 +8441,7 @@ var logsCommand = new Command23().name("logs").description("View logs for an age
|
|
|
8382
8441
|
const logType = getLogType(options);
|
|
8383
8442
|
if (options.tail !== void 0 && options.head !== void 0) {
|
|
8384
8443
|
console.error(
|
|
8385
|
-
|
|
8444
|
+
chalk32.red("Options --tail and --head are mutually exclusive")
|
|
8386
8445
|
);
|
|
8387
8446
|
process.exit(1);
|
|
8388
8447
|
}
|
|
@@ -8419,7 +8478,7 @@ var logsCommand = new Command23().name("logs").description("View logs for an age
|
|
|
8419
8478
|
async function showAgentEvents(runId, options) {
|
|
8420
8479
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
8421
8480
|
if (response.events.length === 0) {
|
|
8422
|
-
console.log(
|
|
8481
|
+
console.log(chalk32.yellow("No agent events found for this run"));
|
|
8423
8482
|
return;
|
|
8424
8483
|
}
|
|
8425
8484
|
const events = options.order === "desc" ? [...response.events].reverse() : response.events;
|
|
@@ -8429,7 +8488,7 @@ async function showAgentEvents(runId, options) {
|
|
|
8429
8488
|
if (response.hasMore) {
|
|
8430
8489
|
console.log();
|
|
8431
8490
|
console.log(
|
|
8432
|
-
|
|
8491
|
+
chalk32.dim(
|
|
8433
8492
|
`Showing ${response.events.length} events. Use --tail to see more.`
|
|
8434
8493
|
)
|
|
8435
8494
|
);
|
|
@@ -8438,21 +8497,21 @@ async function showAgentEvents(runId, options) {
|
|
|
8438
8497
|
async function showSystemLog(runId, options) {
|
|
8439
8498
|
const response = await apiClient.getSystemLog(runId, options);
|
|
8440
8499
|
if (!response.systemLog) {
|
|
8441
|
-
console.log(
|
|
8500
|
+
console.log(chalk32.yellow("No system log found for this run"));
|
|
8442
8501
|
return;
|
|
8443
8502
|
}
|
|
8444
8503
|
console.log(response.systemLog);
|
|
8445
8504
|
if (response.hasMore) {
|
|
8446
8505
|
console.log();
|
|
8447
8506
|
console.log(
|
|
8448
|
-
|
|
8507
|
+
chalk32.dim("More log entries available. Use --tail to see more.")
|
|
8449
8508
|
);
|
|
8450
8509
|
}
|
|
8451
8510
|
}
|
|
8452
8511
|
async function showMetrics(runId, options) {
|
|
8453
8512
|
const response = await apiClient.getMetrics(runId, options);
|
|
8454
8513
|
if (response.metrics.length === 0) {
|
|
8455
|
-
console.log(
|
|
8514
|
+
console.log(chalk32.yellow("No metrics found for this run"));
|
|
8456
8515
|
return;
|
|
8457
8516
|
}
|
|
8458
8517
|
const metrics = options.order === "desc" ? [...response.metrics].reverse() : response.metrics;
|
|
@@ -8462,7 +8521,7 @@ async function showMetrics(runId, options) {
|
|
|
8462
8521
|
if (response.hasMore) {
|
|
8463
8522
|
console.log();
|
|
8464
8523
|
console.log(
|
|
8465
|
-
|
|
8524
|
+
chalk32.dim(
|
|
8466
8525
|
`Showing ${response.metrics.length} metrics. Use --tail to see more.`
|
|
8467
8526
|
)
|
|
8468
8527
|
);
|
|
@@ -8472,7 +8531,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
8472
8531
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
8473
8532
|
if (response.networkLogs.length === 0) {
|
|
8474
8533
|
console.log(
|
|
8475
|
-
|
|
8534
|
+
chalk32.yellow(
|
|
8476
8535
|
"No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner"
|
|
8477
8536
|
)
|
|
8478
8537
|
);
|
|
@@ -8485,7 +8544,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
8485
8544
|
if (response.hasMore) {
|
|
8486
8545
|
console.log();
|
|
8487
8546
|
console.log(
|
|
8488
|
-
|
|
8547
|
+
chalk32.dim(
|
|
8489
8548
|
`Showing ${response.networkLogs.length} network logs. Use --tail to see more.`
|
|
8490
8549
|
)
|
|
8491
8550
|
);
|
|
@@ -8494,31 +8553,31 @@ async function showNetworkLogs(runId, options) {
|
|
|
8494
8553
|
function handleError2(error, runId) {
|
|
8495
8554
|
if (error instanceof Error) {
|
|
8496
8555
|
if (error.message.includes("Not authenticated")) {
|
|
8497
|
-
console.error(
|
|
8556
|
+
console.error(chalk32.red("Not authenticated. Run: vm0 auth login"));
|
|
8498
8557
|
} else if (error.message.includes("not found")) {
|
|
8499
|
-
console.error(
|
|
8558
|
+
console.error(chalk32.red(`Run not found: ${runId}`));
|
|
8500
8559
|
} else if (error.message.includes("Invalid time format")) {
|
|
8501
|
-
console.error(
|
|
8560
|
+
console.error(chalk32.red(error.message));
|
|
8502
8561
|
} else {
|
|
8503
|
-
console.error(
|
|
8504
|
-
console.error(
|
|
8562
|
+
console.error(chalk32.red("Failed to fetch logs"));
|
|
8563
|
+
console.error(chalk32.dim(` ${error.message}`));
|
|
8505
8564
|
}
|
|
8506
8565
|
} else {
|
|
8507
|
-
console.error(
|
|
8566
|
+
console.error(chalk32.red("An unexpected error occurred"));
|
|
8508
8567
|
}
|
|
8509
8568
|
}
|
|
8510
8569
|
|
|
8511
8570
|
// src/commands/scope/index.ts
|
|
8512
|
-
import { Command as
|
|
8571
|
+
import { Command as Command34 } from "commander";
|
|
8513
8572
|
|
|
8514
8573
|
// src/commands/scope/status.ts
|
|
8515
|
-
import { Command as
|
|
8516
|
-
import
|
|
8517
|
-
var
|
|
8574
|
+
import { Command as Command32 } from "commander";
|
|
8575
|
+
import chalk33 from "chalk";
|
|
8576
|
+
var statusCommand4 = new Command32().name("status").description("View current scope status").action(async () => {
|
|
8518
8577
|
try {
|
|
8519
8578
|
const scope = await getScope();
|
|
8520
|
-
console.log(
|
|
8521
|
-
console.log(` Slug: ${
|
|
8579
|
+
console.log(chalk33.bold("Scope Information:"));
|
|
8580
|
+
console.log(` Slug: ${chalk33.green(scope.slug)}`);
|
|
8522
8581
|
console.log(` Type: ${scope.type}`);
|
|
8523
8582
|
console.log(
|
|
8524
8583
|
` Created: ${new Date(scope.createdAt).toLocaleDateString()}`
|
|
@@ -8526,29 +8585,29 @@ var statusCommand3 = new Command24().name("status").description("View current sc
|
|
|
8526
8585
|
} catch (error) {
|
|
8527
8586
|
if (error instanceof Error) {
|
|
8528
8587
|
if (error.message.includes("Not authenticated")) {
|
|
8529
|
-
console.error(
|
|
8588
|
+
console.error(chalk33.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8530
8589
|
} else if (error.message.includes("No scope configured")) {
|
|
8531
|
-
console.log(
|
|
8590
|
+
console.log(chalk33.yellow("No scope configured"));
|
|
8532
8591
|
console.log();
|
|
8533
8592
|
console.log("Set your scope with:");
|
|
8534
|
-
console.log(
|
|
8593
|
+
console.log(chalk33.cyan(" vm0 scope set <slug>"));
|
|
8535
8594
|
console.log();
|
|
8536
8595
|
console.log("Example:");
|
|
8537
|
-
console.log(
|
|
8596
|
+
console.log(chalk33.dim(" vm0 scope set myusername"));
|
|
8538
8597
|
} else {
|
|
8539
|
-
console.error(
|
|
8598
|
+
console.error(chalk33.red(`\u2717 ${error.message}`));
|
|
8540
8599
|
}
|
|
8541
8600
|
} else {
|
|
8542
|
-
console.error(
|
|
8601
|
+
console.error(chalk33.red("\u2717 An unexpected error occurred"));
|
|
8543
8602
|
}
|
|
8544
8603
|
process.exit(1);
|
|
8545
8604
|
}
|
|
8546
8605
|
});
|
|
8547
8606
|
|
|
8548
8607
|
// src/commands/scope/set.ts
|
|
8549
|
-
import { Command as
|
|
8550
|
-
import
|
|
8551
|
-
var setCommand = new
|
|
8608
|
+
import { Command as Command33 } from "commander";
|
|
8609
|
+
import chalk34 from "chalk";
|
|
8610
|
+
var setCommand = new Command33().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) => {
|
|
8552
8611
|
try {
|
|
8553
8612
|
let existingScope;
|
|
8554
8613
|
try {
|
|
@@ -8562,66 +8621,66 @@ var setCommand = new Command25().name("set").description("Set your scope slug").
|
|
|
8562
8621
|
if (existingScope) {
|
|
8563
8622
|
if (!options.force) {
|
|
8564
8623
|
console.error(
|
|
8565
|
-
|
|
8624
|
+
chalk34.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
8566
8625
|
);
|
|
8567
8626
|
console.error();
|
|
8568
8627
|
console.error("To change your scope, use --force:");
|
|
8569
|
-
console.error(
|
|
8628
|
+
console.error(chalk34.cyan(` vm0 scope set ${slug} --force`));
|
|
8570
8629
|
console.error();
|
|
8571
8630
|
console.error(
|
|
8572
|
-
|
|
8631
|
+
chalk34.yellow(
|
|
8573
8632
|
"Warning: Changing your scope may break existing agent references."
|
|
8574
8633
|
)
|
|
8575
8634
|
);
|
|
8576
8635
|
process.exit(1);
|
|
8577
8636
|
}
|
|
8578
8637
|
scope = await updateScope({ slug, force: true });
|
|
8579
|
-
console.log(
|
|
8638
|
+
console.log(chalk34.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
8580
8639
|
} else {
|
|
8581
8640
|
scope = await createScope({ slug });
|
|
8582
|
-
console.log(
|
|
8641
|
+
console.log(chalk34.green(`\u2713 Scope created: ${scope.slug}`));
|
|
8583
8642
|
}
|
|
8584
8643
|
console.log();
|
|
8585
8644
|
console.log("Your agents will now be namespaced as:");
|
|
8586
|
-
console.log(
|
|
8645
|
+
console.log(chalk34.cyan(` ${scope.slug}/<agent-name>`));
|
|
8587
8646
|
} catch (error) {
|
|
8588
8647
|
if (error instanceof Error) {
|
|
8589
8648
|
if (error.message.includes("Not authenticated")) {
|
|
8590
|
-
console.error(
|
|
8649
|
+
console.error(chalk34.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
8591
8650
|
} else if (error.message.includes("already exists")) {
|
|
8592
8651
|
console.error(
|
|
8593
|
-
|
|
8652
|
+
chalk34.red(
|
|
8594
8653
|
`\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
|
|
8595
8654
|
)
|
|
8596
8655
|
);
|
|
8597
8656
|
} else if (error.message.includes("reserved")) {
|
|
8598
|
-
console.error(
|
|
8657
|
+
console.error(chalk34.red(`\u2717 ${error.message}`));
|
|
8599
8658
|
} else if (error.message.includes("vm0")) {
|
|
8600
8659
|
console.error(
|
|
8601
|
-
|
|
8660
|
+
chalk34.red(
|
|
8602
8661
|
"\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
|
|
8603
8662
|
)
|
|
8604
8663
|
);
|
|
8605
8664
|
} else {
|
|
8606
|
-
console.error(
|
|
8665
|
+
console.error(chalk34.red(`\u2717 ${error.message}`));
|
|
8607
8666
|
}
|
|
8608
8667
|
} else {
|
|
8609
|
-
console.error(
|
|
8668
|
+
console.error(chalk34.red("\u2717 An unexpected error occurred"));
|
|
8610
8669
|
}
|
|
8611
8670
|
process.exit(1);
|
|
8612
8671
|
}
|
|
8613
8672
|
});
|
|
8614
8673
|
|
|
8615
8674
|
// src/commands/scope/index.ts
|
|
8616
|
-
var scopeCommand = new
|
|
8675
|
+
var scopeCommand = new Command34().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand4).addCommand(setCommand);
|
|
8617
8676
|
|
|
8618
8677
|
// src/commands/agent/index.ts
|
|
8619
|
-
import { Command as
|
|
8678
|
+
import { Command as Command37 } from "commander";
|
|
8620
8679
|
|
|
8621
8680
|
// src/commands/agent/list.ts
|
|
8622
|
-
import { Command as
|
|
8623
|
-
import
|
|
8624
|
-
var listCommand4 = new
|
|
8681
|
+
import { Command as Command35 } from "commander";
|
|
8682
|
+
import chalk35 from "chalk";
|
|
8683
|
+
var listCommand4 = new Command35().name("list").alias("ls").description("List all agent composes").action(async () => {
|
|
8625
8684
|
try {
|
|
8626
8685
|
const response = await httpGet("/api/agent/composes/list");
|
|
8627
8686
|
if (!response.ok) {
|
|
@@ -8630,9 +8689,9 @@ var listCommand4 = new Command27().name("list").alias("ls").description("List al
|
|
|
8630
8689
|
}
|
|
8631
8690
|
const data = await response.json();
|
|
8632
8691
|
if (data.composes.length === 0) {
|
|
8633
|
-
console.log(
|
|
8692
|
+
console.log(chalk35.dim("No agent composes found"));
|
|
8634
8693
|
console.log(
|
|
8635
|
-
|
|
8694
|
+
chalk35.dim(" Create one with: vm0 compose <agent-compose.yaml>")
|
|
8636
8695
|
);
|
|
8637
8696
|
return;
|
|
8638
8697
|
}
|
|
@@ -8640,9 +8699,9 @@ var listCommand4 = new Command27().name("list").alias("ls").description("List al
|
|
|
8640
8699
|
const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
|
|
8641
8700
|
" "
|
|
8642
8701
|
);
|
|
8643
|
-
console.log(
|
|
8702
|
+
console.log(chalk35.dim(header));
|
|
8644
8703
|
for (const compose of data.composes) {
|
|
8645
|
-
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) :
|
|
8704
|
+
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk35.dim("-");
|
|
8646
8705
|
const row = [
|
|
8647
8706
|
compose.name.padEnd(nameWidth),
|
|
8648
8707
|
versionShort,
|
|
@@ -8651,12 +8710,12 @@ var listCommand4 = new Command27().name("list").alias("ls").description("List al
|
|
|
8651
8710
|
console.log(row);
|
|
8652
8711
|
}
|
|
8653
8712
|
} catch (error) {
|
|
8654
|
-
console.error(
|
|
8713
|
+
console.error(chalk35.red("\u2717 Failed to list agent composes"));
|
|
8655
8714
|
if (error instanceof Error) {
|
|
8656
8715
|
if (error.message.includes("Not authenticated")) {
|
|
8657
|
-
console.error(
|
|
8716
|
+
console.error(chalk35.dim(" Run: vm0 auth login"));
|
|
8658
8717
|
} else {
|
|
8659
|
-
console.error(
|
|
8718
|
+
console.error(chalk35.dim(` ${error.message}`));
|
|
8660
8719
|
}
|
|
8661
8720
|
}
|
|
8662
8721
|
process.exit(1);
|
|
@@ -8664,12 +8723,12 @@ var listCommand4 = new Command27().name("list").alias("ls").description("List al
|
|
|
8664
8723
|
});
|
|
8665
8724
|
|
|
8666
8725
|
// src/commands/agent/status.ts
|
|
8667
|
-
import { Command as
|
|
8668
|
-
import
|
|
8726
|
+
import { Command as Command36 } from "commander";
|
|
8727
|
+
import chalk36 from "chalk";
|
|
8669
8728
|
|
|
8670
8729
|
// src/lib/domain/source-derivation.ts
|
|
8671
8730
|
import * as fs9 from "fs/promises";
|
|
8672
|
-
import * as
|
|
8731
|
+
import * as path14 from "path";
|
|
8673
8732
|
import * as os7 from "os";
|
|
8674
8733
|
async function fetchSkillFrontmatter(skillUrl, tempDir) {
|
|
8675
8734
|
try {
|
|
@@ -8710,7 +8769,7 @@ async function deriveAgentVariableSources(agent, options) {
|
|
|
8710
8769
|
};
|
|
8711
8770
|
}
|
|
8712
8771
|
const tempDir = await fs9.mkdtemp(
|
|
8713
|
-
|
|
8772
|
+
path14.join(os7.tmpdir(), "vm0-source-derivation-")
|
|
8714
8773
|
);
|
|
8715
8774
|
try {
|
|
8716
8775
|
const skillResults = await Promise.all(
|
|
@@ -8789,27 +8848,27 @@ function formatVariableSources(sources) {
|
|
|
8789
8848
|
if (sources.secrets.length > 0) {
|
|
8790
8849
|
console.log(` Secrets:`);
|
|
8791
8850
|
for (const secret of sources.secrets) {
|
|
8792
|
-
const sourceInfo =
|
|
8851
|
+
const sourceInfo = chalk36.dim(`(${secret.source})`);
|
|
8793
8852
|
console.log(` - ${secret.name.padEnd(20)} ${sourceInfo}`);
|
|
8794
8853
|
}
|
|
8795
8854
|
}
|
|
8796
8855
|
if (sources.vars.length > 0) {
|
|
8797
8856
|
console.log(` Vars:`);
|
|
8798
8857
|
for (const v of sources.vars) {
|
|
8799
|
-
const sourceInfo =
|
|
8858
|
+
const sourceInfo = chalk36.dim(`(${v.source})`);
|
|
8800
8859
|
console.log(` - ${v.name.padEnd(20)} ${sourceInfo}`);
|
|
8801
8860
|
}
|
|
8802
8861
|
}
|
|
8803
8862
|
if (sources.credentials.length > 0) {
|
|
8804
8863
|
console.log(` Credentials:`);
|
|
8805
8864
|
for (const cred of sources.credentials) {
|
|
8806
|
-
const sourceInfo =
|
|
8865
|
+
const sourceInfo = chalk36.dim(`(${cred.source})`);
|
|
8807
8866
|
console.log(` - ${cred.name.padEnd(20)} ${sourceInfo}`);
|
|
8808
8867
|
}
|
|
8809
8868
|
}
|
|
8810
8869
|
}
|
|
8811
8870
|
function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
8812
|
-
console.log(` ${
|
|
8871
|
+
console.log(` ${chalk36.cyan(agentName)}:`);
|
|
8813
8872
|
console.log(` Framework: ${agent.framework}`);
|
|
8814
8873
|
if (agent.image) {
|
|
8815
8874
|
console.log(` Image: ${agent.image}`);
|
|
@@ -8828,16 +8887,16 @@ function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
|
8828
8887
|
}
|
|
8829
8888
|
}
|
|
8830
8889
|
function formatComposeOutput(name, versionId, content, variableSources) {
|
|
8831
|
-
console.log(
|
|
8832
|
-
console.log(
|
|
8890
|
+
console.log(chalk36.bold("Name:") + ` ${name}`);
|
|
8891
|
+
console.log(chalk36.bold("Version:") + ` ${versionId}`);
|
|
8833
8892
|
console.log();
|
|
8834
|
-
console.log(
|
|
8893
|
+
console.log(chalk36.bold("Agents:"));
|
|
8835
8894
|
for (const [agentName, agent] of Object.entries(content.agents)) {
|
|
8836
8895
|
const agentSources = variableSources?.get(agentName);
|
|
8837
8896
|
formatAgentDetails(agentName, agent, agentSources, content.volumes);
|
|
8838
8897
|
}
|
|
8839
8898
|
}
|
|
8840
|
-
var
|
|
8899
|
+
var statusCommand5 = new Command36().name("status").description("Show status of agent compose").argument(
|
|
8841
8900
|
"<name[:version]>",
|
|
8842
8901
|
"Agent name with optional version (e.g., my-agent:latest or my-agent:a1b2c3d4)"
|
|
8843
8902
|
).option("--no-sources", "Skip fetching skills to determine variable sources").action(async (argument, options) => {
|
|
@@ -8854,8 +8913,8 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8854
8913
|
}
|
|
8855
8914
|
const compose = await getComposeByName(name);
|
|
8856
8915
|
if (!compose) {
|
|
8857
|
-
console.error(
|
|
8858
|
-
console.error(
|
|
8916
|
+
console.error(chalk36.red(`\u2717 Agent compose not found: ${name}`));
|
|
8917
|
+
console.error(chalk36.dim(" Run: vm0 agent list"));
|
|
8859
8918
|
process.exit(1);
|
|
8860
8919
|
}
|
|
8861
8920
|
let resolvedVersionId = compose.headVersionId;
|
|
@@ -8866,9 +8925,9 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8866
8925
|
resolvedVersionId = versionInfo.versionId;
|
|
8867
8926
|
} catch (error) {
|
|
8868
8927
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
8869
|
-
console.error(
|
|
8928
|
+
console.error(chalk36.red(`\u2717 Version not found: ${version}`));
|
|
8870
8929
|
console.error(
|
|
8871
|
-
|
|
8930
|
+
chalk36.dim(
|
|
8872
8931
|
` HEAD version: ${compose.headVersionId?.slice(0, 8)}`
|
|
8873
8932
|
)
|
|
8874
8933
|
);
|
|
@@ -8881,7 +8940,7 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8881
8940
|
}
|
|
8882
8941
|
}
|
|
8883
8942
|
if (!resolvedVersionId || !compose.content) {
|
|
8884
|
-
console.error(
|
|
8943
|
+
console.error(chalk36.red(`\u2717 No version found for: ${name}`));
|
|
8885
8944
|
process.exit(1);
|
|
8886
8945
|
}
|
|
8887
8946
|
const content = compose.content;
|
|
@@ -8892,7 +8951,7 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8892
8951
|
});
|
|
8893
8952
|
} catch {
|
|
8894
8953
|
console.error(
|
|
8895
|
-
|
|
8954
|
+
chalk36.yellow(
|
|
8896
8955
|
"\u26A0 Warning: Failed to fetch skill sources, showing basic info"
|
|
8897
8956
|
)
|
|
8898
8957
|
);
|
|
@@ -8904,12 +8963,12 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8904
8963
|
variableSources
|
|
8905
8964
|
);
|
|
8906
8965
|
} catch (error) {
|
|
8907
|
-
console.error(
|
|
8966
|
+
console.error(chalk36.red("\u2717 Failed to get agent compose status"));
|
|
8908
8967
|
if (error instanceof Error) {
|
|
8909
8968
|
if (error.message.includes("Not authenticated")) {
|
|
8910
|
-
console.error(
|
|
8969
|
+
console.error(chalk36.dim(" Run: vm0 auth login"));
|
|
8911
8970
|
} else {
|
|
8912
|
-
console.error(
|
|
8971
|
+
console.error(chalk36.dim(` ${error.message}`));
|
|
8913
8972
|
}
|
|
8914
8973
|
}
|
|
8915
8974
|
process.exit(1);
|
|
@@ -8917,13 +8976,13 @@ var statusCommand4 = new Command28().name("status").description("Show status of
|
|
|
8917
8976
|
});
|
|
8918
8977
|
|
|
8919
8978
|
// src/commands/agent/index.ts
|
|
8920
|
-
var agentCommand = new
|
|
8979
|
+
var agentCommand = new Command37().name("agent").description("Manage agent composes").addCommand(listCommand4).addCommand(statusCommand5);
|
|
8921
8980
|
|
|
8922
|
-
// src/commands/init.ts
|
|
8923
|
-
import { Command as
|
|
8924
|
-
import
|
|
8925
|
-
import
|
|
8926
|
-
import { existsSync as
|
|
8981
|
+
// src/commands/init/index.ts
|
|
8982
|
+
import { Command as Command38 } from "commander";
|
|
8983
|
+
import chalk37 from "chalk";
|
|
8984
|
+
import path15 from "path";
|
|
8985
|
+
import { existsSync as existsSync10 } from "fs";
|
|
8927
8986
|
import { writeFile as writeFile6 } from "fs/promises";
|
|
8928
8987
|
var VM0_YAML_FILE = "vm0.yaml";
|
|
8929
8988
|
var AGENTS_MD_FILE = "AGENTS.md";
|
|
@@ -8955,18 +9014,18 @@ You are a HackerNews AI content curator.
|
|
|
8955
9014
|
}
|
|
8956
9015
|
function checkExistingFiles() {
|
|
8957
9016
|
const existingFiles = [];
|
|
8958
|
-
if (
|
|
8959
|
-
if (
|
|
9017
|
+
if (existsSync10(VM0_YAML_FILE)) existingFiles.push(VM0_YAML_FILE);
|
|
9018
|
+
if (existsSync10(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
8960
9019
|
return existingFiles;
|
|
8961
9020
|
}
|
|
8962
|
-
var initCommand3 = new
|
|
9021
|
+
var initCommand3 = new Command38().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
|
|
8963
9022
|
const existingFiles = checkExistingFiles();
|
|
8964
9023
|
if (existingFiles.length > 0 && !options.force) {
|
|
8965
9024
|
for (const file of existingFiles) {
|
|
8966
|
-
console.log(
|
|
9025
|
+
console.log(chalk37.red(`\u2717 ${file} already exists`));
|
|
8967
9026
|
}
|
|
8968
9027
|
console.log();
|
|
8969
|
-
console.log(`To overwrite: ${
|
|
9028
|
+
console.log(`To overwrite: ${chalk37.cyan("vm0 init --force")}`);
|
|
8970
9029
|
process.exit(1);
|
|
8971
9030
|
}
|
|
8972
9031
|
let agentName;
|
|
@@ -8974,12 +9033,12 @@ var initCommand3 = new Command30().name("init").description("Initialize a new VM
|
|
|
8974
9033
|
agentName = options.name.trim();
|
|
8975
9034
|
} else if (!isInteractive()) {
|
|
8976
9035
|
console.error(
|
|
8977
|
-
|
|
9036
|
+
chalk37.red("\u2717 --name flag is required in non-interactive mode")
|
|
8978
9037
|
);
|
|
8979
|
-
console.error(
|
|
9038
|
+
console.error(chalk37.dim(" Usage: vm0 init --name <agent-name>"));
|
|
8980
9039
|
process.exit(1);
|
|
8981
9040
|
} else {
|
|
8982
|
-
const dirName =
|
|
9041
|
+
const dirName = path15.basename(process.cwd());
|
|
8983
9042
|
const defaultName = validateAgentName(dirName) ? dirName : void 0;
|
|
8984
9043
|
const name = await promptText(
|
|
8985
9044
|
"Enter agent name",
|
|
@@ -8992,44 +9051,44 @@ var initCommand3 = new Command30().name("init").description("Initialize a new VM
|
|
|
8992
9051
|
}
|
|
8993
9052
|
);
|
|
8994
9053
|
if (name === void 0) {
|
|
8995
|
-
console.log(
|
|
9054
|
+
console.log(chalk37.dim("Cancelled"));
|
|
8996
9055
|
return;
|
|
8997
9056
|
}
|
|
8998
9057
|
agentName = name;
|
|
8999
9058
|
}
|
|
9000
9059
|
if (!agentName || !validateAgentName(agentName)) {
|
|
9001
|
-
console.log(
|
|
9060
|
+
console.log(chalk37.red("\u2717 Invalid agent name"));
|
|
9002
9061
|
console.log(
|
|
9003
|
-
|
|
9062
|
+
chalk37.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
|
|
9004
9063
|
);
|
|
9005
|
-
console.log(
|
|
9064
|
+
console.log(chalk37.dim(" Must start and end with letter or number"));
|
|
9006
9065
|
process.exit(1);
|
|
9007
9066
|
}
|
|
9008
9067
|
await writeFile6(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
9009
9068
|
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
9010
|
-
console.log(
|
|
9069
|
+
console.log(chalk37.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
9011
9070
|
await writeFile6(AGENTS_MD_FILE, generateAgentsMd());
|
|
9012
9071
|
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
9013
|
-
console.log(
|
|
9072
|
+
console.log(chalk37.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
9014
9073
|
console.log();
|
|
9015
9074
|
console.log("Next steps:");
|
|
9016
9075
|
console.log(
|
|
9017
|
-
` 1. Set model provider (one-time): ${
|
|
9076
|
+
` 1. Set model provider (one-time): ${chalk37.cyan("vm0 model-provider setup")}`
|
|
9018
9077
|
);
|
|
9019
9078
|
console.log(
|
|
9020
|
-
` 2. Edit ${
|
|
9079
|
+
` 2. Edit ${chalk37.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
9021
9080
|
);
|
|
9022
9081
|
console.log(
|
|
9023
|
-
` 3. Run your agent: ${
|
|
9082
|
+
` 3. Run your agent: ${chalk37.cyan(`vm0 cook "let's start working."`)}`
|
|
9024
9083
|
);
|
|
9025
9084
|
});
|
|
9026
9085
|
|
|
9027
9086
|
// src/commands/schedule/index.ts
|
|
9028
|
-
import { Command as
|
|
9087
|
+
import { Command as Command45 } from "commander";
|
|
9029
9088
|
|
|
9030
9089
|
// src/commands/schedule/setup.ts
|
|
9031
|
-
import { Command as
|
|
9032
|
-
import
|
|
9090
|
+
import { Command as Command39 } from "commander";
|
|
9091
|
+
import chalk39 from "chalk";
|
|
9033
9092
|
|
|
9034
9093
|
// src/lib/domain/schedule-utils.ts
|
|
9035
9094
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -9171,7 +9230,7 @@ async function resolveScheduleByAgent(agentName) {
|
|
|
9171
9230
|
}
|
|
9172
9231
|
|
|
9173
9232
|
// src/commands/schedule/gather-configuration.ts
|
|
9174
|
-
import
|
|
9233
|
+
import chalk38 from "chalk";
|
|
9175
9234
|
var defaultPromptDeps = {
|
|
9176
9235
|
isInteractive,
|
|
9177
9236
|
promptConfirm,
|
|
@@ -9205,7 +9264,7 @@ async function handleSecrets(optionSecrets, existingSecretNames, deps) {
|
|
|
9205
9264
|
if (keepSecrets) {
|
|
9206
9265
|
return { secrets: {}, preserveExistingSecrets: true };
|
|
9207
9266
|
}
|
|
9208
|
-
console.log(
|
|
9267
|
+
console.log(chalk38.dim(" Note: You'll need to provide new secret values"));
|
|
9209
9268
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
9210
9269
|
}
|
|
9211
9270
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
@@ -9226,17 +9285,17 @@ async function handleVars(optionVars, existingVars, deps) {
|
|
|
9226
9285
|
return {};
|
|
9227
9286
|
}
|
|
9228
9287
|
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
9229
|
-
console.log(
|
|
9288
|
+
console.log(chalk38.yellow("\nAgent requires the following configuration:"));
|
|
9230
9289
|
if (missingSecrets.length > 0) {
|
|
9231
|
-
console.log(
|
|
9290
|
+
console.log(chalk38.dim(" Secrets:"));
|
|
9232
9291
|
for (const name of missingSecrets) {
|
|
9233
|
-
console.log(
|
|
9292
|
+
console.log(chalk38.dim(` ${name}`));
|
|
9234
9293
|
}
|
|
9235
9294
|
}
|
|
9236
9295
|
if (missingVars.length > 0) {
|
|
9237
|
-
console.log(
|
|
9296
|
+
console.log(chalk38.dim(" Vars:"));
|
|
9238
9297
|
for (const name of missingVars) {
|
|
9239
|
-
console.log(
|
|
9298
|
+
console.log(chalk38.dim(` ${name}`));
|
|
9240
9299
|
}
|
|
9241
9300
|
}
|
|
9242
9301
|
console.log("");
|
|
@@ -9244,7 +9303,7 @@ function displayMissingRequirements(missingSecrets, missingVars) {
|
|
|
9244
9303
|
async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
9245
9304
|
for (const name of missingSecrets) {
|
|
9246
9305
|
const value = await deps.promptPassword(
|
|
9247
|
-
`Enter value for secret ${
|
|
9306
|
+
`Enter value for secret ${chalk38.cyan(name)}`
|
|
9248
9307
|
);
|
|
9249
9308
|
if (value) {
|
|
9250
9309
|
secrets[name] = value;
|
|
@@ -9254,7 +9313,7 @@ async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
|
9254
9313
|
async function promptForMissingVars(missingVars, vars, deps) {
|
|
9255
9314
|
for (const name of missingVars) {
|
|
9256
9315
|
const value = await deps.promptText(
|
|
9257
|
-
`Enter value for var ${
|
|
9316
|
+
`Enter value for var ${chalk38.cyan(name)}`,
|
|
9258
9317
|
""
|
|
9259
9318
|
);
|
|
9260
9319
|
if (value) {
|
|
@@ -9344,7 +9403,7 @@ function expandEnvVars(value) {
|
|
|
9344
9403
|
const envValue = process.env[varName];
|
|
9345
9404
|
if (envValue === void 0) {
|
|
9346
9405
|
console.warn(
|
|
9347
|
-
|
|
9406
|
+
chalk39.yellow(` Warning: Environment variable ${varName} not set`)
|
|
9348
9407
|
);
|
|
9349
9408
|
return match;
|
|
9350
9409
|
}
|
|
@@ -9411,7 +9470,7 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
|
|
|
9411
9470
|
}
|
|
9412
9471
|
if (!isInteractive()) {
|
|
9413
9472
|
console.error(
|
|
9414
|
-
|
|
9473
|
+
chalk39.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
|
|
9415
9474
|
);
|
|
9416
9475
|
process.exit(1);
|
|
9417
9476
|
}
|
|
@@ -9431,7 +9490,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9431
9490
|
const day2 = parseDayOption(optionDay, frequency);
|
|
9432
9491
|
if (day2 === void 0) {
|
|
9433
9492
|
console.error(
|
|
9434
|
-
|
|
9493
|
+
chalk39.red(
|
|
9435
9494
|
`\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
9436
9495
|
)
|
|
9437
9496
|
);
|
|
@@ -9440,7 +9499,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9440
9499
|
return day2;
|
|
9441
9500
|
}
|
|
9442
9501
|
if (!isInteractive()) {
|
|
9443
|
-
console.error(
|
|
9502
|
+
console.error(chalk39.red("\u2717 --day is required for weekly/monthly"));
|
|
9444
9503
|
process.exit(1);
|
|
9445
9504
|
}
|
|
9446
9505
|
if (frequency === "weekly") {
|
|
@@ -9459,7 +9518,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
9459
9518
|
if (!dayStr) return null;
|
|
9460
9519
|
const day = parseInt(dayStr, 10);
|
|
9461
9520
|
if (isNaN(day) || day < 1 || day > 31) {
|
|
9462
|
-
console.error(
|
|
9521
|
+
console.error(chalk39.red("\u2717 Day must be between 1 and 31"));
|
|
9463
9522
|
process.exit(1);
|
|
9464
9523
|
}
|
|
9465
9524
|
return day;
|
|
@@ -9468,13 +9527,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
|
|
|
9468
9527
|
if (optionTime) {
|
|
9469
9528
|
const validation = validateTimeFormat(optionTime);
|
|
9470
9529
|
if (validation !== true) {
|
|
9471
|
-
console.error(
|
|
9530
|
+
console.error(chalk39.red(`\u2717 Invalid time: ${validation}`));
|
|
9472
9531
|
process.exit(1);
|
|
9473
9532
|
}
|
|
9474
9533
|
return optionTime;
|
|
9475
9534
|
}
|
|
9476
9535
|
if (!isInteractive()) {
|
|
9477
|
-
console.error(
|
|
9536
|
+
console.error(chalk39.red("\u2717 --time is required (HH:MM format)"));
|
|
9478
9537
|
process.exit(1);
|
|
9479
9538
|
}
|
|
9480
9539
|
return await promptText(
|
|
@@ -9487,7 +9546,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9487
9546
|
if (optionDay && optionTime) {
|
|
9488
9547
|
if (!validateDateFormat(optionDay)) {
|
|
9489
9548
|
console.error(
|
|
9490
|
-
|
|
9549
|
+
chalk39.red(
|
|
9491
9550
|
`\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
|
|
9492
9551
|
)
|
|
9493
9552
|
);
|
|
@@ -9495,16 +9554,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
9495
9554
|
}
|
|
9496
9555
|
if (!validateTimeFormat(optionTime)) {
|
|
9497
9556
|
console.error(
|
|
9498
|
-
|
|
9557
|
+
chalk39.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
|
|
9499
9558
|
);
|
|
9500
9559
|
process.exit(1);
|
|
9501
9560
|
}
|
|
9502
9561
|
return `${optionDay} ${optionTime}`;
|
|
9503
9562
|
}
|
|
9504
9563
|
if (!isInteractive()) {
|
|
9505
|
-
console.error(
|
|
9564
|
+
console.error(chalk39.red("\u2717 One-time schedules require interactive mode"));
|
|
9506
9565
|
console.error(
|
|
9507
|
-
|
|
9566
|
+
chalk39.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
|
|
9508
9567
|
);
|
|
9509
9568
|
process.exit(1);
|
|
9510
9569
|
}
|
|
@@ -9535,7 +9594,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
|
|
|
9535
9594
|
async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
9536
9595
|
if (optionPrompt) return optionPrompt;
|
|
9537
9596
|
if (!isInteractive()) {
|
|
9538
|
-
console.error(
|
|
9597
|
+
console.error(chalk39.red("\u2717 --prompt is required"));
|
|
9539
9598
|
process.exit(1);
|
|
9540
9599
|
}
|
|
9541
9600
|
return await promptText(
|
|
@@ -9546,8 +9605,8 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
9546
9605
|
async function resolveAgent(agentName) {
|
|
9547
9606
|
const compose = await getComposeByName(agentName);
|
|
9548
9607
|
if (!compose) {
|
|
9549
|
-
console.error(
|
|
9550
|
-
console.error(
|
|
9608
|
+
console.error(chalk39.red(`\u2717 Agent not found: ${agentName}`));
|
|
9609
|
+
console.error(chalk39.dim(" Make sure the agent is composed first"));
|
|
9551
9610
|
process.exit(1);
|
|
9552
9611
|
}
|
|
9553
9612
|
return {
|
|
@@ -9594,7 +9653,7 @@ async function buildAndDeploy(params) {
|
|
|
9594
9653
|
const expandedSecrets = expandEnvVarsInObject(params.secrets);
|
|
9595
9654
|
console.log(
|
|
9596
9655
|
`
|
|
9597
|
-
Deploying schedule for agent ${
|
|
9656
|
+
Deploying schedule for agent ${chalk39.cyan(params.agentName)}...`
|
|
9598
9657
|
);
|
|
9599
9658
|
const deployResult = await deploySchedule({
|
|
9600
9659
|
name: params.scheduleName,
|
|
@@ -9610,12 +9669,12 @@ Deploying schedule for agent ${chalk34.cyan(params.agentName)}...`
|
|
|
9610
9669
|
return deployResult;
|
|
9611
9670
|
}
|
|
9612
9671
|
function handleSetupError(error) {
|
|
9613
|
-
console.error(
|
|
9672
|
+
console.error(chalk39.red("\u2717 Failed to setup schedule"));
|
|
9614
9673
|
if (error instanceof Error) {
|
|
9615
9674
|
if (error.message.includes("Not authenticated")) {
|
|
9616
|
-
console.error(
|
|
9675
|
+
console.error(chalk39.dim(" Run: vm0 auth login"));
|
|
9617
9676
|
} else {
|
|
9618
|
-
console.error(
|
|
9677
|
+
console.error(chalk39.dim(` ${error.message}`));
|
|
9619
9678
|
}
|
|
9620
9679
|
}
|
|
9621
9680
|
process.exit(1);
|
|
@@ -9623,56 +9682,56 @@ function handleSetupError(error) {
|
|
|
9623
9682
|
function displayDeployResult(agentName, deployResult) {
|
|
9624
9683
|
if (deployResult.created) {
|
|
9625
9684
|
console.log(
|
|
9626
|
-
|
|
9685
|
+
chalk39.green(`\u2713 Created schedule for agent ${chalk39.cyan(agentName)}`)
|
|
9627
9686
|
);
|
|
9628
9687
|
} else {
|
|
9629
9688
|
console.log(
|
|
9630
|
-
|
|
9689
|
+
chalk39.green(`\u2713 Updated schedule for agent ${chalk39.cyan(agentName)}`)
|
|
9631
9690
|
);
|
|
9632
9691
|
}
|
|
9633
|
-
console.log(
|
|
9692
|
+
console.log(chalk39.dim(` Timezone: ${deployResult.schedule.timezone}`));
|
|
9634
9693
|
if (deployResult.schedule.cronExpression) {
|
|
9635
|
-
console.log(
|
|
9694
|
+
console.log(chalk39.dim(` Cron: ${deployResult.schedule.cronExpression}`));
|
|
9636
9695
|
if (deployResult.schedule.nextRunAt) {
|
|
9637
9696
|
const nextRun = formatInTimezone(
|
|
9638
9697
|
deployResult.schedule.nextRunAt,
|
|
9639
9698
|
deployResult.schedule.timezone
|
|
9640
9699
|
);
|
|
9641
|
-
console.log(
|
|
9700
|
+
console.log(chalk39.dim(` Next run: ${nextRun}`));
|
|
9642
9701
|
}
|
|
9643
9702
|
} else if (deployResult.schedule.atTime) {
|
|
9644
9703
|
const atTimeFormatted = formatInTimezone(
|
|
9645
9704
|
deployResult.schedule.atTime,
|
|
9646
9705
|
deployResult.schedule.timezone
|
|
9647
9706
|
);
|
|
9648
|
-
console.log(
|
|
9707
|
+
console.log(chalk39.dim(` At: ${atTimeFormatted}`));
|
|
9649
9708
|
}
|
|
9650
9709
|
}
|
|
9651
9710
|
async function tryEnableSchedule(scheduleName, composeId, agentName) {
|
|
9652
9711
|
try {
|
|
9653
9712
|
await enableSchedule({ name: scheduleName, composeId });
|
|
9654
9713
|
console.log(
|
|
9655
|
-
|
|
9714
|
+
chalk39.green(`\u2713 Enabled schedule for agent ${chalk39.cyan(agentName)}`)
|
|
9656
9715
|
);
|
|
9657
9716
|
} catch (error) {
|
|
9658
|
-
console.error(
|
|
9717
|
+
console.error(chalk39.yellow("\u26A0 Failed to enable schedule"));
|
|
9659
9718
|
if (error instanceof ApiRequestError) {
|
|
9660
9719
|
if (error.code === "SCHEDULE_PAST") {
|
|
9661
|
-
console.error(
|
|
9720
|
+
console.error(chalk39.dim(" Scheduled time has already passed"));
|
|
9662
9721
|
} else {
|
|
9663
|
-
console.error(
|
|
9722
|
+
console.error(chalk39.dim(` ${error.message}`));
|
|
9664
9723
|
}
|
|
9665
9724
|
} else if (error instanceof Error) {
|
|
9666
|
-
console.error(
|
|
9725
|
+
console.error(chalk39.dim(` ${error.message}`));
|
|
9667
9726
|
}
|
|
9668
9727
|
console.log(
|
|
9669
|
-
` To enable manually: ${
|
|
9728
|
+
` To enable manually: ${chalk39.cyan(`vm0 schedule enable ${agentName}`)}`
|
|
9670
9729
|
);
|
|
9671
9730
|
}
|
|
9672
9731
|
}
|
|
9673
9732
|
function showEnableHint(agentName) {
|
|
9674
9733
|
console.log();
|
|
9675
|
-
console.log(` To enable: ${
|
|
9734
|
+
console.log(` To enable: ${chalk39.cyan(`vm0 schedule enable ${agentName}`)}`);
|
|
9676
9735
|
}
|
|
9677
9736
|
async function handleScheduleEnabling(params) {
|
|
9678
9737
|
const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
|
|
@@ -9693,13 +9752,13 @@ async function handleScheduleEnabling(params) {
|
|
|
9693
9752
|
showEnableHint(agentName);
|
|
9694
9753
|
}
|
|
9695
9754
|
}
|
|
9696
|
-
var setupCommand = new
|
|
9755
|
+
var setupCommand = new Command39().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").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
|
|
9697
9756
|
try {
|
|
9698
9757
|
const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
|
|
9699
9758
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
9700
9759
|
const existingSchedule = await findExistingSchedule(agentName);
|
|
9701
9760
|
console.log(
|
|
9702
|
-
|
|
9761
|
+
chalk39.dim(
|
|
9703
9762
|
existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
|
|
9704
9763
|
)
|
|
9705
9764
|
);
|
|
@@ -9709,12 +9768,12 @@ var setupCommand = new Command31().name("setup").description("Create or edit a s
|
|
|
9709
9768
|
defaults.frequency
|
|
9710
9769
|
);
|
|
9711
9770
|
if (!frequency) {
|
|
9712
|
-
console.log(
|
|
9771
|
+
console.log(chalk39.dim("Cancelled"));
|
|
9713
9772
|
return;
|
|
9714
9773
|
}
|
|
9715
9774
|
const timing = await gatherTiming(frequency, options, defaults);
|
|
9716
9775
|
if (!timing) {
|
|
9717
|
-
console.log(
|
|
9776
|
+
console.log(chalk39.dim("Cancelled"));
|
|
9718
9777
|
return;
|
|
9719
9778
|
}
|
|
9720
9779
|
const { day, time, atTime } = timing;
|
|
@@ -9723,7 +9782,7 @@ var setupCommand = new Command31().name("setup").description("Create or edit a s
|
|
|
9723
9782
|
existingSchedule?.timezone
|
|
9724
9783
|
);
|
|
9725
9784
|
if (!timezone) {
|
|
9726
|
-
console.log(
|
|
9785
|
+
console.log(chalk39.dim("Cancelled"));
|
|
9727
9786
|
return;
|
|
9728
9787
|
}
|
|
9729
9788
|
const promptText_ = await gatherPromptText(
|
|
@@ -9731,7 +9790,7 @@ var setupCommand = new Command31().name("setup").description("Create or edit a s
|
|
|
9731
9790
|
existingSchedule?.prompt
|
|
9732
9791
|
);
|
|
9733
9792
|
if (!promptText_) {
|
|
9734
|
-
console.log(
|
|
9793
|
+
console.log(chalk39.dim("Cancelled"));
|
|
9735
9794
|
return;
|
|
9736
9795
|
}
|
|
9737
9796
|
const config = await gatherConfiguration({
|
|
@@ -9769,15 +9828,15 @@ var setupCommand = new Command31().name("setup").description("Create or edit a s
|
|
|
9769
9828
|
});
|
|
9770
9829
|
|
|
9771
9830
|
// src/commands/schedule/list.ts
|
|
9772
|
-
import { Command as
|
|
9773
|
-
import
|
|
9774
|
-
var listCommand5 = new
|
|
9831
|
+
import { Command as Command40 } from "commander";
|
|
9832
|
+
import chalk40 from "chalk";
|
|
9833
|
+
var listCommand5 = new Command40().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
9775
9834
|
try {
|
|
9776
9835
|
const result = await listSchedules();
|
|
9777
9836
|
if (result.schedules.length === 0) {
|
|
9778
|
-
console.log(
|
|
9837
|
+
console.log(chalk40.dim("No schedules found"));
|
|
9779
9838
|
console.log(
|
|
9780
|
-
|
|
9839
|
+
chalk40.dim(" Create one with: vm0 schedule setup <agent-name>")
|
|
9781
9840
|
);
|
|
9782
9841
|
return;
|
|
9783
9842
|
}
|
|
@@ -9797,10 +9856,10 @@ var listCommand5 = new Command32().name("list").alias("ls").description("List al
|
|
|
9797
9856
|
"STATUS".padEnd(8),
|
|
9798
9857
|
"NEXT RUN"
|
|
9799
9858
|
].join(" ");
|
|
9800
|
-
console.log(
|
|
9859
|
+
console.log(chalk40.dim(header));
|
|
9801
9860
|
for (const schedule of result.schedules) {
|
|
9802
9861
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
9803
|
-
const status = schedule.enabled ?
|
|
9862
|
+
const status = schedule.enabled ? chalk40.green("enabled") : chalk40.yellow("disabled");
|
|
9804
9863
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
9805
9864
|
const row = [
|
|
9806
9865
|
schedule.composeName.padEnd(agentWidth),
|
|
@@ -9812,12 +9871,12 @@ var listCommand5 = new Command32().name("list").alias("ls").description("List al
|
|
|
9812
9871
|
console.log(row);
|
|
9813
9872
|
}
|
|
9814
9873
|
} catch (error) {
|
|
9815
|
-
console.error(
|
|
9874
|
+
console.error(chalk40.red("\u2717 Failed to list schedules"));
|
|
9816
9875
|
if (error instanceof Error) {
|
|
9817
9876
|
if (error.message.includes("Not authenticated")) {
|
|
9818
|
-
console.error(
|
|
9877
|
+
console.error(chalk40.dim(" Run: vm0 auth login"));
|
|
9819
9878
|
} else {
|
|
9820
|
-
console.error(
|
|
9879
|
+
console.error(chalk40.dim(` ${error.message}`));
|
|
9821
9880
|
}
|
|
9822
9881
|
}
|
|
9823
9882
|
process.exit(1);
|
|
@@ -9825,45 +9884,45 @@ var listCommand5 = new Command32().name("list").alias("ls").description("List al
|
|
|
9825
9884
|
});
|
|
9826
9885
|
|
|
9827
9886
|
// src/commands/schedule/status.ts
|
|
9828
|
-
import { Command as
|
|
9829
|
-
import
|
|
9887
|
+
import { Command as Command41 } from "commander";
|
|
9888
|
+
import chalk41 from "chalk";
|
|
9830
9889
|
function formatDateTimeStyled(dateStr) {
|
|
9831
|
-
if (!dateStr) return
|
|
9890
|
+
if (!dateStr) return chalk41.dim("-");
|
|
9832
9891
|
const formatted = formatDateTime(dateStr);
|
|
9833
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
9892
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk41.dim("($1)"));
|
|
9834
9893
|
}
|
|
9835
9894
|
function formatTrigger(schedule) {
|
|
9836
9895
|
if (schedule.cronExpression) {
|
|
9837
9896
|
return schedule.cronExpression;
|
|
9838
9897
|
}
|
|
9839
9898
|
if (schedule.atTime) {
|
|
9840
|
-
return `${schedule.atTime} ${
|
|
9899
|
+
return `${schedule.atTime} ${chalk41.dim("(one-time)")}`;
|
|
9841
9900
|
}
|
|
9842
|
-
return
|
|
9901
|
+
return chalk41.dim("-");
|
|
9843
9902
|
}
|
|
9844
9903
|
function formatRunStatus2(status) {
|
|
9845
9904
|
switch (status) {
|
|
9846
9905
|
case "completed":
|
|
9847
|
-
return
|
|
9906
|
+
return chalk41.green(status);
|
|
9848
9907
|
case "failed":
|
|
9849
9908
|
case "timeout":
|
|
9850
|
-
return
|
|
9909
|
+
return chalk41.red(status);
|
|
9851
9910
|
case "running":
|
|
9852
|
-
return
|
|
9911
|
+
return chalk41.blue(status);
|
|
9853
9912
|
case "pending":
|
|
9854
|
-
return
|
|
9913
|
+
return chalk41.yellow(status);
|
|
9855
9914
|
default:
|
|
9856
9915
|
return status;
|
|
9857
9916
|
}
|
|
9858
9917
|
}
|
|
9859
9918
|
function printRunConfiguration(schedule) {
|
|
9860
|
-
const statusText = schedule.enabled ?
|
|
9919
|
+
const statusText = schedule.enabled ? chalk41.green("enabled") : chalk41.yellow("disabled");
|
|
9861
9920
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
9862
9921
|
console.log(
|
|
9863
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
9922
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk41.dim(`(${schedule.scopeSlug})`)}`
|
|
9864
9923
|
);
|
|
9865
9924
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
9866
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
9925
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk41.dim(promptPreview)}`);
|
|
9867
9926
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
9868
9927
|
console.log(
|
|
9869
9928
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -9900,7 +9959,7 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
9900
9959
|
console.log();
|
|
9901
9960
|
console.log("Recent Runs:");
|
|
9902
9961
|
console.log(
|
|
9903
|
-
|
|
9962
|
+
chalk41.dim("RUN ID STATUS CREATED")
|
|
9904
9963
|
);
|
|
9905
9964
|
for (const run of runs) {
|
|
9906
9965
|
const id = run.id;
|
|
@@ -9911,24 +9970,24 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
9911
9970
|
}
|
|
9912
9971
|
} catch {
|
|
9913
9972
|
console.log();
|
|
9914
|
-
console.log(
|
|
9973
|
+
console.log(chalk41.dim("Recent Runs: (unable to fetch)"));
|
|
9915
9974
|
}
|
|
9916
9975
|
}
|
|
9917
9976
|
function handleStatusError(error, agentName) {
|
|
9918
|
-
console.error(
|
|
9977
|
+
console.error(chalk41.red("\u2717 Failed to get schedule status"));
|
|
9919
9978
|
if (error instanceof Error) {
|
|
9920
9979
|
if (error.message.includes("Not authenticated")) {
|
|
9921
|
-
console.error(
|
|
9980
|
+
console.error(chalk41.dim(" Run: vm0 auth login"));
|
|
9922
9981
|
} else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
|
|
9923
|
-
console.error(
|
|
9924
|
-
console.error(
|
|
9982
|
+
console.error(chalk41.dim(` No schedule found for agent "${agentName}"`));
|
|
9983
|
+
console.error(chalk41.dim(" Run: vm0 schedule list"));
|
|
9925
9984
|
} else {
|
|
9926
|
-
console.error(
|
|
9985
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
9927
9986
|
}
|
|
9928
9987
|
}
|
|
9929
9988
|
process.exit(1);
|
|
9930
9989
|
}
|
|
9931
|
-
var
|
|
9990
|
+
var statusCommand6 = new Command41().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
|
|
9932
9991
|
"-l, --limit <number>",
|
|
9933
9992
|
"Number of recent runs to show (0 to hide)",
|
|
9934
9993
|
"5"
|
|
@@ -9938,8 +9997,8 @@ var statusCommand5 = new Command33().name("status").description("Show detailed s
|
|
|
9938
9997
|
const { name, composeId } = resolved;
|
|
9939
9998
|
const schedule = await getScheduleByName({ name, composeId });
|
|
9940
9999
|
console.log();
|
|
9941
|
-
console.log(`Schedule for agent: ${
|
|
9942
|
-
console.log(
|
|
10000
|
+
console.log(`Schedule for agent: ${chalk41.cyan(agentName)}`);
|
|
10001
|
+
console.log(chalk41.dim("\u2501".repeat(50)));
|
|
9943
10002
|
printRunConfiguration(schedule);
|
|
9944
10003
|
printTimeSchedule(schedule);
|
|
9945
10004
|
const limit = Math.min(
|
|
@@ -9954,24 +10013,24 @@ var statusCommand5 = new Command33().name("status").description("Show detailed s
|
|
|
9954
10013
|
});
|
|
9955
10014
|
|
|
9956
10015
|
// src/commands/schedule/delete.ts
|
|
9957
|
-
import { Command as
|
|
9958
|
-
import
|
|
9959
|
-
var deleteCommand = new
|
|
10016
|
+
import { Command as Command42 } from "commander";
|
|
10017
|
+
import chalk42 from "chalk";
|
|
10018
|
+
var deleteCommand = new Command42().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
|
|
9960
10019
|
try {
|
|
9961
10020
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
9962
10021
|
if (!options.force) {
|
|
9963
10022
|
if (!isInteractive()) {
|
|
9964
10023
|
console.error(
|
|
9965
|
-
|
|
10024
|
+
chalk42.red("\u2717 --force required in non-interactive mode")
|
|
9966
10025
|
);
|
|
9967
10026
|
process.exit(1);
|
|
9968
10027
|
}
|
|
9969
10028
|
const confirmed = await promptConfirm(
|
|
9970
|
-
`Delete schedule for agent ${
|
|
10029
|
+
`Delete schedule for agent ${chalk42.cyan(agentName)}?`,
|
|
9971
10030
|
false
|
|
9972
10031
|
);
|
|
9973
10032
|
if (!confirmed) {
|
|
9974
|
-
console.log(
|
|
10033
|
+
console.log(chalk42.dim("Cancelled"));
|
|
9975
10034
|
return;
|
|
9976
10035
|
}
|
|
9977
10036
|
}
|
|
@@ -9980,20 +10039,20 @@ var deleteCommand = new Command34().name("delete").alias("rm").description("Dele
|
|
|
9980
10039
|
composeId: resolved.composeId
|
|
9981
10040
|
});
|
|
9982
10041
|
console.log(
|
|
9983
|
-
|
|
10042
|
+
chalk42.green(`\u2713 Deleted schedule for agent ${chalk42.cyan(agentName)}`)
|
|
9984
10043
|
);
|
|
9985
10044
|
} catch (error) {
|
|
9986
|
-
console.error(
|
|
10045
|
+
console.error(chalk42.red("\u2717 Failed to delete schedule"));
|
|
9987
10046
|
if (error instanceof Error) {
|
|
9988
10047
|
if (error.message.includes("Not authenticated")) {
|
|
9989
|
-
console.error(
|
|
10048
|
+
console.error(chalk42.dim(" Run: vm0 auth login"));
|
|
9990
10049
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
9991
10050
|
console.error(
|
|
9992
|
-
|
|
10051
|
+
chalk42.dim(` No schedule found for agent "${agentName}"`)
|
|
9993
10052
|
);
|
|
9994
|
-
console.error(
|
|
10053
|
+
console.error(chalk42.dim(" Run: vm0 schedule list"));
|
|
9995
10054
|
} else {
|
|
9996
|
-
console.error(
|
|
10055
|
+
console.error(chalk42.dim(` ${error.message}`));
|
|
9997
10056
|
}
|
|
9998
10057
|
}
|
|
9999
10058
|
process.exit(1);
|
|
@@ -10001,9 +10060,9 @@ var deleteCommand = new Command34().name("delete").alias("rm").description("Dele
|
|
|
10001
10060
|
});
|
|
10002
10061
|
|
|
10003
10062
|
// src/commands/schedule/enable.ts
|
|
10004
|
-
import { Command as
|
|
10005
|
-
import
|
|
10006
|
-
var enableCommand = new
|
|
10063
|
+
import { Command as Command43 } from "commander";
|
|
10064
|
+
import chalk43 from "chalk";
|
|
10065
|
+
var enableCommand = new Command43().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10007
10066
|
try {
|
|
10008
10067
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10009
10068
|
await enableSchedule({
|
|
@@ -10011,34 +10070,34 @@ var enableCommand = new Command35().name("enable").description("Enable a schedul
|
|
|
10011
10070
|
composeId: resolved.composeId
|
|
10012
10071
|
});
|
|
10013
10072
|
console.log(
|
|
10014
|
-
|
|
10073
|
+
chalk43.green(`\u2713 Enabled schedule for agent ${chalk43.cyan(agentName)}`)
|
|
10015
10074
|
);
|
|
10016
10075
|
} catch (error) {
|
|
10017
|
-
console.error(
|
|
10076
|
+
console.error(chalk43.red("\u2717 Failed to enable schedule"));
|
|
10018
10077
|
if (error instanceof ApiRequestError) {
|
|
10019
10078
|
if (error.code === "SCHEDULE_PAST") {
|
|
10020
|
-
console.error(
|
|
10021
|
-
console.error(
|
|
10079
|
+
console.error(chalk43.dim(" Scheduled time has already passed"));
|
|
10080
|
+
console.error(chalk43.dim(` Run: vm0 schedule setup ${agentName}`));
|
|
10022
10081
|
} else if (error.code === "NOT_FOUND") {
|
|
10023
10082
|
console.error(
|
|
10024
|
-
|
|
10083
|
+
chalk43.dim(` No schedule found for agent "${agentName}"`)
|
|
10025
10084
|
);
|
|
10026
|
-
console.error(
|
|
10085
|
+
console.error(chalk43.dim(" Run: vm0 schedule list"));
|
|
10027
10086
|
} else if (error.code === "UNAUTHORIZED") {
|
|
10028
|
-
console.error(
|
|
10087
|
+
console.error(chalk43.dim(" Run: vm0 auth login"));
|
|
10029
10088
|
} else {
|
|
10030
|
-
console.error(
|
|
10089
|
+
console.error(chalk43.dim(` ${error.message}`));
|
|
10031
10090
|
}
|
|
10032
10091
|
} else if (error instanceof Error) {
|
|
10033
10092
|
if (error.message.includes("Not authenticated")) {
|
|
10034
|
-
console.error(
|
|
10093
|
+
console.error(chalk43.dim(" Run: vm0 auth login"));
|
|
10035
10094
|
} else if (error.message.includes("No schedule found")) {
|
|
10036
10095
|
console.error(
|
|
10037
|
-
|
|
10096
|
+
chalk43.dim(` No schedule found for agent "${agentName}"`)
|
|
10038
10097
|
);
|
|
10039
|
-
console.error(
|
|
10098
|
+
console.error(chalk43.dim(" Run: vm0 schedule list"));
|
|
10040
10099
|
} else {
|
|
10041
|
-
console.error(
|
|
10100
|
+
console.error(chalk43.dim(` ${error.message}`));
|
|
10042
10101
|
}
|
|
10043
10102
|
}
|
|
10044
10103
|
process.exit(1);
|
|
@@ -10046,9 +10105,9 @@ var enableCommand = new Command35().name("enable").description("Enable a schedul
|
|
|
10046
10105
|
});
|
|
10047
10106
|
|
|
10048
10107
|
// src/commands/schedule/disable.ts
|
|
10049
|
-
import { Command as
|
|
10050
|
-
import
|
|
10051
|
-
var disableCommand = new
|
|
10108
|
+
import { Command as Command44 } from "commander";
|
|
10109
|
+
import chalk44 from "chalk";
|
|
10110
|
+
var disableCommand = new Command44().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10052
10111
|
try {
|
|
10053
10112
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10054
10113
|
await disableSchedule({
|
|
@@ -10056,20 +10115,20 @@ var disableCommand = new Command36().name("disable").description("Disable a sche
|
|
|
10056
10115
|
composeId: resolved.composeId
|
|
10057
10116
|
});
|
|
10058
10117
|
console.log(
|
|
10059
|
-
|
|
10118
|
+
chalk44.green(`\u2713 Disabled schedule for agent ${chalk44.cyan(agentName)}`)
|
|
10060
10119
|
);
|
|
10061
10120
|
} catch (error) {
|
|
10062
|
-
console.error(
|
|
10121
|
+
console.error(chalk44.red("\u2717 Failed to disable schedule"));
|
|
10063
10122
|
if (error instanceof Error) {
|
|
10064
10123
|
if (error.message.includes("Not authenticated")) {
|
|
10065
|
-
console.error(
|
|
10124
|
+
console.error(chalk44.dim(" Run: vm0 auth login"));
|
|
10066
10125
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
10067
10126
|
console.error(
|
|
10068
|
-
|
|
10127
|
+
chalk44.dim(` No schedule found for agent "${agentName}"`)
|
|
10069
10128
|
);
|
|
10070
|
-
console.error(
|
|
10129
|
+
console.error(chalk44.dim(" Run: vm0 schedule list"));
|
|
10071
10130
|
} else {
|
|
10072
|
-
console.error(
|
|
10131
|
+
console.error(chalk44.dim(` ${error.message}`));
|
|
10073
10132
|
}
|
|
10074
10133
|
}
|
|
10075
10134
|
process.exit(1);
|
|
@@ -10077,11 +10136,11 @@ var disableCommand = new Command36().name("disable").description("Disable a sche
|
|
|
10077
10136
|
});
|
|
10078
10137
|
|
|
10079
10138
|
// src/commands/schedule/index.ts
|
|
10080
|
-
var scheduleCommand = new
|
|
10139
|
+
var scheduleCommand = new Command45().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand5).addCommand(statusCommand6).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
|
|
10081
10140
|
|
|
10082
|
-
// src/commands/usage.ts
|
|
10083
|
-
import { Command as
|
|
10084
|
-
import
|
|
10141
|
+
// src/commands/usage/index.ts
|
|
10142
|
+
import { Command as Command46 } from "commander";
|
|
10143
|
+
import chalk45 from "chalk";
|
|
10085
10144
|
|
|
10086
10145
|
// src/lib/utils/duration-formatter.ts
|
|
10087
10146
|
function formatDuration(ms) {
|
|
@@ -10111,7 +10170,7 @@ function formatDuration(ms) {
|
|
|
10111
10170
|
return parts.join(" ");
|
|
10112
10171
|
}
|
|
10113
10172
|
|
|
10114
|
-
// src/commands/usage.ts
|
|
10173
|
+
// src/commands/usage/index.ts
|
|
10115
10174
|
var MAX_RANGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
10116
10175
|
var DEFAULT_RANGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
10117
10176
|
function formatDateDisplay(dateStr) {
|
|
@@ -10154,7 +10213,7 @@ function fillMissingDates(daily, startDate, endDate) {
|
|
|
10154
10213
|
result.sort((a, b) => b.date.localeCompare(a.date));
|
|
10155
10214
|
return result;
|
|
10156
10215
|
}
|
|
10157
|
-
var usageCommand = new
|
|
10216
|
+
var usageCommand = new Command46().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
|
|
10158
10217
|
"--until <date>",
|
|
10159
10218
|
"End date (ISO format or relative, defaults to now)"
|
|
10160
10219
|
).action(async (options) => {
|
|
@@ -10168,7 +10227,7 @@ var usageCommand = new Command38().name("usage").description("View usage statist
|
|
|
10168
10227
|
endDate = new Date(untilMs);
|
|
10169
10228
|
} catch {
|
|
10170
10229
|
console.error(
|
|
10171
|
-
|
|
10230
|
+
chalk45.red(
|
|
10172
10231
|
"\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10173
10232
|
)
|
|
10174
10233
|
);
|
|
@@ -10183,7 +10242,7 @@ var usageCommand = new Command38().name("usage").description("View usage statist
|
|
|
10183
10242
|
startDate = new Date(sinceMs);
|
|
10184
10243
|
} catch {
|
|
10185
10244
|
console.error(
|
|
10186
|
-
|
|
10245
|
+
chalk45.red(
|
|
10187
10246
|
"\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10188
10247
|
)
|
|
10189
10248
|
);
|
|
@@ -10193,13 +10252,13 @@ var usageCommand = new Command38().name("usage").description("View usage statist
|
|
|
10193
10252
|
startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
|
|
10194
10253
|
}
|
|
10195
10254
|
if (startDate >= endDate) {
|
|
10196
|
-
console.error(
|
|
10255
|
+
console.error(chalk45.red("\u2717 --since must be before --until"));
|
|
10197
10256
|
process.exit(1);
|
|
10198
10257
|
}
|
|
10199
10258
|
const rangeMs = endDate.getTime() - startDate.getTime();
|
|
10200
10259
|
if (rangeMs > MAX_RANGE_MS) {
|
|
10201
10260
|
console.error(
|
|
10202
|
-
|
|
10261
|
+
chalk45.red(
|
|
10203
10262
|
"\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
|
|
10204
10263
|
)
|
|
10205
10264
|
);
|
|
@@ -10216,19 +10275,19 @@ var usageCommand = new Command38().name("usage").description("View usage statist
|
|
|
10216
10275
|
);
|
|
10217
10276
|
console.log();
|
|
10218
10277
|
console.log(
|
|
10219
|
-
|
|
10278
|
+
chalk45.bold(
|
|
10220
10279
|
`Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
|
|
10221
10280
|
)
|
|
10222
10281
|
);
|
|
10223
10282
|
console.log();
|
|
10224
|
-
console.log(
|
|
10283
|
+
console.log(chalk45.dim("DATE RUNS RUN TIME"));
|
|
10225
10284
|
for (const day of filledDaily) {
|
|
10226
10285
|
const dateDisplay = formatDateDisplay(day.date).padEnd(10);
|
|
10227
10286
|
const runsDisplay = String(day.run_count).padStart(6);
|
|
10228
10287
|
const timeDisplay = formatDuration(day.run_time_ms);
|
|
10229
10288
|
console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
|
|
10230
10289
|
}
|
|
10231
|
-
console.log(
|
|
10290
|
+
console.log(chalk45.dim("\u2500".repeat(29)));
|
|
10232
10291
|
const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
|
|
10233
10292
|
const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
|
|
10234
10293
|
console.log(
|
|
@@ -10238,68 +10297,68 @@ var usageCommand = new Command38().name("usage").description("View usage statist
|
|
|
10238
10297
|
} catch (error) {
|
|
10239
10298
|
if (error instanceof Error) {
|
|
10240
10299
|
if (error.message.includes("Not authenticated")) {
|
|
10241
|
-
console.error(
|
|
10242
|
-
console.error(
|
|
10300
|
+
console.error(chalk45.red("\u2717 Not authenticated"));
|
|
10301
|
+
console.error(chalk45.dim(" Run: vm0 auth login"));
|
|
10243
10302
|
} else {
|
|
10244
|
-
console.error(
|
|
10303
|
+
console.error(chalk45.red(`\u2717 ${error.message}`));
|
|
10245
10304
|
}
|
|
10246
10305
|
} else {
|
|
10247
|
-
console.error(
|
|
10306
|
+
console.error(chalk45.red("\u2717 An unexpected error occurred"));
|
|
10248
10307
|
}
|
|
10249
10308
|
process.exit(1);
|
|
10250
10309
|
}
|
|
10251
10310
|
});
|
|
10252
10311
|
|
|
10253
10312
|
// src/commands/credential/index.ts
|
|
10254
|
-
import { Command as
|
|
10313
|
+
import { Command as Command50 } from "commander";
|
|
10255
10314
|
|
|
10256
10315
|
// src/commands/credential/list.ts
|
|
10257
|
-
import { Command as
|
|
10258
|
-
import
|
|
10259
|
-
var listCommand6 = new
|
|
10316
|
+
import { Command as Command47 } from "commander";
|
|
10317
|
+
import chalk46 from "chalk";
|
|
10318
|
+
var listCommand6 = new Command47().name("list").alias("ls").description("List all credentials").action(async () => {
|
|
10260
10319
|
try {
|
|
10261
10320
|
const result = await listCredentials();
|
|
10262
10321
|
if (result.credentials.length === 0) {
|
|
10263
|
-
console.log(
|
|
10322
|
+
console.log(chalk46.dim("No credentials found"));
|
|
10264
10323
|
console.log();
|
|
10265
10324
|
console.log("To add a credential:");
|
|
10266
|
-
console.log(
|
|
10325
|
+
console.log(chalk46.cyan(" vm0 credential set MY_API_KEY <value>"));
|
|
10267
10326
|
return;
|
|
10268
10327
|
}
|
|
10269
|
-
console.log(
|
|
10328
|
+
console.log(chalk46.bold("Credentials:"));
|
|
10270
10329
|
console.log();
|
|
10271
10330
|
for (const credential of result.credentials) {
|
|
10272
|
-
const typeIndicator = credential.type === "model-provider" ?
|
|
10273
|
-
console.log(` ${
|
|
10331
|
+
const typeIndicator = credential.type === "model-provider" ? chalk46.dim(" [model-provider]") : "";
|
|
10332
|
+
console.log(` ${chalk46.cyan(credential.name)}${typeIndicator}`);
|
|
10274
10333
|
if (credential.description) {
|
|
10275
|
-
console.log(` ${
|
|
10334
|
+
console.log(` ${chalk46.dim(credential.description)}`);
|
|
10276
10335
|
}
|
|
10277
10336
|
console.log(
|
|
10278
|
-
` ${
|
|
10337
|
+
` ${chalk46.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
|
|
10279
10338
|
);
|
|
10280
10339
|
console.log();
|
|
10281
10340
|
}
|
|
10282
10341
|
console.log(
|
|
10283
|
-
|
|
10342
|
+
chalk46.dim(`Total: ${result.credentials.length} credential(s)`)
|
|
10284
10343
|
);
|
|
10285
10344
|
} catch (error) {
|
|
10286
10345
|
if (error instanceof Error) {
|
|
10287
10346
|
if (error.message.includes("Not authenticated")) {
|
|
10288
|
-
console.error(
|
|
10347
|
+
console.error(chalk46.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10289
10348
|
} else {
|
|
10290
|
-
console.error(
|
|
10349
|
+
console.error(chalk46.red(`\u2717 ${error.message}`));
|
|
10291
10350
|
}
|
|
10292
10351
|
} else {
|
|
10293
|
-
console.error(
|
|
10352
|
+
console.error(chalk46.red("\u2717 An unexpected error occurred"));
|
|
10294
10353
|
}
|
|
10295
10354
|
process.exit(1);
|
|
10296
10355
|
}
|
|
10297
10356
|
});
|
|
10298
10357
|
|
|
10299
10358
|
// src/commands/credential/set.ts
|
|
10300
|
-
import { Command as
|
|
10301
|
-
import
|
|
10302
|
-
var setCommand2 = new
|
|
10359
|
+
import { Command as Command48 } from "commander";
|
|
10360
|
+
import chalk47 from "chalk";
|
|
10361
|
+
var setCommand2 = new Command48().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(
|
|
10303
10362
|
async (name, value, options) => {
|
|
10304
10363
|
try {
|
|
10305
10364
|
const credential = await setCredential({
|
|
@@ -10307,29 +10366,29 @@ var setCommand2 = new Command40().name("set").description("Create or update a cr
|
|
|
10307
10366
|
value,
|
|
10308
10367
|
description: options.description
|
|
10309
10368
|
});
|
|
10310
|
-
console.log(
|
|
10369
|
+
console.log(chalk47.green(`\u2713 Credential "${credential.name}" saved`));
|
|
10311
10370
|
console.log();
|
|
10312
10371
|
console.log("Use in vm0.yaml:");
|
|
10313
|
-
console.log(
|
|
10314
|
-
console.log(
|
|
10372
|
+
console.log(chalk47.cyan(` environment:`));
|
|
10373
|
+
console.log(chalk47.cyan(` ${name}: \${{ credentials.${name} }}`));
|
|
10315
10374
|
} catch (error) {
|
|
10316
10375
|
if (error instanceof Error) {
|
|
10317
10376
|
if (error.message.includes("Not authenticated")) {
|
|
10318
10377
|
console.error(
|
|
10319
|
-
|
|
10378
|
+
chalk47.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10320
10379
|
);
|
|
10321
10380
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
10322
|
-
console.error(
|
|
10381
|
+
console.error(chalk47.red(`\u2717 ${error.message}`));
|
|
10323
10382
|
console.log();
|
|
10324
10383
|
console.log("Examples of valid credential names:");
|
|
10325
|
-
console.log(
|
|
10326
|
-
console.log(
|
|
10327
|
-
console.log(
|
|
10384
|
+
console.log(chalk47.dim(" MY_API_KEY"));
|
|
10385
|
+
console.log(chalk47.dim(" GITHUB_TOKEN"));
|
|
10386
|
+
console.log(chalk47.dim(" AWS_ACCESS_KEY_ID"));
|
|
10328
10387
|
} else {
|
|
10329
|
-
console.error(
|
|
10388
|
+
console.error(chalk47.red(`\u2717 ${error.message}`));
|
|
10330
10389
|
}
|
|
10331
10390
|
} else {
|
|
10332
|
-
console.error(
|
|
10391
|
+
console.error(chalk47.red("\u2717 An unexpected error occurred"));
|
|
10333
10392
|
}
|
|
10334
10393
|
process.exit(1);
|
|
10335
10394
|
}
|
|
@@ -10337,20 +10396,20 @@ var setCommand2 = new Command40().name("set").description("Create or update a cr
|
|
|
10337
10396
|
);
|
|
10338
10397
|
|
|
10339
10398
|
// src/commands/credential/delete.ts
|
|
10340
|
-
import { Command as
|
|
10341
|
-
import
|
|
10342
|
-
var deleteCommand2 = new
|
|
10399
|
+
import { Command as Command49 } from "commander";
|
|
10400
|
+
import chalk48 from "chalk";
|
|
10401
|
+
var deleteCommand2 = new Command49().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
10343
10402
|
try {
|
|
10344
10403
|
try {
|
|
10345
10404
|
await getCredential(name);
|
|
10346
10405
|
} catch {
|
|
10347
|
-
console.error(
|
|
10406
|
+
console.error(chalk48.red(`\u2717 Credential "${name}" not found`));
|
|
10348
10407
|
process.exit(1);
|
|
10349
10408
|
}
|
|
10350
10409
|
if (!options.yes) {
|
|
10351
10410
|
if (!isInteractive()) {
|
|
10352
10411
|
console.error(
|
|
10353
|
-
|
|
10412
|
+
chalk48.red("\u2717 --yes flag is required in non-interactive mode")
|
|
10354
10413
|
);
|
|
10355
10414
|
process.exit(1);
|
|
10356
10415
|
}
|
|
@@ -10359,43 +10418,43 @@ var deleteCommand2 = new Command41().name("delete").description("Delete a creden
|
|
|
10359
10418
|
false
|
|
10360
10419
|
);
|
|
10361
10420
|
if (!confirmed) {
|
|
10362
|
-
console.log(
|
|
10421
|
+
console.log(chalk48.dim("Cancelled"));
|
|
10363
10422
|
return;
|
|
10364
10423
|
}
|
|
10365
10424
|
}
|
|
10366
10425
|
await deleteCredential(name);
|
|
10367
|
-
console.log(
|
|
10426
|
+
console.log(chalk48.green(`\u2713 Credential "${name}" deleted`));
|
|
10368
10427
|
} catch (error) {
|
|
10369
10428
|
if (error instanceof Error) {
|
|
10370
10429
|
if (error.message.includes("Not authenticated")) {
|
|
10371
|
-
console.error(
|
|
10430
|
+
console.error(chalk48.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10372
10431
|
} else {
|
|
10373
|
-
console.error(
|
|
10432
|
+
console.error(chalk48.red(`\u2717 ${error.message}`));
|
|
10374
10433
|
}
|
|
10375
10434
|
} else {
|
|
10376
|
-
console.error(
|
|
10435
|
+
console.error(chalk48.red("\u2717 An unexpected error occurred"));
|
|
10377
10436
|
}
|
|
10378
10437
|
process.exit(1);
|
|
10379
10438
|
}
|
|
10380
10439
|
});
|
|
10381
10440
|
|
|
10382
10441
|
// src/commands/credential/index.ts
|
|
10383
|
-
var credentialCommand = new
|
|
10442
|
+
var credentialCommand = new Command50().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand6).addCommand(setCommand2).addCommand(deleteCommand2);
|
|
10384
10443
|
|
|
10385
10444
|
// src/commands/model-provider/index.ts
|
|
10386
|
-
import { Command as
|
|
10445
|
+
import { Command as Command55 } from "commander";
|
|
10387
10446
|
|
|
10388
10447
|
// src/commands/model-provider/list.ts
|
|
10389
|
-
import { Command as
|
|
10390
|
-
import
|
|
10391
|
-
var listCommand7 = new
|
|
10448
|
+
import { Command as Command51 } from "commander";
|
|
10449
|
+
import chalk49 from "chalk";
|
|
10450
|
+
var listCommand7 = new Command51().name("list").alias("ls").description("List all model providers").action(async () => {
|
|
10392
10451
|
try {
|
|
10393
10452
|
const result = await listModelProviders();
|
|
10394
10453
|
if (result.modelProviders.length === 0) {
|
|
10395
|
-
console.log(
|
|
10454
|
+
console.log(chalk49.dim("No model providers configured"));
|
|
10396
10455
|
console.log();
|
|
10397
10456
|
console.log("To add a model provider:");
|
|
10398
|
-
console.log(
|
|
10457
|
+
console.log(chalk49.cyan(" vm0 model-provider setup"));
|
|
10399
10458
|
return;
|
|
10400
10459
|
}
|
|
10401
10460
|
const byFramework = result.modelProviders.reduce(
|
|
@@ -10409,15 +10468,15 @@ var listCommand7 = new Command43().name("list").alias("ls").description("List al
|
|
|
10409
10468
|
},
|
|
10410
10469
|
{}
|
|
10411
10470
|
);
|
|
10412
|
-
console.log(
|
|
10471
|
+
console.log(chalk49.bold("Model Providers:"));
|
|
10413
10472
|
console.log();
|
|
10414
10473
|
for (const [framework, providers] of Object.entries(byFramework)) {
|
|
10415
|
-
console.log(` ${
|
|
10474
|
+
console.log(` ${chalk49.cyan(framework)}:`);
|
|
10416
10475
|
for (const provider of providers) {
|
|
10417
|
-
const defaultTag = provider.isDefault ?
|
|
10476
|
+
const defaultTag = provider.isDefault ? chalk49.green(" (default)") : "";
|
|
10418
10477
|
console.log(` ${provider.type}${defaultTag}`);
|
|
10419
10478
|
console.log(
|
|
10420
|
-
|
|
10479
|
+
chalk49.dim(
|
|
10421
10480
|
` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
|
|
10422
10481
|
)
|
|
10423
10482
|
);
|
|
@@ -10425,25 +10484,25 @@ var listCommand7 = new Command43().name("list").alias("ls").description("List al
|
|
|
10425
10484
|
console.log();
|
|
10426
10485
|
}
|
|
10427
10486
|
console.log(
|
|
10428
|
-
|
|
10487
|
+
chalk49.dim(`Total: ${result.modelProviders.length} provider(s)`)
|
|
10429
10488
|
);
|
|
10430
10489
|
} catch (error) {
|
|
10431
10490
|
if (error instanceof Error) {
|
|
10432
10491
|
if (error.message.includes("Not authenticated")) {
|
|
10433
|
-
console.error(
|
|
10492
|
+
console.error(chalk49.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10434
10493
|
} else {
|
|
10435
|
-
console.error(
|
|
10494
|
+
console.error(chalk49.red(`\u2717 ${error.message}`));
|
|
10436
10495
|
}
|
|
10437
10496
|
} else {
|
|
10438
|
-
console.error(
|
|
10497
|
+
console.error(chalk49.red("\u2717 An unexpected error occurred"));
|
|
10439
10498
|
}
|
|
10440
10499
|
process.exit(1);
|
|
10441
10500
|
}
|
|
10442
10501
|
});
|
|
10443
10502
|
|
|
10444
10503
|
// src/commands/model-provider/setup.ts
|
|
10445
|
-
import { Command as
|
|
10446
|
-
import
|
|
10504
|
+
import { Command as Command52 } from "commander";
|
|
10505
|
+
import chalk50 from "chalk";
|
|
10447
10506
|
import prompts2 from "prompts";
|
|
10448
10507
|
var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
10449
10508
|
([type, config]) => ({
|
|
@@ -10451,7 +10510,7 @@ var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
|
10451
10510
|
value: type
|
|
10452
10511
|
})
|
|
10453
10512
|
);
|
|
10454
|
-
var setupCommand2 = new
|
|
10513
|
+
var setupCommand2 = new Command52().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
|
|
10455
10514
|
"-c, --credential <credential>",
|
|
10456
10515
|
"Credential value (for non-interactive mode)"
|
|
10457
10516
|
).option("--convert", "Convert existing user credential to model provider").action(
|
|
@@ -10462,11 +10521,11 @@ var setupCommand2 = new Command44().name("setup").description("Configure a model
|
|
|
10462
10521
|
const shouldConvert = options.convert ?? false;
|
|
10463
10522
|
if (options.type && options.credential) {
|
|
10464
10523
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(options.type)) {
|
|
10465
|
-
console.error(
|
|
10524
|
+
console.error(chalk50.red(`\u2717 Invalid type "${options.type}"`));
|
|
10466
10525
|
console.log();
|
|
10467
10526
|
console.log("Valid types:");
|
|
10468
10527
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10469
|
-
console.log(` ${
|
|
10528
|
+
console.log(` ${chalk50.cyan(t)} - ${config.label}`);
|
|
10470
10529
|
}
|
|
10471
10530
|
process.exit(1);
|
|
10472
10531
|
}
|
|
@@ -10474,16 +10533,16 @@ var setupCommand2 = new Command44().name("setup").description("Configure a model
|
|
|
10474
10533
|
credential = options.credential;
|
|
10475
10534
|
} else if (options.type || options.credential) {
|
|
10476
10535
|
console.error(
|
|
10477
|
-
|
|
10536
|
+
chalk50.red("\u2717 Both --type and --credential are required")
|
|
10478
10537
|
);
|
|
10479
10538
|
process.exit(1);
|
|
10480
10539
|
} else {
|
|
10481
10540
|
if (!isInteractive()) {
|
|
10482
|
-
console.error(
|
|
10541
|
+
console.error(chalk50.red("\u2717 Interactive mode requires a TTY"));
|
|
10483
10542
|
console.log();
|
|
10484
10543
|
console.log("Use non-interactive mode:");
|
|
10485
10544
|
console.log(
|
|
10486
|
-
|
|
10545
|
+
chalk50.cyan(
|
|
10487
10546
|
' vm0 model-provider setup --type <type> --credential "<value>"'
|
|
10488
10547
|
)
|
|
10489
10548
|
);
|
|
@@ -10514,19 +10573,19 @@ var setupCommand2 = new Command44().name("setup").description("Configure a model
|
|
|
10514
10573
|
const provider2 = await convertModelProviderCredential(type);
|
|
10515
10574
|
const defaultNote2 = provider2.isDefault ? ` (default for ${provider2.framework})` : "";
|
|
10516
10575
|
console.log(
|
|
10517
|
-
|
|
10576
|
+
chalk50.green(
|
|
10518
10577
|
`\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote2}`
|
|
10519
10578
|
)
|
|
10520
10579
|
);
|
|
10521
10580
|
return;
|
|
10522
10581
|
} else {
|
|
10523
|
-
console.log(
|
|
10582
|
+
console.log(chalk50.dim("Aborted"));
|
|
10524
10583
|
process.exit(0);
|
|
10525
10584
|
}
|
|
10526
10585
|
}
|
|
10527
10586
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
10528
10587
|
console.log();
|
|
10529
|
-
console.log(
|
|
10588
|
+
console.log(chalk50.dim(config.helpText));
|
|
10530
10589
|
console.log();
|
|
10531
10590
|
const credentialResponse = await prompts2(
|
|
10532
10591
|
{
|
|
@@ -10547,24 +10606,24 @@ var setupCommand2 = new Command44().name("setup").description("Configure a model
|
|
|
10547
10606
|
const action = created ? "created" : "updated";
|
|
10548
10607
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
10549
10608
|
console.log(
|
|
10550
|
-
|
|
10609
|
+
chalk50.green(`\u2713 Model provider "${type}" ${action}${defaultNote}`)
|
|
10551
10610
|
);
|
|
10552
10611
|
} catch (error) {
|
|
10553
10612
|
if (error instanceof Error) {
|
|
10554
10613
|
if (error.message.includes("already exists")) {
|
|
10555
|
-
console.error(
|
|
10614
|
+
console.error(chalk50.red(`\u2717 ${error.message}`));
|
|
10556
10615
|
console.log();
|
|
10557
10616
|
console.log("To convert the existing credential, run:");
|
|
10558
|
-
console.log(
|
|
10617
|
+
console.log(chalk50.cyan(" vm0 model-provider setup --convert"));
|
|
10559
10618
|
} else if (error.message.includes("Not authenticated")) {
|
|
10560
10619
|
console.error(
|
|
10561
|
-
|
|
10620
|
+
chalk50.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10562
10621
|
);
|
|
10563
10622
|
} else {
|
|
10564
|
-
console.error(
|
|
10623
|
+
console.error(chalk50.red(`\u2717 ${error.message}`));
|
|
10565
10624
|
}
|
|
10566
10625
|
} else {
|
|
10567
|
-
console.error(
|
|
10626
|
+
console.error(chalk50.red("\u2717 An unexpected error occurred"));
|
|
10568
10627
|
}
|
|
10569
10628
|
process.exit(1);
|
|
10570
10629
|
}
|
|
@@ -10572,85 +10631,85 @@ var setupCommand2 = new Command44().name("setup").description("Configure a model
|
|
|
10572
10631
|
);
|
|
10573
10632
|
|
|
10574
10633
|
// src/commands/model-provider/delete.ts
|
|
10575
|
-
import { Command as
|
|
10576
|
-
import
|
|
10577
|
-
var deleteCommand3 = new
|
|
10634
|
+
import { Command as Command53 } from "commander";
|
|
10635
|
+
import chalk51 from "chalk";
|
|
10636
|
+
var deleteCommand3 = new Command53().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
|
|
10578
10637
|
try {
|
|
10579
10638
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10580
|
-
console.error(
|
|
10639
|
+
console.error(chalk51.red(`\u2717 Invalid type "${type}"`));
|
|
10581
10640
|
console.log();
|
|
10582
10641
|
console.log("Valid types:");
|
|
10583
10642
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10584
|
-
console.log(` ${
|
|
10643
|
+
console.log(` ${chalk51.cyan(t)} - ${config.label}`);
|
|
10585
10644
|
}
|
|
10586
10645
|
process.exit(1);
|
|
10587
10646
|
}
|
|
10588
10647
|
await deleteModelProvider(type);
|
|
10589
|
-
console.log(
|
|
10648
|
+
console.log(chalk51.green(`\u2713 Model provider "${type}" deleted`));
|
|
10590
10649
|
} catch (error) {
|
|
10591
10650
|
if (error instanceof Error) {
|
|
10592
10651
|
if (error.message.includes("not found")) {
|
|
10593
|
-
console.error(
|
|
10652
|
+
console.error(chalk51.red(`\u2717 Model provider "${type}" not found`));
|
|
10594
10653
|
} else if (error.message.includes("Not authenticated")) {
|
|
10595
|
-
console.error(
|
|
10654
|
+
console.error(chalk51.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10596
10655
|
} else {
|
|
10597
|
-
console.error(
|
|
10656
|
+
console.error(chalk51.red(`\u2717 ${error.message}`));
|
|
10598
10657
|
}
|
|
10599
10658
|
} else {
|
|
10600
|
-
console.error(
|
|
10659
|
+
console.error(chalk51.red("\u2717 An unexpected error occurred"));
|
|
10601
10660
|
}
|
|
10602
10661
|
process.exit(1);
|
|
10603
10662
|
}
|
|
10604
10663
|
});
|
|
10605
10664
|
|
|
10606
10665
|
// src/commands/model-provider/set-default.ts
|
|
10607
|
-
import { Command as
|
|
10608
|
-
import
|
|
10609
|
-
var setDefaultCommand = new
|
|
10666
|
+
import { Command as Command54 } from "commander";
|
|
10667
|
+
import chalk52 from "chalk";
|
|
10668
|
+
var setDefaultCommand = new Command54().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) => {
|
|
10610
10669
|
try {
|
|
10611
10670
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
10612
|
-
console.error(
|
|
10671
|
+
console.error(chalk52.red(`\u2717 Invalid type "${type}"`));
|
|
10613
10672
|
console.log();
|
|
10614
10673
|
console.log("Valid types:");
|
|
10615
10674
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
10616
|
-
console.log(` ${
|
|
10675
|
+
console.log(` ${chalk52.cyan(t)} - ${config.label}`);
|
|
10617
10676
|
}
|
|
10618
10677
|
process.exit(1);
|
|
10619
10678
|
}
|
|
10620
10679
|
const provider = await setModelProviderDefault(type);
|
|
10621
10680
|
console.log(
|
|
10622
|
-
|
|
10681
|
+
chalk52.green(
|
|
10623
10682
|
`\u2713 Default for ${provider.framework} set to "${provider.type}"`
|
|
10624
10683
|
)
|
|
10625
10684
|
);
|
|
10626
10685
|
} catch (error) {
|
|
10627
10686
|
if (error instanceof Error) {
|
|
10628
10687
|
if (error.message.includes("not found")) {
|
|
10629
|
-
console.error(
|
|
10688
|
+
console.error(chalk52.red(`\u2717 Model provider "${type}" not found`));
|
|
10630
10689
|
} else if (error.message.includes("Not authenticated")) {
|
|
10631
|
-
console.error(
|
|
10690
|
+
console.error(chalk52.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10632
10691
|
} else {
|
|
10633
|
-
console.error(
|
|
10692
|
+
console.error(chalk52.red(`\u2717 ${error.message}`));
|
|
10634
10693
|
}
|
|
10635
10694
|
} else {
|
|
10636
|
-
console.error(
|
|
10695
|
+
console.error(chalk52.red("\u2717 An unexpected error occurred"));
|
|
10637
10696
|
}
|
|
10638
10697
|
process.exit(1);
|
|
10639
10698
|
}
|
|
10640
10699
|
});
|
|
10641
10700
|
|
|
10642
10701
|
// src/commands/model-provider/index.ts
|
|
10643
|
-
var modelProviderCommand = new
|
|
10702
|
+
var modelProviderCommand = new Command55().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand7).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
|
|
10644
10703
|
|
|
10645
|
-
// src/commands/onboard.ts
|
|
10646
|
-
import { Command as
|
|
10647
|
-
import
|
|
10704
|
+
// src/commands/onboard/index.ts
|
|
10705
|
+
import { Command as Command56 } from "commander";
|
|
10706
|
+
import chalk56 from "chalk";
|
|
10648
10707
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
10649
|
-
import { existsSync as
|
|
10650
|
-
import
|
|
10708
|
+
import { existsSync as existsSync11 } from "fs";
|
|
10709
|
+
import path16 from "path";
|
|
10651
10710
|
|
|
10652
10711
|
// src/lib/ui/welcome-box.ts
|
|
10653
|
-
import
|
|
10712
|
+
import chalk53 from "chalk";
|
|
10654
10713
|
function renderWelcomeBox(lines, width) {
|
|
10655
10714
|
const maxLineLength = Math.max(...lines.map((line) => line.length));
|
|
10656
10715
|
const boxWidth = width ?? maxLineLength + 4;
|
|
@@ -10658,15 +10717,15 @@ function renderWelcomeBox(lines, width) {
|
|
|
10658
10717
|
const horizontalLine = "\u2500".repeat(innerWidth);
|
|
10659
10718
|
const topBorder = `\u250C${horizontalLine}\u2510`;
|
|
10660
10719
|
const bottomBorder = `\u2514${horizontalLine}\u2518`;
|
|
10661
|
-
console.log(
|
|
10720
|
+
console.log(chalk53.cyan(topBorder));
|
|
10662
10721
|
for (const line of lines) {
|
|
10663
10722
|
const padding = innerWidth - line.length;
|
|
10664
10723
|
const leftPad = Math.floor(padding / 2);
|
|
10665
10724
|
const rightPad = padding - leftPad;
|
|
10666
10725
|
const centeredLine = " ".repeat(leftPad) + line + " ".repeat(rightPad);
|
|
10667
|
-
console.log(
|
|
10726
|
+
console.log(chalk53.cyan("\u2502") + centeredLine + chalk53.cyan("\u2502"));
|
|
10668
10727
|
}
|
|
10669
|
-
console.log(
|
|
10728
|
+
console.log(chalk53.cyan(bottomBorder));
|
|
10670
10729
|
}
|
|
10671
10730
|
function renderOnboardWelcome() {
|
|
10672
10731
|
renderWelcomeBox([
|
|
@@ -10679,7 +10738,7 @@ function renderOnboardWelcome() {
|
|
|
10679
10738
|
}
|
|
10680
10739
|
|
|
10681
10740
|
// src/lib/ui/progress-line.ts
|
|
10682
|
-
import
|
|
10741
|
+
import chalk54 from "chalk";
|
|
10683
10742
|
var STATUS_SYMBOLS = {
|
|
10684
10743
|
completed: "\u25CF",
|
|
10685
10744
|
"in-progress": "\u25D0",
|
|
@@ -10689,14 +10748,14 @@ var STATUS_SYMBOLS = {
|
|
|
10689
10748
|
function getStatusColor(status) {
|
|
10690
10749
|
switch (status) {
|
|
10691
10750
|
case "completed":
|
|
10692
|
-
return
|
|
10751
|
+
return chalk54.green;
|
|
10693
10752
|
case "in-progress":
|
|
10694
|
-
return
|
|
10753
|
+
return chalk54.yellow;
|
|
10695
10754
|
case "failed":
|
|
10696
|
-
return
|
|
10755
|
+
return chalk54.red;
|
|
10697
10756
|
case "pending":
|
|
10698
10757
|
default:
|
|
10699
|
-
return
|
|
10758
|
+
return chalk54.dim;
|
|
10700
10759
|
}
|
|
10701
10760
|
}
|
|
10702
10761
|
function renderProgressLine(steps) {
|
|
@@ -10707,7 +10766,7 @@ function renderProgressLine(steps) {
|
|
|
10707
10766
|
const color = getStatusColor(step.status);
|
|
10708
10767
|
console.log(color(`${symbol} ${step.label}`));
|
|
10709
10768
|
if (i < steps.length - 1) {
|
|
10710
|
-
console.log(
|
|
10769
|
+
console.log(chalk54.dim("\u2502"));
|
|
10711
10770
|
}
|
|
10712
10771
|
}
|
|
10713
10772
|
}
|
|
@@ -10862,7 +10921,7 @@ async function setupModelProvider(type, credential, options) {
|
|
|
10862
10921
|
|
|
10863
10922
|
// src/lib/domain/onboard/claude-setup.ts
|
|
10864
10923
|
import { spawn as spawn3 } from "child_process";
|
|
10865
|
-
import
|
|
10924
|
+
import chalk55 from "chalk";
|
|
10866
10925
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
10867
10926
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
10868
10927
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
@@ -10900,12 +10959,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
10900
10959
|
}
|
|
10901
10960
|
function handlePluginError(error, context) {
|
|
10902
10961
|
const displayContext = context ?? "Claude plugin";
|
|
10903
|
-
console.error(
|
|
10962
|
+
console.error(chalk55.red(`Failed to install ${displayContext}`));
|
|
10904
10963
|
if (error instanceof Error) {
|
|
10905
|
-
console.error(
|
|
10964
|
+
console.error(chalk55.red(error.message));
|
|
10906
10965
|
}
|
|
10907
10966
|
console.error(
|
|
10908
|
-
|
|
10967
|
+
chalk55.dim("Please ensure Claude CLI is installed and accessible.")
|
|
10909
10968
|
);
|
|
10910
10969
|
process.exit(1);
|
|
10911
10970
|
}
|
|
@@ -10960,7 +11019,7 @@ async function installVm0Plugin(scope = "user", cwd) {
|
|
|
10960
11019
|
};
|
|
10961
11020
|
}
|
|
10962
11021
|
|
|
10963
|
-
// src/commands/onboard.ts
|
|
11022
|
+
// src/commands/onboard/index.ts
|
|
10964
11023
|
var DEFAULT_AGENT_NAME = "my-vm0-agent";
|
|
10965
11024
|
async function handleAuthentication(ctx) {
|
|
10966
11025
|
ctx.updateProgress(0, "in-progress");
|
|
@@ -10970,34 +11029,34 @@ async function handleAuthentication(ctx) {
|
|
|
10970
11029
|
return;
|
|
10971
11030
|
}
|
|
10972
11031
|
if (!ctx.interactive) {
|
|
10973
|
-
console.error(
|
|
11032
|
+
console.error(chalk56.red("Error: Not authenticated"));
|
|
10974
11033
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
10975
11034
|
process.exit(1);
|
|
10976
11035
|
}
|
|
10977
|
-
console.log(
|
|
11036
|
+
console.log(chalk56.dim("Authentication required..."));
|
|
10978
11037
|
console.log();
|
|
10979
11038
|
await runAuthFlow({
|
|
10980
11039
|
onInitiating: () => {
|
|
10981
11040
|
console.log("Initiating authentication...");
|
|
10982
11041
|
},
|
|
10983
11042
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
10984
|
-
console.log(
|
|
10985
|
-
console.log(
|
|
11043
|
+
console.log(chalk56.green("\nDevice code generated"));
|
|
11044
|
+
console.log(chalk56.cyan(`
|
|
10986
11045
|
To authenticate, visit: ${url}`));
|
|
10987
|
-
console.log(`And enter this code: ${
|
|
11046
|
+
console.log(`And enter this code: ${chalk56.bold(code)}`);
|
|
10988
11047
|
console.log(`
|
|
10989
11048
|
The code expires in ${expiresIn} minutes.`);
|
|
10990
11049
|
console.log("\nWaiting for authentication...");
|
|
10991
11050
|
},
|
|
10992
11051
|
onPolling: () => {
|
|
10993
|
-
process.stdout.write(
|
|
11052
|
+
process.stdout.write(chalk56.dim("."));
|
|
10994
11053
|
},
|
|
10995
11054
|
onSuccess: () => {
|
|
10996
|
-
console.log(
|
|
11055
|
+
console.log(chalk56.green("\nAuthentication successful!"));
|
|
10997
11056
|
console.log("Your credentials have been saved.");
|
|
10998
11057
|
},
|
|
10999
11058
|
onError: (error) => {
|
|
11000
|
-
console.error(
|
|
11059
|
+
console.error(chalk56.red(`
|
|
11001
11060
|
${error.message}`));
|
|
11002
11061
|
process.exit(1);
|
|
11003
11062
|
}
|
|
@@ -11012,11 +11071,11 @@ async function handleModelProvider(ctx) {
|
|
|
11012
11071
|
return;
|
|
11013
11072
|
}
|
|
11014
11073
|
if (!ctx.interactive) {
|
|
11015
|
-
console.error(
|
|
11074
|
+
console.error(chalk56.red("Error: No model provider configured"));
|
|
11016
11075
|
console.error("Run 'vm0 model-provider setup' first");
|
|
11017
11076
|
process.exit(1);
|
|
11018
11077
|
}
|
|
11019
|
-
console.log(
|
|
11078
|
+
console.log(chalk56.dim("Model provider setup required..."));
|
|
11020
11079
|
console.log();
|
|
11021
11080
|
const choices = getProviderChoices();
|
|
11022
11081
|
const providerType = await promptSelect(
|
|
@@ -11033,19 +11092,19 @@ async function handleModelProvider(ctx) {
|
|
|
11033
11092
|
const selectedChoice = choices.find((c20) => c20.type === providerType);
|
|
11034
11093
|
if (selectedChoice) {
|
|
11035
11094
|
console.log();
|
|
11036
|
-
console.log(
|
|
11095
|
+
console.log(chalk56.dim(selectedChoice.helpText));
|
|
11037
11096
|
console.log();
|
|
11038
11097
|
}
|
|
11039
11098
|
const credential = await promptPassword(
|
|
11040
11099
|
`Enter your ${selectedChoice?.credentialLabel ?? "credential"}:`
|
|
11041
11100
|
);
|
|
11042
11101
|
if (!credential) {
|
|
11043
|
-
console.log(
|
|
11102
|
+
console.log(chalk56.dim("Cancelled"));
|
|
11044
11103
|
process.exit(0);
|
|
11045
11104
|
}
|
|
11046
11105
|
const result = await setupModelProvider(providerType, credential);
|
|
11047
11106
|
console.log(
|
|
11048
|
-
|
|
11107
|
+
chalk56.green(
|
|
11049
11108
|
`
|
|
11050
11109
|
\u2713 Model provider "${providerType}" ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}`
|
|
11051
11110
|
)
|
|
@@ -11073,22 +11132,22 @@ async function handleAgentCreation(ctx) {
|
|
|
11073
11132
|
}
|
|
11074
11133
|
if (!validateAgentName(agentName)) {
|
|
11075
11134
|
console.error(
|
|
11076
|
-
|
|
11135
|
+
chalk56.red(
|
|
11077
11136
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
11078
11137
|
)
|
|
11079
11138
|
);
|
|
11080
11139
|
process.exit(1);
|
|
11081
11140
|
}
|
|
11082
|
-
if (
|
|
11083
|
-
console.error(
|
|
11141
|
+
if (existsSync11(agentName)) {
|
|
11142
|
+
console.error(chalk56.red(`
|
|
11084
11143
|
\u2717 ${agentName}/ already exists`));
|
|
11085
11144
|
console.log();
|
|
11086
11145
|
console.log("Remove it first or choose a different name:");
|
|
11087
|
-
console.log(
|
|
11146
|
+
console.log(chalk56.cyan(` rm -rf ${agentName}`));
|
|
11088
11147
|
process.exit(1);
|
|
11089
11148
|
}
|
|
11090
11149
|
await mkdir7(agentName, { recursive: true });
|
|
11091
|
-
console.log(
|
|
11150
|
+
console.log(chalk56.green(`\u2713 Created ${agentName}/`));
|
|
11092
11151
|
ctx.updateProgress(2, "completed");
|
|
11093
11152
|
return agentName;
|
|
11094
11153
|
}
|
|
@@ -11104,16 +11163,16 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11104
11163
|
shouldInstall = confirmed ?? true;
|
|
11105
11164
|
}
|
|
11106
11165
|
if (!shouldInstall) {
|
|
11107
|
-
console.log(
|
|
11166
|
+
console.log(chalk56.dim("Skipped plugin installation"));
|
|
11108
11167
|
ctx.updateProgress(3, "completed");
|
|
11109
11168
|
return;
|
|
11110
11169
|
}
|
|
11111
11170
|
const scope = "project";
|
|
11112
11171
|
try {
|
|
11113
|
-
const agentDir =
|
|
11172
|
+
const agentDir = path16.resolve(process.cwd(), agentName);
|
|
11114
11173
|
const result = await installVm0Plugin(scope, agentDir);
|
|
11115
11174
|
console.log(
|
|
11116
|
-
|
|
11175
|
+
chalk56.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11117
11176
|
);
|
|
11118
11177
|
} catch (error) {
|
|
11119
11178
|
handlePluginError(error);
|
|
@@ -11122,14 +11181,14 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11122
11181
|
}
|
|
11123
11182
|
function printNextSteps(agentName) {
|
|
11124
11183
|
console.log();
|
|
11125
|
-
console.log(
|
|
11184
|
+
console.log(chalk56.bold("Next step:"));
|
|
11126
11185
|
console.log();
|
|
11127
11186
|
console.log(
|
|
11128
|
-
` ${
|
|
11187
|
+
` ${chalk56.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`)}`
|
|
11129
11188
|
);
|
|
11130
11189
|
console.log();
|
|
11131
11190
|
}
|
|
11132
|
-
var onboardCommand = new
|
|
11191
|
+
var onboardCommand = new Command56().name("onboard").description("Guided setup for new VM0 users").option("-y, --yes", "Skip confirmation prompts").option("--name <name>", `Agent name (default: ${DEFAULT_AGENT_NAME})`).action(async (options) => {
|
|
11133
11192
|
const interactive = isInteractive();
|
|
11134
11193
|
if (interactive) {
|
|
11135
11194
|
console.log();
|
|
@@ -11160,16 +11219,16 @@ var onboardCommand = new Command48().name("onboard").description("Guided setup f
|
|
|
11160
11219
|
printNextSteps(agentName);
|
|
11161
11220
|
});
|
|
11162
11221
|
|
|
11163
|
-
// src/commands/setup-claude.ts
|
|
11164
|
-
import { Command as
|
|
11165
|
-
import
|
|
11166
|
-
var setupClaudeCommand = new
|
|
11167
|
-
console.log(
|
|
11222
|
+
// src/commands/setup-claude/index.ts
|
|
11223
|
+
import { Command as Command57 } from "commander";
|
|
11224
|
+
import chalk57 from "chalk";
|
|
11225
|
+
var setupClaudeCommand = new Command57().name("setup-claude").description("Install VM0 Claude Plugin").option("--agent-dir <dir>", "Agent directory to run install in").option("--scope <scope>", "Installation scope (user or project)", "project").action(async (options) => {
|
|
11226
|
+
console.log(chalk57.dim("Installing VM0 Claude Plugin..."));
|
|
11168
11227
|
const scope = options.scope === "user" ? "user" : "project";
|
|
11169
11228
|
try {
|
|
11170
11229
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
11171
11230
|
console.log(
|
|
11172
|
-
|
|
11231
|
+
chalk57.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11173
11232
|
);
|
|
11174
11233
|
} catch (error) {
|
|
11175
11234
|
handlePluginError(error);
|
|
@@ -11178,40 +11237,23 @@ var setupClaudeCommand = new Command49().name("setup-claude").description("Insta
|
|
|
11178
11237
|
console.log("Next step:");
|
|
11179
11238
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
11180
11239
|
console.log(
|
|
11181
|
-
|
|
11240
|
+
chalk57.cyan(
|
|
11182
11241
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
11183
11242
|
)
|
|
11184
11243
|
);
|
|
11185
11244
|
});
|
|
11186
11245
|
|
|
11187
11246
|
// src/index.ts
|
|
11188
|
-
var program = new
|
|
11189
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.4.
|
|
11190
|
-
program.
|
|
11191
|
-
|
|
11192
|
-
console.log(`Node Version: ${process.version}`);
|
|
11193
|
-
console.log(`Platform: ${process.platform}`);
|
|
11194
|
-
console.log(`Architecture: ${process.arch}`);
|
|
11195
|
-
const apiUrl = await getApiUrl();
|
|
11196
|
-
console.log(`API Host: ${apiUrl}`);
|
|
11197
|
-
});
|
|
11198
|
-
var authCommand = program.command("auth").description("Authenticate vm0");
|
|
11199
|
-
authCommand.addCommand(loginCommand);
|
|
11200
|
-
authCommand.command("logout").description("Log out of VM0").action(async () => {
|
|
11201
|
-
await logout();
|
|
11202
|
-
});
|
|
11203
|
-
authCommand.command("status").description("Show current authentication status").action(async () => {
|
|
11204
|
-
await checkAuthStatus();
|
|
11205
|
-
});
|
|
11206
|
-
authCommand.command("setup-token").description("Output auth token for CI/CD environments").action(async () => {
|
|
11207
|
-
await setupToken();
|
|
11208
|
-
});
|
|
11247
|
+
var program = new Command58();
|
|
11248
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.4.1");
|
|
11249
|
+
program.addCommand(authCommand);
|
|
11250
|
+
program.addCommand(infoCommand);
|
|
11209
11251
|
program.addCommand(composeCommand);
|
|
11210
11252
|
program.addCommand(runCommand);
|
|
11211
11253
|
program.addCommand(volumeCommand);
|
|
11212
11254
|
program.addCommand(artifactCommand);
|
|
11213
11255
|
program.addCommand(cookCommand);
|
|
11214
|
-
program.addCommand(
|
|
11256
|
+
program.addCommand(logsCommand2);
|
|
11215
11257
|
program.addCommand(scopeCommand);
|
|
11216
11258
|
program.addCommand(agentCommand);
|
|
11217
11259
|
program.addCommand(initCommand3);
|