@vm0/cli 4.8.1 → 4.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +248 -163
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
 
8
8
  // src/index.ts
9
9
  import { Command as Command17 } from "commander";
10
- import chalk16 from "chalk";
10
+ import chalk17 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -1200,10 +1200,13 @@ var EventRenderer = class {
1200
1200
  * Render run failed state
1201
1201
  * Note: This is run lifecycle status, not an event
1202
1202
  */
1203
- static renderRunFailed(error43) {
1203
+ static renderRunFailed(error43, runId) {
1204
1204
  console.log("");
1205
1205
  console.log(chalk3.red("\u2717 Run failed"));
1206
1206
  console.log(` Error: ${chalk3.red(error43 || "Unknown error")}`);
1207
+ console.log(
1208
+ chalk3.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
1209
+ );
1207
1210
  }
1208
1211
  static renderInit(event, prefix, suffix) {
1209
1212
  console.log(
@@ -14596,11 +14599,14 @@ async function pollEvents(runId, options) {
14596
14599
  };
14597
14600
  } else if (runStatus === "failed") {
14598
14601
  complete = true;
14599
- EventRenderer.renderRunFailed(response.run.error);
14602
+ EventRenderer.renderRunFailed(response.run.error, runId);
14600
14603
  result = { succeeded: false, runId };
14601
14604
  } else if (runStatus === "timeout") {
14602
14605
  complete = true;
14603
14606
  console.error(chalk4.red("\n\u2717 Run timed out"));
14607
+ console.error(
14608
+ chalk4.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
14609
+ );
14604
14610
  result = { succeeded: false, runId };
14605
14611
  }
14606
14612
  if (!complete) {
@@ -15303,11 +15309,25 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15303
15309
 
15304
15310
  // src/commands/volume/pull.ts
15305
15311
  import { Command as Command5 } from "commander";
15306
- import chalk7 from "chalk";
15312
+ import chalk8 from "chalk";
15307
15313
  import path8 from "path";
15308
15314
  import * as fs6 from "fs";
15309
15315
  import * as os4 from "os";
15310
15316
  import * as tar4 from "tar";
15317
+
15318
+ // src/lib/pull-utils.ts
15319
+ import chalk7 from "chalk";
15320
+ async function handleEmptyStorageResponse(cwd) {
15321
+ console.log(chalk7.gray("Syncing local files..."));
15322
+ const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
15323
+ if (removedCount > 0) {
15324
+ console.log(chalk7.green(`\u2713 Removed ${removedCount} files not in remote`));
15325
+ }
15326
+ console.log(chalk7.green("\u2713 Synced (0 files)"));
15327
+ return { removedCount };
15328
+ }
15329
+
15330
+ // src/commands/volume/pull.ts
15311
15331
  function formatBytes2(bytes) {
15312
15332
  if (bytes === 0) return "0 B";
15313
15333
  const k = 1024;
@@ -15320,18 +15340,18 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15320
15340
  const cwd = process.cwd();
15321
15341
  const config2 = await readStorageConfig(cwd);
15322
15342
  if (!config2) {
15323
- console.error(chalk7.red("\u2717 No volume initialized in this directory"));
15324
- console.error(chalk7.gray(" Run: vm0 volume init"));
15343
+ console.error(chalk8.red("\u2717 No volume initialized in this directory"));
15344
+ console.error(chalk8.gray(" Run: vm0 volume init"));
15325
15345
  process.exit(1);
15326
15346
  }
15327
15347
  if (versionId) {
15328
15348
  console.log(
15329
- chalk7.cyan(`Pulling volume: ${config2.name} (version: ${versionId})`)
15349
+ chalk8.cyan(`Pulling volume: ${config2.name} (version: ${versionId})`)
15330
15350
  );
15331
15351
  } else {
15332
- console.log(chalk7.cyan(`Pulling volume: ${config2.name}`));
15352
+ console.log(chalk8.cyan(`Pulling volume: ${config2.name}`));
15333
15353
  }
15334
- console.log(chalk7.gray("Downloading..."));
15354
+ console.log(chalk8.gray("Downloading..."));
15335
15355
  let url2 = `/api/storages?name=${encodeURIComponent(config2.name)}&type=volume`;
15336
15356
  if (versionId) {
15337
15357
  url2 += `&version=${encodeURIComponent(versionId)}`;
@@ -15339,14 +15359,14 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15339
15359
  const response = await apiClient.get(url2);
15340
15360
  if (!response.ok) {
15341
15361
  if (response.status === 404) {
15342
- console.error(chalk7.red(`\u2717 Volume "${config2.name}" not found`));
15362
+ console.error(chalk8.red(`\u2717 Volume "${config2.name}" not found`));
15343
15363
  console.error(
15344
- chalk7.gray(
15364
+ chalk8.gray(
15345
15365
  " Make sure the volume name is correct in .vm0/storage.yaml"
15346
15366
  )
15347
15367
  );
15348
15368
  console.error(
15349
- chalk7.gray(" Or push the volume first with: vm0 volume push")
15369
+ chalk8.gray(" Or push the volume first with: vm0 volume push")
15350
15370
  );
15351
15371
  } else {
15352
15372
  const error43 = await response.json();
@@ -15354,13 +15374,17 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15354
15374
  }
15355
15375
  process.exit(1);
15356
15376
  }
15377
+ if (response.status === 204) {
15378
+ await handleEmptyStorageResponse(cwd);
15379
+ return;
15380
+ }
15357
15381
  const arrayBuffer = await response.arrayBuffer();
15358
15382
  const tarBuffer = Buffer.from(arrayBuffer);
15359
- console.log(chalk7.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
15383
+ console.log(chalk8.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
15360
15384
  const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
15361
15385
  const tarPath = path8.join(tmpDir, "volume.tar.gz");
15362
15386
  await fs6.promises.writeFile(tarPath, tarBuffer);
15363
- console.log(chalk7.gray("Syncing local files..."));
15387
+ console.log(chalk8.gray("Syncing local files..."));
15364
15388
  const remoteFiles = await listTarFiles(tarPath);
15365
15389
  const remoteFilesSet = new Set(
15366
15390
  remoteFiles.map((f) => f.replace(/\\/g, "/"))
@@ -15368,10 +15392,10 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15368
15392
  const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
15369
15393
  if (removedCount > 0) {
15370
15394
  console.log(
15371
- chalk7.green(`\u2713 Removed ${removedCount} files not in remote`)
15395
+ chalk8.green(`\u2713 Removed ${removedCount} files not in remote`)
15372
15396
  );
15373
15397
  }
15374
- console.log(chalk7.gray("Extracting files..."));
15398
+ console.log(chalk8.gray("Extracting files..."));
15375
15399
  await tar4.extract({
15376
15400
  file: tarPath,
15377
15401
  cwd,
@@ -15379,11 +15403,11 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15379
15403
  });
15380
15404
  await fs6.promises.unlink(tarPath);
15381
15405
  await fs6.promises.rmdir(tmpDir);
15382
- console.log(chalk7.green(`\u2713 Extracted ${remoteFiles.length} files`));
15406
+ console.log(chalk8.green(`\u2713 Extracted ${remoteFiles.length} files`));
15383
15407
  } catch (error43) {
15384
- console.error(chalk7.red("\u2717 Pull failed"));
15408
+ console.error(chalk8.red("\u2717 Pull failed"));
15385
15409
  if (error43 instanceof Error) {
15386
- console.error(chalk7.gray(` ${error43.message}`));
15410
+ console.error(chalk8.gray(` ${error43.message}`));
15387
15411
  }
15388
15412
  process.exit(1);
15389
15413
  }
@@ -15397,7 +15421,7 @@ import { Command as Command10 } from "commander";
15397
15421
 
15398
15422
  // src/commands/artifact/init.ts
15399
15423
  import { Command as Command7 } from "commander";
15400
- import chalk8 from "chalk";
15424
+ import chalk9 from "chalk";
15401
15425
  import path9 from "path";
15402
15426
  var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
15403
15427
  try {
@@ -15407,51 +15431,51 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15407
15431
  if (existingConfig) {
15408
15432
  if (existingConfig.type === "artifact") {
15409
15433
  console.log(
15410
- chalk8.yellow(
15434
+ chalk9.yellow(
15411
15435
  `Artifact already initialized: ${existingConfig.name}`
15412
15436
  )
15413
15437
  );
15414
15438
  } else {
15415
15439
  console.log(
15416
- chalk8.yellow(
15440
+ chalk9.yellow(
15417
15441
  `Directory already initialized as volume: ${existingConfig.name}`
15418
15442
  )
15419
15443
  );
15420
15444
  console.log(
15421
- chalk8.gray(
15445
+ chalk9.gray(
15422
15446
  " To change type, delete .vm0/storage.yaml and reinitialize"
15423
15447
  )
15424
15448
  );
15425
15449
  }
15426
15450
  console.log(
15427
- chalk8.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15451
+ chalk9.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15428
15452
  );
15429
15453
  return;
15430
15454
  }
15431
15455
  const artifactName = dirName;
15432
15456
  if (!isValidStorageName(artifactName)) {
15433
- console.error(chalk8.red(`\u2717 Invalid artifact name: "${dirName}"`));
15457
+ console.error(chalk9.red(`\u2717 Invalid artifact name: "${dirName}"`));
15434
15458
  console.error(
15435
- chalk8.gray(
15459
+ chalk9.gray(
15436
15460
  " Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
15437
15461
  )
15438
15462
  );
15439
15463
  console.error(
15440
- chalk8.gray(" Example: my-project, user-workspace, code-artifact")
15464
+ chalk9.gray(" Example: my-project, user-workspace, code-artifact")
15441
15465
  );
15442
15466
  process.exit(1);
15443
15467
  }
15444
15468
  await writeStorageConfig(artifactName, cwd, "artifact");
15445
- console.log(chalk8.green(`\u2713 Initialized artifact: ${artifactName}`));
15469
+ console.log(chalk9.green(`\u2713 Initialized artifact: ${artifactName}`));
15446
15470
  console.log(
15447
- chalk8.gray(
15471
+ chalk9.gray(
15448
15472
  `\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
15449
15473
  )
15450
15474
  );
15451
15475
  } catch (error43) {
15452
- console.error(chalk8.red("\u2717 Failed to initialize artifact"));
15476
+ console.error(chalk9.red("\u2717 Failed to initialize artifact"));
15453
15477
  if (error43 instanceof Error) {
15454
- console.error(chalk8.gray(` ${error43.message}`));
15478
+ console.error(chalk9.gray(` ${error43.message}`));
15455
15479
  }
15456
15480
  process.exit(1);
15457
15481
  }
@@ -15459,7 +15483,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15459
15483
 
15460
15484
  // src/commands/artifact/push.ts
15461
15485
  import { Command as Command8 } from "commander";
15462
- import chalk9 from "chalk";
15486
+ import chalk10 from "chalk";
15463
15487
  import path10 from "path";
15464
15488
  import * as fs7 from "fs";
15465
15489
  import * as os5 from "os";
@@ -15497,21 +15521,21 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15497
15521
  const cwd = process.cwd();
15498
15522
  const config2 = await readStorageConfig(cwd);
15499
15523
  if (!config2) {
15500
- console.error(chalk9.red("\u2717 No artifact initialized in this directory"));
15501
- console.error(chalk9.gray(" Run: vm0 artifact init"));
15524
+ console.error(chalk10.red("\u2717 No artifact initialized in this directory"));
15525
+ console.error(chalk10.gray(" Run: vm0 artifact init"));
15502
15526
  process.exit(1);
15503
15527
  }
15504
15528
  if (config2.type !== "artifact") {
15505
15529
  console.error(
15506
- chalk9.red(
15530
+ chalk10.red(
15507
15531
  `\u2717 This directory is initialized as a volume, not an artifact`
15508
15532
  )
15509
15533
  );
15510
- console.error(chalk9.gray(" Use: vm0 volume push"));
15534
+ console.error(chalk10.gray(" Use: vm0 volume push"));
15511
15535
  process.exit(1);
15512
15536
  }
15513
- console.log(chalk9.cyan(`Pushing artifact: ${config2.name}`));
15514
- console.log(chalk9.gray("Collecting files..."));
15537
+ console.log(chalk10.cyan(`Pushing artifact: ${config2.name}`));
15538
+ console.log(chalk10.gray("Collecting files..."));
15515
15539
  const files = await getAllFiles2(cwd);
15516
15540
  let totalSize = 0;
15517
15541
  for (const file2 of files) {
@@ -15519,13 +15543,13 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15519
15543
  totalSize += stats.size;
15520
15544
  }
15521
15545
  if (files.length === 0) {
15522
- console.log(chalk9.gray("No files found (empty artifact)"));
15546
+ console.log(chalk10.gray("No files found (empty artifact)"));
15523
15547
  } else {
15524
15548
  console.log(
15525
- chalk9.gray(`Found ${files.length} files (${formatBytes3(totalSize)})`)
15549
+ chalk10.gray(`Found ${files.length} files (${formatBytes3(totalSize)})`)
15526
15550
  );
15527
15551
  }
15528
- console.log(chalk9.gray("Compressing files..."));
15552
+ console.log(chalk10.gray("Compressing files..."));
15529
15553
  const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
15530
15554
  const tarPath = path10.join(tmpDir, "artifact.tar.gz");
15531
15555
  const relativePaths = files.map((file2) => path10.relative(cwd, file2));
@@ -15553,9 +15577,9 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15553
15577
  await fs7.promises.unlink(tarPath);
15554
15578
  await fs7.promises.rmdir(tmpDir);
15555
15579
  console.log(
15556
- chalk9.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
15580
+ chalk10.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
15557
15581
  );
15558
- console.log(chalk9.gray("Uploading..."));
15582
+ console.log(chalk10.gray("Uploading..."));
15559
15583
  const formData = new FormData();
15560
15584
  formData.append("name", config2.name);
15561
15585
  formData.append("type", "artifact");
@@ -15577,17 +15601,17 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15577
15601
  const result = await response.json();
15578
15602
  const shortVersion = result.versionId.slice(0, 8);
15579
15603
  if (result.deduplicated) {
15580
- console.log(chalk9.green("\u2713 Content unchanged (deduplicated)"));
15604
+ console.log(chalk10.green("\u2713 Content unchanged (deduplicated)"));
15581
15605
  } else {
15582
- console.log(chalk9.green("\u2713 Upload complete"));
15606
+ console.log(chalk10.green("\u2713 Upload complete"));
15583
15607
  }
15584
- console.log(chalk9.gray(` Version: ${shortVersion}`));
15585
- console.log(chalk9.gray(` Files: ${result.fileCount.toLocaleString()}`));
15586
- console.log(chalk9.gray(` Size: ${formatBytes3(result.size)}`));
15608
+ console.log(chalk10.gray(` Version: ${shortVersion}`));
15609
+ console.log(chalk10.gray(` Files: ${result.fileCount.toLocaleString()}`));
15610
+ console.log(chalk10.gray(` Size: ${formatBytes3(result.size)}`));
15587
15611
  } catch (error43) {
15588
- console.error(chalk9.red("\u2717 Push failed"));
15612
+ console.error(chalk10.red("\u2717 Push failed"));
15589
15613
  if (error43 instanceof Error) {
15590
- console.error(chalk9.gray(` ${error43.message}`));
15614
+ console.error(chalk10.gray(` ${error43.message}`));
15591
15615
  }
15592
15616
  process.exit(1);
15593
15617
  }
@@ -15595,7 +15619,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15595
15619
 
15596
15620
  // src/commands/artifact/pull.ts
15597
15621
  import { Command as Command9 } from "commander";
15598
- import chalk10 from "chalk";
15622
+ import chalk11 from "chalk";
15599
15623
  import path11 from "path";
15600
15624
  import * as fs8 from "fs";
15601
15625
  import * as os6 from "os";
@@ -15612,29 +15636,29 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15612
15636
  const cwd = process.cwd();
15613
15637
  const config2 = await readStorageConfig(cwd);
15614
15638
  if (!config2) {
15615
- console.error(chalk10.red("\u2717 No artifact initialized in this directory"));
15616
- console.error(chalk10.gray(" Run: vm0 artifact init"));
15639
+ console.error(chalk11.red("\u2717 No artifact initialized in this directory"));
15640
+ console.error(chalk11.gray(" Run: vm0 artifact init"));
15617
15641
  process.exit(1);
15618
15642
  }
15619
15643
  if (config2.type !== "artifact") {
15620
15644
  console.error(
15621
- chalk10.red(
15645
+ chalk11.red(
15622
15646
  `\u2717 This directory is initialized as a volume, not an artifact`
15623
15647
  )
15624
15648
  );
15625
- console.error(chalk10.gray(" Use: vm0 volume pull"));
15649
+ console.error(chalk11.gray(" Use: vm0 volume pull"));
15626
15650
  process.exit(1);
15627
15651
  }
15628
15652
  if (versionId) {
15629
15653
  console.log(
15630
- chalk10.cyan(
15654
+ chalk11.cyan(
15631
15655
  `Pulling artifact: ${config2.name} (version: ${versionId})`
15632
15656
  )
15633
15657
  );
15634
15658
  } else {
15635
- console.log(chalk10.cyan(`Pulling artifact: ${config2.name}`));
15659
+ console.log(chalk11.cyan(`Pulling artifact: ${config2.name}`));
15636
15660
  }
15637
- console.log(chalk10.gray("Downloading..."));
15661
+ console.log(chalk11.gray("Downloading..."));
15638
15662
  let url2 = `/api/storages?name=${encodeURIComponent(config2.name)}&type=artifact`;
15639
15663
  if (versionId) {
15640
15664
  url2 += `&version=${encodeURIComponent(versionId)}`;
@@ -15642,14 +15666,14 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15642
15666
  const response = await apiClient.get(url2);
15643
15667
  if (!response.ok) {
15644
15668
  if (response.status === 404) {
15645
- console.error(chalk10.red(`\u2717 Artifact "${config2.name}" not found`));
15669
+ console.error(chalk11.red(`\u2717 Artifact "${config2.name}" not found`));
15646
15670
  console.error(
15647
- chalk10.gray(
15671
+ chalk11.gray(
15648
15672
  " Make sure the artifact name is correct in .vm0/storage.yaml"
15649
15673
  )
15650
15674
  );
15651
15675
  console.error(
15652
- chalk10.gray(" Or push the artifact first with: vm0 artifact push")
15676
+ chalk11.gray(" Or push the artifact first with: vm0 artifact push")
15653
15677
  );
15654
15678
  } else {
15655
15679
  const error43 = await response.json();
@@ -15657,13 +15681,17 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15657
15681
  }
15658
15682
  process.exit(1);
15659
15683
  }
15684
+ if (response.status === 204) {
15685
+ await handleEmptyStorageResponse(cwd);
15686
+ return;
15687
+ }
15660
15688
  const arrayBuffer = await response.arrayBuffer();
15661
15689
  const tarBuffer = Buffer.from(arrayBuffer);
15662
- console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
15690
+ console.log(chalk11.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
15663
15691
  const tmpDir = fs8.mkdtempSync(path11.join(os6.tmpdir(), "vm0-"));
15664
15692
  const tarPath = path11.join(tmpDir, "artifact.tar.gz");
15665
15693
  await fs8.promises.writeFile(tarPath, tarBuffer);
15666
- console.log(chalk10.gray("Syncing local files..."));
15694
+ console.log(chalk11.gray("Syncing local files..."));
15667
15695
  const remoteFiles = await listTarFiles(tarPath);
15668
15696
  const remoteFilesSet = new Set(
15669
15697
  remoteFiles.map((f) => f.replace(/\\/g, "/"))
@@ -15671,10 +15699,10 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15671
15699
  const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
15672
15700
  if (removedCount > 0) {
15673
15701
  console.log(
15674
- chalk10.green(`\u2713 Removed ${removedCount} files not in remote`)
15702
+ chalk11.green(`\u2713 Removed ${removedCount} files not in remote`)
15675
15703
  );
15676
15704
  }
15677
- console.log(chalk10.gray("Extracting files..."));
15705
+ console.log(chalk11.gray("Extracting files..."));
15678
15706
  await tar6.extract({
15679
15707
  file: tarPath,
15680
15708
  cwd,
@@ -15682,11 +15710,11 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15682
15710
  });
15683
15711
  await fs8.promises.unlink(tarPath);
15684
15712
  await fs8.promises.rmdir(tmpDir);
15685
- console.log(chalk10.green(`\u2713 Extracted ${remoteFiles.length} files`));
15713
+ console.log(chalk11.green(`\u2713 Extracted ${remoteFiles.length} files`));
15686
15714
  } catch (error43) {
15687
- console.error(chalk10.red("\u2717 Pull failed"));
15715
+ console.error(chalk11.red("\u2717 Pull failed"));
15688
15716
  if (error43 instanceof Error) {
15689
- console.error(chalk10.gray(` ${error43.message}`));
15717
+ console.error(chalk11.gray(` ${error43.message}`));
15690
15718
  }
15691
15719
  process.exit(1);
15692
15720
  }
@@ -15697,12 +15725,13 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
15697
15725
 
15698
15726
  // src/commands/cook.ts
15699
15727
  import { Command as Command11 } from "commander";
15700
- import chalk11 from "chalk";
15701
- import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
15702
- import { existsSync as existsSync5 } from "fs";
15728
+ import chalk12 from "chalk";
15729
+ import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
15730
+ import { existsSync as existsSync5, readFileSync } from "fs";
15703
15731
  import path12 from "path";
15704
15732
  import { spawn } from "child_process";
15705
15733
  import { parse as parseYaml3 } from "yaml";
15734
+ import { config as dotenvConfig2 } from "dotenv";
15706
15735
  var CONFIG_FILE3 = "vm0.yaml";
15707
15736
  var ARTIFACT_DIR = "artifact";
15708
15737
  function execVm0Command(args, options = {}) {
@@ -15780,11 +15809,49 @@ function parseArtifactVersionFromCompletion(output, artifactName) {
15780
15809
  function escapeRegExp(str) {
15781
15810
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15782
15811
  }
15812
+ function extractRequiredVarNames(config2) {
15813
+ const refs = extractVariableReferences(config2);
15814
+ const grouped = groupVariablesBySource(refs);
15815
+ const varNames = grouped.vars.map((r) => r.name);
15816
+ const secretNames = grouped.secrets.map((r) => r.name);
15817
+ return [.../* @__PURE__ */ new Set([...varNames, ...secretNames])];
15818
+ }
15819
+ function checkMissingVariables(varNames, envFilePath) {
15820
+ let dotenvValues = {};
15821
+ if (existsSync5(envFilePath)) {
15822
+ const result = dotenvConfig2({ path: envFilePath });
15823
+ if (result.parsed) {
15824
+ dotenvValues = result.parsed;
15825
+ }
15826
+ }
15827
+ const missing = [];
15828
+ for (const name of varNames) {
15829
+ const inEnv = process.env[name] !== void 0;
15830
+ const inDotenv = dotenvValues[name] !== void 0;
15831
+ if (!inEnv && !inDotenv) {
15832
+ missing.push(name);
15833
+ }
15834
+ }
15835
+ return missing;
15836
+ }
15837
+ async function generateEnvPlaceholders(missingVars, envFilePath) {
15838
+ const placeholders = missingVars.map((name) => `${name}=`).join("\n");
15839
+ if (existsSync5(envFilePath)) {
15840
+ const existingContent = readFileSync(envFilePath, "utf8");
15841
+ const needsNewline = existingContent.length > 0 && !existingContent.endsWith("\n");
15842
+ const prefix = needsNewline ? "\n" : "";
15843
+ await appendFile(envFilePath, `${prefix}${placeholders}
15844
+ `);
15845
+ } else {
15846
+ await writeFile5(envFilePath, `${placeholders}
15847
+ `);
15848
+ }
15849
+ }
15783
15850
  var cookCommand = new Command11().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
15784
15851
  const cwd = process.cwd();
15785
- console.log(chalk11.blue(`Reading config: ${CONFIG_FILE3}`));
15852
+ console.log(chalk12.blue(`Reading config: ${CONFIG_FILE3}`));
15786
15853
  if (!existsSync5(CONFIG_FILE3)) {
15787
- console.error(chalk11.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15854
+ console.error(chalk12.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15788
15855
  process.exit(1);
15789
15856
  }
15790
15857
  let config2;
@@ -15792,32 +15859,50 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15792
15859
  const content = await readFile5(CONFIG_FILE3, "utf8");
15793
15860
  config2 = parseYaml3(content);
15794
15861
  } catch (error43) {
15795
- console.error(chalk11.red("\u2717 Invalid YAML format"));
15862
+ console.error(chalk12.red("\u2717 Invalid YAML format"));
15796
15863
  if (error43 instanceof Error) {
15797
- console.error(chalk11.gray(` ${error43.message}`));
15864
+ console.error(chalk12.gray(` ${error43.message}`));
15798
15865
  }
15799
15866
  process.exit(1);
15800
15867
  }
15801
15868
  const validation = validateAgentCompose(config2);
15802
15869
  if (!validation.valid) {
15803
- console.error(chalk11.red(`\u2717 ${validation.error}`));
15870
+ console.error(chalk12.red(`\u2717 ${validation.error}`));
15804
15871
  process.exit(1);
15805
15872
  }
15806
15873
  const agentNames = Object.keys(config2.agents);
15807
15874
  const agentName = agentNames[0];
15808
15875
  const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
15809
15876
  console.log(
15810
- chalk11.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15877
+ chalk12.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15811
15878
  );
15879
+ const requiredVarNames = extractRequiredVarNames(config2);
15880
+ if (requiredVarNames.length > 0) {
15881
+ const envFilePath = path12.join(cwd, ".env");
15882
+ const missingVars = checkMissingVariables(requiredVarNames, envFilePath);
15883
+ if (missingVars.length > 0) {
15884
+ await generateEnvPlaceholders(missingVars, envFilePath);
15885
+ console.log();
15886
+ console.log(
15887
+ chalk12.yellow(
15888
+ `\u26A0 Missing environment variables. Please fill in values in .env file:`
15889
+ )
15890
+ );
15891
+ for (const varName of missingVars) {
15892
+ console.log(chalk12.yellow(` ${varName}`));
15893
+ }
15894
+ process.exit(1);
15895
+ }
15896
+ }
15812
15897
  if (config2.volumes && Object.keys(config2.volumes).length > 0) {
15813
15898
  console.log();
15814
- console.log(chalk11.blue("Processing volumes..."));
15899
+ console.log(chalk12.blue("Processing volumes..."));
15815
15900
  for (const volumeConfig of Object.values(config2.volumes)) {
15816
15901
  const volumeDir = path12.join(cwd, volumeConfig.name);
15817
- console.log(chalk11.gray(` ${volumeConfig.name}/`));
15902
+ console.log(chalk12.gray(` ${volumeConfig.name}/`));
15818
15903
  if (!existsSync5(volumeDir)) {
15819
15904
  console.error(
15820
- chalk11.red(
15905
+ chalk12.red(
15821
15906
  ` \u2717 Directory not found. Create the directory and add files first.`
15822
15907
  )
15823
15908
  );
@@ -15830,30 +15915,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15830
15915
  cwd: volumeDir,
15831
15916
  silent: true
15832
15917
  });
15833
- console.log(chalk11.green(` \u2713 Initialized`));
15918
+ console.log(chalk12.green(` \u2713 Initialized`));
15834
15919
  }
15835
15920
  await execVm0Command(["volume", "push"], {
15836
15921
  cwd: volumeDir,
15837
15922
  silent: true
15838
15923
  });
15839
- console.log(chalk11.green(` \u2713 Pushed`));
15924
+ console.log(chalk12.green(` \u2713 Pushed`));
15840
15925
  } catch (error43) {
15841
- console.error(chalk11.red(` \u2717 Failed`));
15926
+ console.error(chalk12.red(` \u2717 Failed`));
15842
15927
  if (error43 instanceof Error) {
15843
- console.error(chalk11.gray(` ${error43.message}`));
15928
+ console.error(chalk12.gray(` ${error43.message}`));
15844
15929
  }
15845
15930
  process.exit(1);
15846
15931
  }
15847
15932
  }
15848
15933
  }
15849
15934
  console.log();
15850
- console.log(chalk11.blue("Processing artifact..."));
15935
+ console.log(chalk12.blue("Processing artifact..."));
15851
15936
  const artifactDir = path12.join(cwd, ARTIFACT_DIR);
15852
- console.log(chalk11.gray(` ${ARTIFACT_DIR}/`));
15937
+ console.log(chalk12.gray(` ${ARTIFACT_DIR}/`));
15853
15938
  try {
15854
15939
  if (!existsSync5(artifactDir)) {
15855
15940
  await mkdir5(artifactDir, { recursive: true });
15856
- console.log(chalk11.green(` \u2713 Created directory`));
15941
+ console.log(chalk12.green(` \u2713 Created directory`));
15857
15942
  }
15858
15943
  const existingConfig = await readStorageConfig(artifactDir);
15859
15944
  if (!existingConfig) {
@@ -15861,38 +15946,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15861
15946
  cwd: artifactDir,
15862
15947
  silent: true
15863
15948
  });
15864
- console.log(chalk11.green(` \u2713 Initialized`));
15949
+ console.log(chalk12.green(` \u2713 Initialized`));
15865
15950
  }
15866
15951
  await execVm0Command(["artifact", "push"], {
15867
15952
  cwd: artifactDir,
15868
15953
  silent: true
15869
15954
  });
15870
- console.log(chalk11.green(` \u2713 Pushed`));
15955
+ console.log(chalk12.green(` \u2713 Pushed`));
15871
15956
  } catch (error43) {
15872
- console.error(chalk11.red(` \u2717 Failed`));
15957
+ console.error(chalk12.red(` \u2717 Failed`));
15873
15958
  if (error43 instanceof Error) {
15874
- console.error(chalk11.gray(` ${error43.message}`));
15959
+ console.error(chalk12.gray(` ${error43.message}`));
15875
15960
  }
15876
15961
  process.exit(1);
15877
15962
  }
15878
15963
  console.log();
15879
- console.log(chalk11.blue("Uploading compose..."));
15964
+ console.log(chalk12.blue("Uploading compose..."));
15880
15965
  try {
15881
15966
  await execVm0Command(["compose", CONFIG_FILE3], {
15882
15967
  cwd,
15883
15968
  silent: true
15884
15969
  });
15885
- console.log(chalk11.green(`\u2713 Compose uploaded: ${agentName}`));
15970
+ console.log(chalk12.green(`\u2713 Compose uploaded: ${agentName}`));
15886
15971
  } catch (error43) {
15887
- console.error(chalk11.red(`\u2717 Compose failed`));
15972
+ console.error(chalk12.red(`\u2717 Compose failed`));
15888
15973
  if (error43 instanceof Error) {
15889
- console.error(chalk11.gray(` ${error43.message}`));
15974
+ console.error(chalk12.gray(` ${error43.message}`));
15890
15975
  }
15891
15976
  process.exit(1);
15892
15977
  }
15893
15978
  if (prompt) {
15894
15979
  console.log();
15895
- console.log(chalk11.blue(`Running agent: ${agentName}`));
15980
+ console.log(chalk12.blue(`Running agent: ${agentName}`));
15896
15981
  console.log();
15897
15982
  let runOutput;
15898
15983
  try {
@@ -15913,17 +15998,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15913
15998
  );
15914
15999
  if (serverVersion) {
15915
16000
  console.log();
15916
- console.log(chalk11.blue("Pulling updated artifact..."));
16001
+ console.log(chalk12.blue("Pulling updated artifact..."));
15917
16002
  try {
15918
16003
  await execVm0Command(["artifact", "pull"], {
15919
16004
  cwd: artifactDir,
15920
16005
  silent: true
15921
16006
  });
15922
- console.log(chalk11.green(`\u2713 Artifact pulled (${serverVersion})`));
16007
+ console.log(chalk12.green(`\u2713 Artifact pulled (${serverVersion})`));
15923
16008
  } catch (error43) {
15924
- console.error(chalk11.red(`\u2717 Artifact pull failed`));
16009
+ console.error(chalk12.red(`\u2717 Artifact pull failed`));
15925
16010
  if (error43 instanceof Error) {
15926
- console.error(chalk11.gray(` ${error43.message}`));
16011
+ console.error(chalk12.gray(` ${error43.message}`));
15927
16012
  }
15928
16013
  }
15929
16014
  }
@@ -15931,7 +16016,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15931
16016
  console.log();
15932
16017
  console.log(" Run your agent:");
15933
16018
  console.log(
15934
- chalk11.cyan(
16019
+ chalk12.cyan(
15935
16020
  ` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
15936
16021
  )
15937
16022
  );
@@ -15943,7 +16028,7 @@ import { Command as Command15 } from "commander";
15943
16028
 
15944
16029
  // src/commands/image/build.ts
15945
16030
  import { Command as Command12 } from "commander";
15946
- import chalk12 from "chalk";
16031
+ import chalk13 from "chalk";
15947
16032
  import { readFile as readFile6 } from "fs/promises";
15948
16033
  import { existsSync as existsSync6 } from "fs";
15949
16034
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
@@ -15951,13 +16036,13 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15951
16036
  async (options) => {
15952
16037
  const { file: file2, name, deleteExisting } = options;
15953
16038
  if (!existsSync6(file2)) {
15954
- console.error(chalk12.red(`\u2717 Dockerfile not found: ${file2}`));
16039
+ console.error(chalk13.red(`\u2717 Dockerfile not found: ${file2}`));
15955
16040
  process.exit(1);
15956
16041
  }
15957
16042
  const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
15958
16043
  if (!nameRegex.test(name)) {
15959
16044
  console.error(
15960
- chalk12.red(
16045
+ chalk13.red(
15961
16046
  "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
15962
16047
  )
15963
16048
  );
@@ -15965,7 +16050,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15965
16050
  }
15966
16051
  if (name.startsWith("vm0-")) {
15967
16052
  console.error(
15968
- chalk12.red(
16053
+ chalk13.red(
15969
16054
  '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
15970
16055
  )
15971
16056
  );
@@ -15973,8 +16058,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15973
16058
  }
15974
16059
  try {
15975
16060
  const dockerfile = await readFile6(file2, "utf8");
15976
- console.log(chalk12.blue(`Building image: ${name}`));
15977
- console.log(chalk12.gray(` Dockerfile: ${file2}`));
16061
+ console.log(chalk13.blue(`Building image: ${name}`));
16062
+ console.log(chalk13.gray(` Dockerfile: ${file2}`));
15978
16063
  console.log();
15979
16064
  const buildInfo = await apiClient.createImage({
15980
16065
  dockerfile,
@@ -15982,7 +16067,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15982
16067
  deleteExisting
15983
16068
  });
15984
16069
  const { imageId, buildId } = buildInfo;
15985
- console.log(chalk12.gray(` Build ID: ${buildId}`));
16070
+ console.log(chalk13.gray(` Build ID: ${buildId}`));
15986
16071
  console.log();
15987
16072
  let logsOffset = 0;
15988
16073
  let status = "building";
@@ -15998,7 +16083,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15998
16083
  }
15999
16084
  const statusData = await statusResponse.json();
16000
16085
  for (const log of statusData.logs) {
16001
- console.log(chalk12.gray(` ${log}`));
16086
+ console.log(chalk13.gray(` ${log}`));
16002
16087
  }
16003
16088
  logsOffset = statusData.logsOffset;
16004
16089
  status = statusData.status;
@@ -16008,27 +16093,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16008
16093
  }
16009
16094
  console.log();
16010
16095
  if (status === "ready") {
16011
- console.log(chalk12.green(`\u2713 Image built: ${name}`));
16096
+ console.log(chalk13.green(`\u2713 Image built: ${name}`));
16012
16097
  console.log();
16013
16098
  console.log("Use in vm0.yaml:");
16014
- console.log(chalk12.cyan(` agents:`));
16015
- console.log(chalk12.cyan(` your-agent:`));
16016
- console.log(chalk12.cyan(` image: "${name}"`));
16099
+ console.log(chalk13.cyan(` agents:`));
16100
+ console.log(chalk13.cyan(` your-agent:`));
16101
+ console.log(chalk13.cyan(` image: "${name}"`));
16017
16102
  } else {
16018
- console.error(chalk12.red(`\u2717 Build failed`));
16103
+ console.error(chalk13.red(`\u2717 Build failed`));
16019
16104
  process.exit(1);
16020
16105
  }
16021
16106
  } catch (error43) {
16022
16107
  if (error43 instanceof Error) {
16023
16108
  if (error43.message.includes("Not authenticated")) {
16024
16109
  console.error(
16025
- chalk12.red("\u2717 Not authenticated. Run: vm0 auth login")
16110
+ chalk13.red("\u2717 Not authenticated. Run: vm0 auth login")
16026
16111
  );
16027
16112
  } else {
16028
- console.error(chalk12.red(`\u2717 ${error43.message}`));
16113
+ console.error(chalk13.red(`\u2717 ${error43.message}`));
16029
16114
  }
16030
16115
  } else {
16031
- console.error(chalk12.red("\u2717 An unexpected error occurred"));
16116
+ console.error(chalk13.red("\u2717 An unexpected error occurred"));
16032
16117
  }
16033
16118
  process.exit(1);
16034
16119
  }
@@ -16037,7 +16122,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16037
16122
 
16038
16123
  // src/commands/image/list.ts
16039
16124
  import { Command as Command13 } from "commander";
16040
- import chalk13 from "chalk";
16125
+ import chalk14 from "chalk";
16041
16126
  var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
16042
16127
  try {
16043
16128
  const response = await apiClient.get("/api/images");
@@ -16050,43 +16135,43 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16050
16135
  const data = await response.json();
16051
16136
  const { images } = data;
16052
16137
  if (images.length === 0) {
16053
- console.log(chalk13.gray("No images found."));
16138
+ console.log(chalk14.gray("No images found."));
16054
16139
  console.log();
16055
16140
  console.log("Build your first image:");
16056
16141
  console.log(
16057
- chalk13.cyan(" vm0 image build --file Dockerfile --name my-image")
16142
+ chalk14.cyan(" vm0 image build --file Dockerfile --name my-image")
16058
16143
  );
16059
16144
  return;
16060
16145
  }
16061
- console.log(chalk13.bold("Your images:"));
16146
+ console.log(chalk14.bold("Your images:"));
16062
16147
  console.log();
16063
16148
  console.log(
16064
- chalk13.gray(
16149
+ chalk14.gray(
16065
16150
  `${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16066
16151
  )
16067
16152
  );
16068
- console.log(chalk13.gray("-".repeat(62)));
16153
+ console.log(chalk14.gray("-".repeat(62)));
16069
16154
  for (const image of images) {
16070
- const statusColor = image.status === "ready" ? chalk13.green : image.status === "building" ? chalk13.yellow : chalk13.red;
16155
+ const statusColor = image.status === "ready" ? chalk14.green : image.status === "building" ? chalk14.yellow : chalk14.red;
16071
16156
  const createdAt = new Date(image.createdAt).toLocaleString();
16072
16157
  console.log(
16073
16158
  `${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16074
16159
  );
16075
16160
  if (image.status === "error" && image.errorMessage) {
16076
- console.log(chalk13.red(` Error: ${image.errorMessage}`));
16161
+ console.log(chalk14.red(` Error: ${image.errorMessage}`));
16077
16162
  }
16078
16163
  }
16079
16164
  console.log();
16080
- console.log(chalk13.gray(`Total: ${images.length} image(s)`));
16165
+ console.log(chalk14.gray(`Total: ${images.length} image(s)`));
16081
16166
  } catch (error43) {
16082
16167
  if (error43 instanceof Error) {
16083
16168
  if (error43.message.includes("Not authenticated")) {
16084
- console.error(chalk13.red("Not authenticated. Run: vm0 auth login"));
16169
+ console.error(chalk14.red("Not authenticated. Run: vm0 auth login"));
16085
16170
  } else {
16086
- console.error(chalk13.red(`Error: ${error43.message}`));
16171
+ console.error(chalk14.red(`Error: ${error43.message}`));
16087
16172
  }
16088
16173
  } else {
16089
- console.error(chalk13.red("An unexpected error occurred"));
16174
+ console.error(chalk14.red("An unexpected error occurred"));
16090
16175
  }
16091
16176
  process.exit(1);
16092
16177
  }
@@ -16094,7 +16179,7 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16094
16179
 
16095
16180
  // src/commands/image/delete.ts
16096
16181
  import { Command as Command14 } from "commander";
16097
- import chalk14 from "chalk";
16182
+ import chalk15 from "chalk";
16098
16183
  import * as readline from "readline";
16099
16184
  var deleteCommand = new Command14().name("delete").alias("rm").description("Delete a custom image").argument("<name>", "Name of the image to delete").option("-f, --force", "Skip confirmation prompt").action(async (name, options) => {
16100
16185
  try {
@@ -16108,7 +16193,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16108
16193
  const data = await listResponse.json();
16109
16194
  const image = data.images.find((img) => img.alias === name);
16110
16195
  if (!image) {
16111
- console.error(chalk14.red(`Image not found: ${name}`));
16196
+ console.error(chalk15.red(`Image not found: ${name}`));
16112
16197
  process.exit(1);
16113
16198
  }
16114
16199
  if (!options.force) {
@@ -16118,7 +16203,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16118
16203
  });
16119
16204
  const answer = await new Promise((resolve2) => {
16120
16205
  rl.question(
16121
- chalk14.yellow(`Delete image "${name}"? [y/N] `),
16206
+ chalk15.yellow(`Delete image "${name}"? [y/N] `),
16122
16207
  (answer2) => {
16123
16208
  rl.close();
16124
16209
  resolve2(answer2);
@@ -16126,7 +16211,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16126
16211
  );
16127
16212
  });
16128
16213
  if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16129
- console.log(chalk14.gray("Cancelled."));
16214
+ console.log(chalk15.gray("Cancelled."));
16130
16215
  return;
16131
16216
  }
16132
16217
  }
@@ -16137,16 +16222,16 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16137
16222
  error43.error?.message || "Failed to delete image"
16138
16223
  );
16139
16224
  }
16140
- console.log(chalk14.green(`Deleted image: ${name}`));
16225
+ console.log(chalk15.green(`Deleted image: ${name}`));
16141
16226
  } catch (error43) {
16142
16227
  if (error43 instanceof Error) {
16143
16228
  if (error43.message.includes("Not authenticated")) {
16144
- console.error(chalk14.red("Not authenticated. Run: vm0 auth login"));
16229
+ console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16145
16230
  } else {
16146
- console.error(chalk14.red(`Error: ${error43.message}`));
16231
+ console.error(chalk15.red(`Error: ${error43.message}`));
16147
16232
  }
16148
16233
  } else {
16149
- console.error(chalk14.red("An unexpected error occurred"));
16234
+ console.error(chalk15.red("An unexpected error occurred"));
16150
16235
  }
16151
16236
  process.exit(1);
16152
16237
  }
@@ -16157,7 +16242,7 @@ var imageCommand = new Command15().name("image").description("Manage custom imag
16157
16242
 
16158
16243
  // src/commands/logs/index.ts
16159
16244
  import { Command as Command16 } from "commander";
16160
- import chalk15 from "chalk";
16245
+ import chalk16 from "chalk";
16161
16246
 
16162
16247
  // src/lib/time-parser.ts
16163
16248
  function parseTime(timeStr) {
@@ -16219,23 +16304,23 @@ function formatMetric(metric) {
16219
16304
  function formatNetworkLog(entry) {
16220
16305
  let statusColor;
16221
16306
  if (entry.status >= 200 && entry.status < 300) {
16222
- statusColor = chalk15.green;
16307
+ statusColor = chalk16.green;
16223
16308
  } else if (entry.status >= 300 && entry.status < 400) {
16224
- statusColor = chalk15.yellow;
16309
+ statusColor = chalk16.yellow;
16225
16310
  } else if (entry.status >= 400) {
16226
- statusColor = chalk15.red;
16311
+ statusColor = chalk16.red;
16227
16312
  } else {
16228
- statusColor = chalk15.gray;
16313
+ statusColor = chalk16.gray;
16229
16314
  }
16230
16315
  let latencyColor;
16231
16316
  if (entry.latency_ms < 500) {
16232
- latencyColor = chalk15.green;
16317
+ latencyColor = chalk16.green;
16233
16318
  } else if (entry.latency_ms < 2e3) {
16234
- latencyColor = chalk15.yellow;
16319
+ latencyColor = chalk16.yellow;
16235
16320
  } else {
16236
- latencyColor = chalk15.red;
16321
+ latencyColor = chalk16.red;
16237
16322
  }
16238
- return `[${entry.timestamp}] ${chalk15.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk15.gray(entry.url)}`;
16323
+ return `[${entry.timestamp}] ${chalk16.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk16.gray(entry.url)}`;
16239
16324
  }
16240
16325
  function renderAgentEvent(event) {
16241
16326
  const parsed = ClaudeEventParser.parse(
@@ -16255,7 +16340,7 @@ function getLogType(options) {
16255
16340
  ].filter(Boolean).length;
16256
16341
  if (selected > 1) {
16257
16342
  console.error(
16258
- chalk15.red(
16343
+ chalk16.red(
16259
16344
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
16260
16345
  )
16261
16346
  );
@@ -16308,7 +16393,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
16308
16393
  async function showAgentEvents(runId, options) {
16309
16394
  const response = await apiClient.getAgentEvents(runId, options);
16310
16395
  if (response.events.length === 0) {
16311
- console.log(chalk15.yellow("No agent events found for this run."));
16396
+ console.log(chalk16.yellow("No agent events found for this run."));
16312
16397
  return;
16313
16398
  }
16314
16399
  for (const event of response.events) {
@@ -16317,7 +16402,7 @@ async function showAgentEvents(runId, options) {
16317
16402
  if (response.hasMore) {
16318
16403
  console.log();
16319
16404
  console.log(
16320
- chalk15.gray(
16405
+ chalk16.gray(
16321
16406
  `Showing ${response.events.length} events. Use --limit to see more.`
16322
16407
  )
16323
16408
  );
@@ -16326,21 +16411,21 @@ async function showAgentEvents(runId, options) {
16326
16411
  async function showSystemLog(runId, options) {
16327
16412
  const response = await apiClient.getSystemLog(runId, options);
16328
16413
  if (!response.systemLog) {
16329
- console.log(chalk15.yellow("No system log found for this run."));
16414
+ console.log(chalk16.yellow("No system log found for this run."));
16330
16415
  return;
16331
16416
  }
16332
16417
  console.log(response.systemLog);
16333
16418
  if (response.hasMore) {
16334
16419
  console.log();
16335
16420
  console.log(
16336
- chalk15.gray("More log entries available. Use --limit to see more.")
16421
+ chalk16.gray("More log entries available. Use --limit to see more.")
16337
16422
  );
16338
16423
  }
16339
16424
  }
16340
16425
  async function showMetrics(runId, options) {
16341
16426
  const response = await apiClient.getMetrics(runId, options);
16342
16427
  if (response.metrics.length === 0) {
16343
- console.log(chalk15.yellow("No metrics found for this run."));
16428
+ console.log(chalk16.yellow("No metrics found for this run."));
16344
16429
  return;
16345
16430
  }
16346
16431
  for (const metric of response.metrics) {
@@ -16349,7 +16434,7 @@ async function showMetrics(runId, options) {
16349
16434
  if (response.hasMore) {
16350
16435
  console.log();
16351
16436
  console.log(
16352
- chalk15.gray(
16437
+ chalk16.gray(
16353
16438
  `Showing ${response.metrics.length} metrics. Use --limit to see more.`
16354
16439
  )
16355
16440
  );
@@ -16359,7 +16444,7 @@ async function showNetworkLogs(runId, options) {
16359
16444
  const response = await apiClient.getNetworkLogs(runId, options);
16360
16445
  if (response.networkLogs.length === 0) {
16361
16446
  console.log(
16362
- chalk15.yellow(
16447
+ chalk16.yellow(
16363
16448
  "No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
16364
16449
  )
16365
16450
  );
@@ -16371,7 +16456,7 @@ async function showNetworkLogs(runId, options) {
16371
16456
  if (response.hasMore) {
16372
16457
  console.log();
16373
16458
  console.log(
16374
- chalk15.gray(
16459
+ chalk16.gray(
16375
16460
  `Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
16376
16461
  )
16377
16462
  );
@@ -16380,25 +16465,25 @@ async function showNetworkLogs(runId, options) {
16380
16465
  function handleError(error43, runId) {
16381
16466
  if (error43 instanceof Error) {
16382
16467
  if (error43.message.includes("Not authenticated")) {
16383
- console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16468
+ console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16384
16469
  } else if (error43.message.includes("not found")) {
16385
- console.error(chalk15.red(`Run not found: ${runId}`));
16470
+ console.error(chalk16.red(`Run not found: ${runId}`));
16386
16471
  } else if (error43.message.includes("Invalid time format")) {
16387
- console.error(chalk15.red(error43.message));
16472
+ console.error(chalk16.red(error43.message));
16388
16473
  } else {
16389
- console.error(chalk15.red("Failed to fetch logs"));
16390
- console.error(chalk15.gray(` ${error43.message}`));
16474
+ console.error(chalk16.red("Failed to fetch logs"));
16475
+ console.error(chalk16.gray(` ${error43.message}`));
16391
16476
  }
16392
16477
  } else {
16393
- console.error(chalk15.red("An unexpected error occurred"));
16478
+ console.error(chalk16.red("An unexpected error occurred"));
16394
16479
  }
16395
16480
  }
16396
16481
 
16397
16482
  // src/index.ts
16398
16483
  var program = new Command17();
16399
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.8.1");
16484
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.10.0");
16400
16485
  program.command("info").description("Display environment information").action(async () => {
16401
- console.log(chalk16.cyan("System Information:"));
16486
+ console.log(chalk17.cyan("System Information:"));
16402
16487
  console.log(`Node Version: ${process.version}`);
16403
16488
  console.log(`Platform: ${process.platform}`);
16404
16489
  console.log(`Architecture: ${process.arch}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.8.1",
3
+ "version": "4.10.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",