@vm0/cli 4.13.1 → 4.14.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.
Files changed (2) hide show
  1. package/index.js +323 -188
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -6,8 +6,8 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/index.ts
9
- import { Command as Command17 } from "commander";
10
- import chalk18 from "chalk";
9
+ import { Command as Command19 } from "commander";
10
+ import chalk20 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -1011,7 +1011,6 @@ async function directUpload(storageName, storageType, cwd, options) {
1011
1011
  const files = await getAllFiles(cwd);
1012
1012
  onProgress?.("Computing file hashes...");
1013
1013
  const fileEntries = await collectFileMetadata(cwd, files, onProgress);
1014
- const totalSize = fileEntries.reduce((sum, f) => sum + f.size, 0);
1015
1014
  onProgress?.("Preparing upload...");
1016
1015
  const prepareResponse = await apiClient.post("/api/storages/prepare", {
1017
1016
  body: JSON.stringify({
@@ -1027,12 +1026,26 @@ async function directUpload(storageName, storageType, cwd, options) {
1027
1026
  }
1028
1027
  const prepareResult = await prepareResponse.json();
1029
1028
  if (prepareResult.existing) {
1029
+ onProgress?.("Version exists, updating HEAD...");
1030
+ const commitResponse2 = await apiClient.post("/api/storages/commit", {
1031
+ body: JSON.stringify({
1032
+ storageName,
1033
+ storageType,
1034
+ versionId: prepareResult.versionId,
1035
+ files: fileEntries
1036
+ })
1037
+ });
1038
+ if (!commitResponse2.ok) {
1039
+ const error43 = await commitResponse2.json();
1040
+ throw new Error(error43.error?.message || "Commit failed");
1041
+ }
1042
+ const commitResult2 = await commitResponse2.json();
1030
1043
  return {
1031
- versionId: prepareResult.versionId,
1032
- size: totalSize,
1033
- fileCount: fileEntries.length,
1044
+ versionId: commitResult2.versionId,
1045
+ size: commitResult2.size,
1046
+ fileCount: commitResult2.fileCount,
1034
1047
  deduplicated: true,
1035
- empty: fileEntries.length === 0
1048
+ empty: commitResult2.fileCount === 0
1036
1049
  };
1037
1050
  }
1038
1051
  if (files.length > 0) {
@@ -15258,7 +15271,7 @@ runCmd.command("continue").description(
15258
15271
  var runCommand = runCmd;
15259
15272
 
15260
15273
  // src/commands/volume/index.ts
15261
- import { Command as Command6 } from "commander";
15274
+ import { Command as Command7 } from "commander";
15262
15275
 
15263
15276
  // src/commands/volume/init.ts
15264
15277
  import { Command as Command3 } from "commander";
@@ -15520,17 +15533,78 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15520
15533
  }
15521
15534
  });
15522
15535
 
15536
+ // src/commands/volume/status.ts
15537
+ import { Command as Command6 } from "commander";
15538
+ import chalk9 from "chalk";
15539
+ function formatBytes3(bytes) {
15540
+ if (bytes === 0) return "0 B";
15541
+ const k = 1024;
15542
+ const sizes = ["B", "KB", "MB", "GB"];
15543
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
15544
+ return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
15545
+ }
15546
+ var statusCommand = new Command6().name("status").description("Show status of cloud volume").action(async () => {
15547
+ try {
15548
+ const cwd = process.cwd();
15549
+ const config2 = await readStorageConfig(cwd);
15550
+ if (!config2) {
15551
+ console.error(chalk9.red("\u2717 No volume initialized in this directory"));
15552
+ console.error(chalk9.gray(" Run: vm0 volume init"));
15553
+ process.exit(1);
15554
+ }
15555
+ if (config2.type !== "volume") {
15556
+ console.error(
15557
+ chalk9.red(
15558
+ "\u2717 This directory is initialized as an artifact, not a volume"
15559
+ )
15560
+ );
15561
+ console.error(chalk9.gray(" Use: vm0 artifact status"));
15562
+ process.exit(1);
15563
+ }
15564
+ console.log(chalk9.cyan(`Checking volume: ${config2.name}`));
15565
+ const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=volume`;
15566
+ const response = await apiClient.get(url2);
15567
+ if (!response.ok) {
15568
+ if (response.status === 404) {
15569
+ console.error(chalk9.red("\u2717 Not found on remote"));
15570
+ console.error(chalk9.gray(" Run: vm0 volume push"));
15571
+ } else {
15572
+ const error43 = await response.json();
15573
+ throw new Error(error43.error?.message || "Status check failed");
15574
+ }
15575
+ process.exit(1);
15576
+ }
15577
+ const info = await response.json();
15578
+ const shortVersion = info.versionId.slice(0, 8);
15579
+ if (info.empty) {
15580
+ console.log(chalk9.green("\u2713 Found (empty)"));
15581
+ console.log(chalk9.gray(` Version: ${shortVersion}`));
15582
+ } else {
15583
+ console.log(chalk9.green("\u2713 Found"));
15584
+ console.log(chalk9.gray(` Version: ${shortVersion}`));
15585
+ console.log(chalk9.gray(` Files: ${info.fileCount.toLocaleString()}`));
15586
+ console.log(chalk9.gray(` Size: ${formatBytes3(info.size)}`));
15587
+ }
15588
+ } catch (error43) {
15589
+ console.error(chalk9.red("\u2717 Status check failed"));
15590
+ if (error43 instanceof Error) {
15591
+ console.error(chalk9.gray(` ${error43.message}`));
15592
+ }
15593
+ process.exit(1);
15594
+ }
15595
+ });
15596
+
15523
15597
  // src/commands/volume/index.ts
15524
- var volumeCommand = new Command6().name("volume").description("Manage cloud volumes").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand);
15598
+ var volumeCommand = new Command7().name("volume").description("Manage cloud volumes").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand).addCommand(statusCommand);
15525
15599
 
15526
15600
  // src/commands/artifact/index.ts
15527
- import { Command as Command10 } from "commander";
15601
+ import { Command as Command12 } from "commander";
15528
15602
 
15529
15603
  // src/commands/artifact/init.ts
15530
- import { Command as Command7 } from "commander";
15531
- import chalk9 from "chalk";
15604
+ import { Command as Command8 } from "commander";
15605
+ import chalk10 from "chalk";
15532
15606
  import path9 from "path";
15533
- var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
15607
+ var initCommand2 = new Command8().name("init").description("Initialize an artifact in the current directory").action(async () => {
15534
15608
  try {
15535
15609
  const cwd = process.cwd();
15536
15610
  const dirName = path9.basename(cwd);
@@ -15538,67 +15612,67 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15538
15612
  if (existingConfig) {
15539
15613
  if (existingConfig.type === "artifact") {
15540
15614
  console.log(
15541
- chalk9.yellow(
15615
+ chalk10.yellow(
15542
15616
  `Artifact already initialized: ${existingConfig.name}`
15543
15617
  )
15544
15618
  );
15545
15619
  } else {
15546
15620
  console.log(
15547
- chalk9.yellow(
15621
+ chalk10.yellow(
15548
15622
  `Directory already initialized as volume: ${existingConfig.name}`
15549
15623
  )
15550
15624
  );
15551
15625
  console.log(
15552
- chalk9.gray(
15626
+ chalk10.gray(
15553
15627
  " To change type, delete .vm0/storage.yaml and reinitialize"
15554
15628
  )
15555
15629
  );
15556
15630
  }
15557
15631
  console.log(
15558
- chalk9.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15632
+ chalk10.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15559
15633
  );
15560
15634
  return;
15561
15635
  }
15562
15636
  const artifactName = dirName;
15563
15637
  if (!isValidStorageName(artifactName)) {
15564
- console.error(chalk9.red(`\u2717 Invalid artifact name: "${dirName}"`));
15638
+ console.error(chalk10.red(`\u2717 Invalid artifact name: "${dirName}"`));
15565
15639
  console.error(
15566
- chalk9.gray(
15640
+ chalk10.gray(
15567
15641
  " Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
15568
15642
  )
15569
15643
  );
15570
15644
  console.error(
15571
- chalk9.gray(" Example: my-project, user-workspace, code-artifact")
15645
+ chalk10.gray(" Example: my-project, user-workspace, code-artifact")
15572
15646
  );
15573
15647
  process.exit(1);
15574
15648
  }
15575
15649
  await writeStorageConfig(artifactName, cwd, "artifact");
15576
- console.log(chalk9.green(`\u2713 Initialized artifact: ${artifactName}`));
15650
+ console.log(chalk10.green(`\u2713 Initialized artifact: ${artifactName}`));
15577
15651
  console.log(
15578
- chalk9.gray(
15652
+ chalk10.gray(
15579
15653
  `\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
15580
15654
  )
15581
15655
  );
15582
15656
  } catch (error43) {
15583
- console.error(chalk9.red("\u2717 Failed to initialize artifact"));
15657
+ console.error(chalk10.red("\u2717 Failed to initialize artifact"));
15584
15658
  if (error43 instanceof Error) {
15585
- console.error(chalk9.gray(` ${error43.message}`));
15659
+ console.error(chalk10.gray(` ${error43.message}`));
15586
15660
  }
15587
15661
  process.exit(1);
15588
15662
  }
15589
15663
  });
15590
15664
 
15591
15665
  // src/commands/artifact/push.ts
15592
- import { Command as Command8 } from "commander";
15593
- import chalk10 from "chalk";
15594
- function formatBytes3(bytes) {
15666
+ import { Command as Command9 } from "commander";
15667
+ import chalk11 from "chalk";
15668
+ function formatBytes4(bytes) {
15595
15669
  if (bytes === 0) return "0 B";
15596
15670
  const k = 1024;
15597
15671
  const sizes = ["B", "KB", "MB", "GB"];
15598
15672
  const i = Math.floor(Math.log(bytes) / Math.log(k));
15599
15673
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
15600
15674
  }
15601
- var pushCommand2 = new Command8().name("push").description("Push local files to cloud artifact").option(
15675
+ var pushCommand2 = new Command9().name("push").description("Push local files to cloud artifact").option(
15602
15676
  "-f, --force",
15603
15677
  "Force upload even if content unchanged (recreate archive)"
15604
15678
  ).action(async (options) => {
@@ -15606,88 +15680,88 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15606
15680
  const cwd = process.cwd();
15607
15681
  const config2 = await readStorageConfig(cwd);
15608
15682
  if (!config2) {
15609
- console.error(chalk10.red("\u2717 No artifact initialized in this directory"));
15610
- console.error(chalk10.gray(" Run: vm0 artifact init"));
15683
+ console.error(chalk11.red("\u2717 No artifact initialized in this directory"));
15684
+ console.error(chalk11.gray(" Run: vm0 artifact init"));
15611
15685
  process.exit(1);
15612
15686
  }
15613
15687
  if (config2.type !== "artifact") {
15614
15688
  console.error(
15615
- chalk10.red(
15689
+ chalk11.red(
15616
15690
  `\u2717 This directory is initialized as a volume, not an artifact`
15617
15691
  )
15618
15692
  );
15619
- console.error(chalk10.gray(" Use: vm0 volume push"));
15693
+ console.error(chalk11.gray(" Use: vm0 volume push"));
15620
15694
  process.exit(1);
15621
15695
  }
15622
- console.log(chalk10.cyan(`Pushing artifact: ${config2.name}`));
15696
+ console.log(chalk11.cyan(`Pushing artifact: ${config2.name}`));
15623
15697
  const result = await directUpload(config2.name, "artifact", cwd, {
15624
15698
  onProgress: (message) => {
15625
- console.log(chalk10.gray(message));
15699
+ console.log(chalk11.gray(message));
15626
15700
  },
15627
15701
  force: options.force
15628
15702
  });
15629
15703
  const shortVersion = result.versionId.slice(0, 8);
15630
15704
  if (result.empty) {
15631
- console.log(chalk10.yellow("No files found (empty artifact)"));
15705
+ console.log(chalk11.yellow("No files found (empty artifact)"));
15632
15706
  } else if (result.deduplicated) {
15633
- console.log(chalk10.green("\u2713 Content unchanged (deduplicated)"));
15707
+ console.log(chalk11.green("\u2713 Content unchanged (deduplicated)"));
15634
15708
  } else {
15635
- console.log(chalk10.green("\u2713 Upload complete"));
15709
+ console.log(chalk11.green("\u2713 Upload complete"));
15636
15710
  }
15637
- console.log(chalk10.gray(` Version: ${shortVersion}`));
15638
- console.log(chalk10.gray(` Files: ${result.fileCount.toLocaleString()}`));
15639
- console.log(chalk10.gray(` Size: ${formatBytes3(result.size)}`));
15711
+ console.log(chalk11.gray(` Version: ${shortVersion}`));
15712
+ console.log(chalk11.gray(` Files: ${result.fileCount.toLocaleString()}`));
15713
+ console.log(chalk11.gray(` Size: ${formatBytes4(result.size)}`));
15640
15714
  } catch (error43) {
15641
- console.error(chalk10.red("\u2717 Push failed"));
15715
+ console.error(chalk11.red("\u2717 Push failed"));
15642
15716
  if (error43 instanceof Error) {
15643
- console.error(chalk10.gray(` ${error43.message}`));
15717
+ console.error(chalk11.gray(` ${error43.message}`));
15644
15718
  }
15645
15719
  process.exit(1);
15646
15720
  }
15647
15721
  });
15648
15722
 
15649
15723
  // src/commands/artifact/pull.ts
15650
- import { Command as Command9 } from "commander";
15651
- import chalk11 from "chalk";
15724
+ import { Command as Command10 } from "commander";
15725
+ import chalk12 from "chalk";
15652
15726
  import path10 from "path";
15653
15727
  import * as fs7 from "fs";
15654
15728
  import * as os5 from "os";
15655
15729
  import * as tar4 from "tar";
15656
- function formatBytes4(bytes) {
15730
+ function formatBytes5(bytes) {
15657
15731
  if (bytes === 0) return "0 B";
15658
15732
  const k = 1024;
15659
15733
  const sizes = ["B", "KB", "MB", "GB"];
15660
15734
  const i = Math.floor(Math.log(bytes) / Math.log(k));
15661
15735
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
15662
15736
  }
15663
- var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
15737
+ var pullCommand2 = new Command10().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(async (versionId) => {
15664
15738
  try {
15665
15739
  const cwd = process.cwd();
15666
15740
  const config2 = await readStorageConfig(cwd);
15667
15741
  if (!config2) {
15668
- console.error(chalk11.red("\u2717 No artifact initialized in this directory"));
15669
- console.error(chalk11.gray(" Run: vm0 artifact init"));
15742
+ console.error(chalk12.red("\u2717 No artifact initialized in this directory"));
15743
+ console.error(chalk12.gray(" Run: vm0 artifact init"));
15670
15744
  process.exit(1);
15671
15745
  }
15672
15746
  if (config2.type !== "artifact") {
15673
15747
  console.error(
15674
- chalk11.red(
15748
+ chalk12.red(
15675
15749
  `\u2717 This directory is initialized as a volume, not an artifact`
15676
15750
  )
15677
15751
  );
15678
- console.error(chalk11.gray(" Use: vm0 volume pull"));
15752
+ console.error(chalk12.gray(" Use: vm0 volume pull"));
15679
15753
  process.exit(1);
15680
15754
  }
15681
15755
  if (versionId) {
15682
15756
  console.log(
15683
- chalk11.cyan(
15757
+ chalk12.cyan(
15684
15758
  `Pulling artifact: ${config2.name} (version: ${versionId})`
15685
15759
  )
15686
15760
  );
15687
15761
  } else {
15688
- console.log(chalk11.cyan(`Pulling artifact: ${config2.name}`));
15762
+ console.log(chalk12.cyan(`Pulling artifact: ${config2.name}`));
15689
15763
  }
15690
- console.log(chalk11.gray("Getting download URL..."));
15764
+ console.log(chalk12.gray("Getting download URL..."));
15691
15765
  let url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
15692
15766
  if (versionId) {
15693
15767
  url2 += `&version=${encodeURIComponent(versionId)}`;
@@ -15695,14 +15769,14 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15695
15769
  const response = await apiClient.get(url2);
15696
15770
  if (!response.ok) {
15697
15771
  if (response.status === 404) {
15698
- console.error(chalk11.red(`\u2717 Artifact "${config2.name}" not found`));
15772
+ console.error(chalk12.red(`\u2717 Artifact "${config2.name}" not found`));
15699
15773
  console.error(
15700
- chalk11.gray(
15774
+ chalk12.gray(
15701
15775
  " Make sure the artifact name is correct in .vm0/storage.yaml"
15702
15776
  )
15703
15777
  );
15704
15778
  console.error(
15705
- chalk11.gray(" Or push the artifact first with: vm0 artifact push")
15779
+ chalk12.gray(" Or push the artifact first with: vm0 artifact push")
15706
15780
  );
15707
15781
  } else {
15708
15782
  const error43 = await response.json();
@@ -15718,18 +15792,18 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15718
15792
  if (!downloadInfo.url) {
15719
15793
  throw new Error("No download URL returned");
15720
15794
  }
15721
- console.log(chalk11.gray("Downloading from S3..."));
15795
+ console.log(chalk12.gray("Downloading from S3..."));
15722
15796
  const s3Response = await fetch(downloadInfo.url);
15723
15797
  if (!s3Response.ok) {
15724
15798
  throw new Error(`S3 download failed: ${s3Response.status}`);
15725
15799
  }
15726
15800
  const arrayBuffer = await s3Response.arrayBuffer();
15727
15801
  const tarBuffer = Buffer.from(arrayBuffer);
15728
- console.log(chalk11.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
15802
+ console.log(chalk12.green(`\u2713 Downloaded ${formatBytes5(tarBuffer.length)}`));
15729
15803
  const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
15730
15804
  const tarPath = path10.join(tmpDir, "artifact.tar.gz");
15731
15805
  await fs7.promises.writeFile(tarPath, tarBuffer);
15732
- console.log(chalk11.gray("Syncing local files..."));
15806
+ console.log(chalk12.gray("Syncing local files..."));
15733
15807
  const remoteFiles = await listTarFiles(tarPath);
15734
15808
  const remoteFilesSet = new Set(
15735
15809
  remoteFiles.map((f) => f.replace(/\\/g, "/"))
@@ -15737,10 +15811,10 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15737
15811
  const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
15738
15812
  if (removedCount > 0) {
15739
15813
  console.log(
15740
- chalk11.green(`\u2713 Removed ${removedCount} files not in remote`)
15814
+ chalk12.green(`\u2713 Removed ${removedCount} files not in remote`)
15741
15815
  );
15742
15816
  }
15743
- console.log(chalk11.gray("Extracting files..."));
15817
+ console.log(chalk12.gray("Extracting files..."));
15744
15818
  await tar4.extract({
15745
15819
  file: tarPath,
15746
15820
  cwd,
@@ -15748,22 +15822,83 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15748
15822
  });
15749
15823
  await fs7.promises.unlink(tarPath);
15750
15824
  await fs7.promises.rmdir(tmpDir);
15751
- console.log(chalk11.green(`\u2713 Extracted ${remoteFiles.length} files`));
15825
+ console.log(chalk12.green(`\u2713 Extracted ${remoteFiles.length} files`));
15752
15826
  } catch (error43) {
15753
- console.error(chalk11.red("\u2717 Pull failed"));
15827
+ console.error(chalk12.red("\u2717 Pull failed"));
15754
15828
  if (error43 instanceof Error) {
15755
- console.error(chalk11.gray(` ${error43.message}`));
15829
+ console.error(chalk12.gray(` ${error43.message}`));
15830
+ }
15831
+ process.exit(1);
15832
+ }
15833
+ });
15834
+
15835
+ // src/commands/artifact/status.ts
15836
+ import { Command as Command11 } from "commander";
15837
+ import chalk13 from "chalk";
15838
+ function formatBytes6(bytes) {
15839
+ if (bytes === 0) return "0 B";
15840
+ const k = 1024;
15841
+ const sizes = ["B", "KB", "MB", "GB"];
15842
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
15843
+ return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
15844
+ }
15845
+ var statusCommand2 = new Command11().name("status").description("Show status of cloud artifact").action(async () => {
15846
+ try {
15847
+ const cwd = process.cwd();
15848
+ const config2 = await readStorageConfig(cwd);
15849
+ if (!config2) {
15850
+ console.error(chalk13.red("\u2717 No artifact initialized in this directory"));
15851
+ console.error(chalk13.gray(" Run: vm0 artifact init"));
15852
+ process.exit(1);
15853
+ }
15854
+ if (config2.type !== "artifact") {
15855
+ console.error(
15856
+ chalk13.red(
15857
+ "\u2717 This directory is initialized as a volume, not an artifact"
15858
+ )
15859
+ );
15860
+ console.error(chalk13.gray(" Use: vm0 volume status"));
15861
+ process.exit(1);
15862
+ }
15863
+ console.log(chalk13.cyan(`Checking artifact: ${config2.name}`));
15864
+ const url2 = `/api/storages/download?name=${encodeURIComponent(config2.name)}&type=artifact`;
15865
+ const response = await apiClient.get(url2);
15866
+ if (!response.ok) {
15867
+ if (response.status === 404) {
15868
+ console.error(chalk13.red("\u2717 Not found on remote"));
15869
+ console.error(chalk13.gray(" Run: vm0 artifact push"));
15870
+ } else {
15871
+ const error43 = await response.json();
15872
+ throw new Error(error43.error?.message || "Status check failed");
15873
+ }
15874
+ process.exit(1);
15875
+ }
15876
+ const info = await response.json();
15877
+ const shortVersion = info.versionId.slice(0, 8);
15878
+ if (info.empty) {
15879
+ console.log(chalk13.green("\u2713 Found (empty)"));
15880
+ console.log(chalk13.gray(` Version: ${shortVersion}`));
15881
+ } else {
15882
+ console.log(chalk13.green("\u2713 Found"));
15883
+ console.log(chalk13.gray(` Version: ${shortVersion}`));
15884
+ console.log(chalk13.gray(` Files: ${info.fileCount.toLocaleString()}`));
15885
+ console.log(chalk13.gray(` Size: ${formatBytes6(info.size)}`));
15886
+ }
15887
+ } catch (error43) {
15888
+ console.error(chalk13.red("\u2717 Status check failed"));
15889
+ if (error43 instanceof Error) {
15890
+ console.error(chalk13.gray(` ${error43.message}`));
15756
15891
  }
15757
15892
  process.exit(1);
15758
15893
  }
15759
15894
  });
15760
15895
 
15761
15896
  // src/commands/artifact/index.ts
15762
- var artifactCommand = new Command10().name("artifact").description("Manage cloud artifacts (work products)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2);
15897
+ var artifactCommand = new Command12().name("artifact").description("Manage cloud artifacts (work products)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand2);
15763
15898
 
15764
15899
  // src/commands/cook.ts
15765
- import { Command as Command11 } from "commander";
15766
- import chalk13 from "chalk";
15900
+ import { Command as Command13 } from "commander";
15901
+ import chalk15 from "chalk";
15767
15902
  import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
15768
15903
  import { existsSync as existsSync6, readFileSync } from "fs";
15769
15904
  import path11 from "path";
@@ -15774,7 +15909,7 @@ import { config as dotenvConfig2 } from "dotenv";
15774
15909
  // src/lib/update-checker.ts
15775
15910
  import https from "https";
15776
15911
  import { spawn } from "child_process";
15777
- import chalk12 from "chalk";
15912
+ import chalk14 from "chalk";
15778
15913
  var PACKAGE_NAME = "@vm0/cli";
15779
15914
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
15780
15915
  var TIMEOUT_MS = 5e3;
@@ -15839,21 +15974,21 @@ function performUpgrade(packageManager) {
15839
15974
  async function checkAndUpgrade(currentVersion, prompt) {
15840
15975
  const latestVersion = await getLatestVersion();
15841
15976
  if (latestVersion === null) {
15842
- console.log(chalk12.yellow("Warning: Could not check for updates"));
15977
+ console.log(chalk14.yellow("Warning: Could not check for updates"));
15843
15978
  console.log();
15844
15979
  return false;
15845
15980
  }
15846
15981
  if (latestVersion === currentVersion) {
15847
15982
  return false;
15848
15983
  }
15849
- console.log(chalk12.yellow("vm0 is currently in Early Access (EA)."));
15984
+ console.log(chalk14.yellow("vm0 is currently in Early Access (EA)."));
15850
15985
  console.log(
15851
- chalk12.yellow(
15986
+ chalk14.yellow(
15852
15987
  `Current version: ${currentVersion} -> Latest version: ${latestVersion}`
15853
15988
  )
15854
15989
  );
15855
15990
  console.log(
15856
- chalk12.yellow(
15991
+ chalk14.yellow(
15857
15992
  "Please always use the latest version for best compatibility."
15858
15993
  )
15859
15994
  );
@@ -15862,20 +15997,20 @@ async function checkAndUpgrade(currentVersion, prompt) {
15862
15997
  console.log(`Upgrading via ${packageManager}...`);
15863
15998
  const success2 = await performUpgrade(packageManager);
15864
15999
  if (success2) {
15865
- console.log(chalk12.green(`Upgraded to ${latestVersion}`));
16000
+ console.log(chalk14.green(`Upgraded to ${latestVersion}`));
15866
16001
  console.log();
15867
16002
  console.log("To continue, run:");
15868
- console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
16003
+ console.log(chalk14.cyan(` ${buildRerunCommand(prompt)}`));
15869
16004
  return true;
15870
16005
  }
15871
16006
  console.log();
15872
- console.log(chalk12.red("Upgrade failed. Please run manually:"));
15873
- console.log(chalk12.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
15874
- console.log(chalk12.gray(" # or"));
15875
- console.log(chalk12.cyan(` pnpm add -g ${PACKAGE_NAME}@latest`));
16007
+ console.log(chalk14.red("Upgrade failed. Please run manually:"));
16008
+ console.log(chalk14.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
16009
+ console.log(chalk14.gray(" # or"));
16010
+ console.log(chalk14.cyan(` pnpm add -g ${PACKAGE_NAME}@latest`));
15876
16011
  console.log();
15877
16012
  console.log("Then re-run:");
15878
- console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
16013
+ console.log(chalk14.cyan(` ${buildRerunCommand(prompt)}`));
15879
16014
  return true;
15880
16015
  }
15881
16016
 
@@ -15995,15 +16130,15 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
15995
16130
  `);
15996
16131
  }
15997
16132
  }
15998
- 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) => {
15999
- const shouldExit = await checkAndUpgrade("4.13.1", prompt);
16133
+ var cookCommand = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
16134
+ const shouldExit = await checkAndUpgrade("4.14.1", prompt);
16000
16135
  if (shouldExit) {
16001
16136
  process.exit(0);
16002
16137
  }
16003
16138
  const cwd = process.cwd();
16004
- console.log(chalk13.blue(`Reading config: ${CONFIG_FILE3}`));
16139
+ console.log(chalk15.blue(`Reading config: ${CONFIG_FILE3}`));
16005
16140
  if (!existsSync6(CONFIG_FILE3)) {
16006
- console.error(chalk13.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
16141
+ console.error(chalk15.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
16007
16142
  process.exit(1);
16008
16143
  }
16009
16144
  let config2;
@@ -16011,22 +16146,22 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16011
16146
  const content = await readFile5(CONFIG_FILE3, "utf8");
16012
16147
  config2 = parseYaml3(content);
16013
16148
  } catch (error43) {
16014
- console.error(chalk13.red("\u2717 Invalid YAML format"));
16149
+ console.error(chalk15.red("\u2717 Invalid YAML format"));
16015
16150
  if (error43 instanceof Error) {
16016
- console.error(chalk13.gray(` ${error43.message}`));
16151
+ console.error(chalk15.gray(` ${error43.message}`));
16017
16152
  }
16018
16153
  process.exit(1);
16019
16154
  }
16020
16155
  const validation = validateAgentCompose(config2);
16021
16156
  if (!validation.valid) {
16022
- console.error(chalk13.red(`\u2717 ${validation.error}`));
16157
+ console.error(chalk15.red(`\u2717 ${validation.error}`));
16023
16158
  process.exit(1);
16024
16159
  }
16025
16160
  const agentNames = Object.keys(config2.agents);
16026
16161
  const agentName = agentNames[0];
16027
16162
  const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
16028
16163
  console.log(
16029
- chalk13.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
16164
+ chalk15.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
16030
16165
  );
16031
16166
  const requiredVarNames = extractRequiredVarNames(config2);
16032
16167
  if (requiredVarNames.length > 0) {
@@ -16036,25 +16171,25 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16036
16171
  await generateEnvPlaceholders(missingVars, envFilePath);
16037
16172
  console.log();
16038
16173
  console.log(
16039
- chalk13.yellow(
16174
+ chalk15.yellow(
16040
16175
  `\u26A0 Missing environment variables. Please fill in values in .env file:`
16041
16176
  )
16042
16177
  );
16043
16178
  for (const varName of missingVars) {
16044
- console.log(chalk13.yellow(` ${varName}`));
16179
+ console.log(chalk15.yellow(` ${varName}`));
16045
16180
  }
16046
16181
  process.exit(1);
16047
16182
  }
16048
16183
  }
16049
16184
  if (config2.volumes && Object.keys(config2.volumes).length > 0) {
16050
16185
  console.log();
16051
- console.log(chalk13.blue("Processing volumes..."));
16186
+ console.log(chalk15.blue("Processing volumes..."));
16052
16187
  for (const volumeConfig of Object.values(config2.volumes)) {
16053
16188
  const volumeDir = path11.join(cwd, volumeConfig.name);
16054
- console.log(chalk13.gray(` ${volumeConfig.name}/`));
16189
+ console.log(chalk15.gray(` ${volumeConfig.name}/`));
16055
16190
  if (!existsSync6(volumeDir)) {
16056
16191
  console.error(
16057
- chalk13.red(
16192
+ chalk15.red(
16058
16193
  ` \u2717 Directory not found. Create the directory and add files first.`
16059
16194
  )
16060
16195
  );
@@ -16067,30 +16202,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16067
16202
  cwd: volumeDir,
16068
16203
  silent: true
16069
16204
  });
16070
- console.log(chalk13.green(` \u2713 Initialized`));
16205
+ console.log(chalk15.green(` \u2713 Initialized`));
16071
16206
  }
16072
16207
  await execVm0Command(["volume", "push"], {
16073
16208
  cwd: volumeDir,
16074
16209
  silent: true
16075
16210
  });
16076
- console.log(chalk13.green(` \u2713 Pushed`));
16211
+ console.log(chalk15.green(` \u2713 Pushed`));
16077
16212
  } catch (error43) {
16078
- console.error(chalk13.red(` \u2717 Failed`));
16213
+ console.error(chalk15.red(` \u2717 Failed`));
16079
16214
  if (error43 instanceof Error) {
16080
- console.error(chalk13.gray(` ${error43.message}`));
16215
+ console.error(chalk15.gray(` ${error43.message}`));
16081
16216
  }
16082
16217
  process.exit(1);
16083
16218
  }
16084
16219
  }
16085
16220
  }
16086
16221
  console.log();
16087
- console.log(chalk13.blue("Processing artifact..."));
16222
+ console.log(chalk15.blue("Processing artifact..."));
16088
16223
  const artifactDir = path11.join(cwd, ARTIFACT_DIR);
16089
- console.log(chalk13.gray(` ${ARTIFACT_DIR}/`));
16224
+ console.log(chalk15.gray(` ${ARTIFACT_DIR}/`));
16090
16225
  try {
16091
16226
  if (!existsSync6(artifactDir)) {
16092
16227
  await mkdir5(artifactDir, { recursive: true });
16093
- console.log(chalk13.green(` \u2713 Created directory`));
16228
+ console.log(chalk15.green(` \u2713 Created directory`));
16094
16229
  }
16095
16230
  const existingConfig = await readStorageConfig(artifactDir);
16096
16231
  if (!existingConfig) {
@@ -16098,38 +16233,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16098
16233
  cwd: artifactDir,
16099
16234
  silent: true
16100
16235
  });
16101
- console.log(chalk13.green(` \u2713 Initialized`));
16236
+ console.log(chalk15.green(` \u2713 Initialized`));
16102
16237
  }
16103
16238
  await execVm0Command(["artifact", "push"], {
16104
16239
  cwd: artifactDir,
16105
16240
  silent: true
16106
16241
  });
16107
- console.log(chalk13.green(` \u2713 Pushed`));
16242
+ console.log(chalk15.green(` \u2713 Pushed`));
16108
16243
  } catch (error43) {
16109
- console.error(chalk13.red(` \u2717 Failed`));
16244
+ console.error(chalk15.red(` \u2717 Failed`));
16110
16245
  if (error43 instanceof Error) {
16111
- console.error(chalk13.gray(` ${error43.message}`));
16246
+ console.error(chalk15.gray(` ${error43.message}`));
16112
16247
  }
16113
16248
  process.exit(1);
16114
16249
  }
16115
16250
  console.log();
16116
- console.log(chalk13.blue("Uploading compose..."));
16251
+ console.log(chalk15.blue("Uploading compose..."));
16117
16252
  try {
16118
16253
  await execVm0Command(["compose", CONFIG_FILE3], {
16119
16254
  cwd,
16120
16255
  silent: true
16121
16256
  });
16122
- console.log(chalk13.green(`\u2713 Compose uploaded: ${agentName}`));
16257
+ console.log(chalk15.green(`\u2713 Compose uploaded: ${agentName}`));
16123
16258
  } catch (error43) {
16124
- console.error(chalk13.red(`\u2717 Compose failed`));
16259
+ console.error(chalk15.red(`\u2717 Compose failed`));
16125
16260
  if (error43 instanceof Error) {
16126
- console.error(chalk13.gray(` ${error43.message}`));
16261
+ console.error(chalk15.gray(` ${error43.message}`));
16127
16262
  }
16128
16263
  process.exit(1);
16129
16264
  }
16130
16265
  if (prompt) {
16131
16266
  console.log();
16132
- console.log(chalk13.blue(`Running agent: ${agentName}`));
16267
+ console.log(chalk15.blue(`Running agent: ${agentName}`));
16133
16268
  console.log();
16134
16269
  let runOutput;
16135
16270
  try {
@@ -16150,17 +16285,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16150
16285
  );
16151
16286
  if (serverVersion) {
16152
16287
  console.log();
16153
- console.log(chalk13.blue("Pulling updated artifact..."));
16288
+ console.log(chalk15.blue("Pulling updated artifact..."));
16154
16289
  try {
16155
16290
  await execVm0Command(["artifact", "pull"], {
16156
16291
  cwd: artifactDir,
16157
16292
  silent: true
16158
16293
  });
16159
- console.log(chalk13.green(`\u2713 Artifact pulled (${serverVersion})`));
16294
+ console.log(chalk15.green(`\u2713 Artifact pulled (${serverVersion})`));
16160
16295
  } catch (error43) {
16161
- console.error(chalk13.red(`\u2717 Artifact pull failed`));
16296
+ console.error(chalk15.red(`\u2717 Artifact pull failed`));
16162
16297
  if (error43 instanceof Error) {
16163
- console.error(chalk13.gray(` ${error43.message}`));
16298
+ console.error(chalk15.gray(` ${error43.message}`));
16164
16299
  }
16165
16300
  }
16166
16301
  }
@@ -16168,7 +16303,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16168
16303
  console.log();
16169
16304
  console.log(" Run your agent:");
16170
16305
  console.log(
16171
- chalk13.cyan(
16306
+ chalk15.cyan(
16172
16307
  ` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
16173
16308
  )
16174
16309
  );
@@ -16176,25 +16311,25 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16176
16311
  });
16177
16312
 
16178
16313
  // src/commands/image/index.ts
16179
- import { Command as Command15 } from "commander";
16314
+ import { Command as Command17 } from "commander";
16180
16315
 
16181
16316
  // src/commands/image/build.ts
16182
- import { Command as Command12 } from "commander";
16183
- import chalk14 from "chalk";
16317
+ import { Command as Command14 } from "commander";
16318
+ import chalk16 from "chalk";
16184
16319
  import { readFile as readFile6 } from "fs/promises";
16185
16320
  import { existsSync as existsSync7 } from "fs";
16186
16321
  var sleep2 = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
16187
- var buildCommand = new Command12().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").option("--delete-existing", "Delete existing image before building").action(
16322
+ var buildCommand = new Command14().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").option("--delete-existing", "Delete existing image before building").action(
16188
16323
  async (options) => {
16189
16324
  const { file: file2, name, deleteExisting } = options;
16190
16325
  if (!existsSync7(file2)) {
16191
- console.error(chalk14.red(`\u2717 Dockerfile not found: ${file2}`));
16326
+ console.error(chalk16.red(`\u2717 Dockerfile not found: ${file2}`));
16192
16327
  process.exit(1);
16193
16328
  }
16194
16329
  const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
16195
16330
  if (!nameRegex.test(name)) {
16196
16331
  console.error(
16197
- chalk14.red(
16332
+ chalk16.red(
16198
16333
  "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
16199
16334
  )
16200
16335
  );
@@ -16202,7 +16337,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16202
16337
  }
16203
16338
  if (name.startsWith("vm0-")) {
16204
16339
  console.error(
16205
- chalk14.red(
16340
+ chalk16.red(
16206
16341
  '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
16207
16342
  )
16208
16343
  );
@@ -16210,8 +16345,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16210
16345
  }
16211
16346
  try {
16212
16347
  const dockerfile = await readFile6(file2, "utf8");
16213
- console.log(chalk14.blue(`Building image: ${name}`));
16214
- console.log(chalk14.gray(` Dockerfile: ${file2}`));
16348
+ console.log(chalk16.blue(`Building image: ${name}`));
16349
+ console.log(chalk16.gray(` Dockerfile: ${file2}`));
16215
16350
  console.log();
16216
16351
  const buildInfo = await apiClient.createImage({
16217
16352
  dockerfile,
@@ -16219,7 +16354,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16219
16354
  deleteExisting
16220
16355
  });
16221
16356
  const { imageId, buildId } = buildInfo;
16222
- console.log(chalk14.gray(` Build ID: ${buildId}`));
16357
+ console.log(chalk16.gray(` Build ID: ${buildId}`));
16223
16358
  console.log();
16224
16359
  let logsOffset = 0;
16225
16360
  let status = "building";
@@ -16235,7 +16370,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16235
16370
  }
16236
16371
  const statusData = await statusResponse.json();
16237
16372
  for (const log of statusData.logs) {
16238
- console.log(chalk14.gray(` ${log}`));
16373
+ console.log(chalk16.gray(` ${log}`));
16239
16374
  }
16240
16375
  logsOffset = statusData.logsOffset;
16241
16376
  status = statusData.status;
@@ -16245,27 +16380,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16245
16380
  }
16246
16381
  console.log();
16247
16382
  if (status === "ready") {
16248
- console.log(chalk14.green(`\u2713 Image built: ${name}`));
16383
+ console.log(chalk16.green(`\u2713 Image built: ${name}`));
16249
16384
  console.log();
16250
16385
  console.log("Use in vm0.yaml:");
16251
- console.log(chalk14.cyan(` agents:`));
16252
- console.log(chalk14.cyan(` your-agent:`));
16253
- console.log(chalk14.cyan(` image: "${name}"`));
16386
+ console.log(chalk16.cyan(` agents:`));
16387
+ console.log(chalk16.cyan(` your-agent:`));
16388
+ console.log(chalk16.cyan(` image: "${name}"`));
16254
16389
  } else {
16255
- console.error(chalk14.red(`\u2717 Build failed`));
16390
+ console.error(chalk16.red(`\u2717 Build failed`));
16256
16391
  process.exit(1);
16257
16392
  }
16258
16393
  } catch (error43) {
16259
16394
  if (error43 instanceof Error) {
16260
16395
  if (error43.message.includes("Not authenticated")) {
16261
16396
  console.error(
16262
- chalk14.red("\u2717 Not authenticated. Run: vm0 auth login")
16397
+ chalk16.red("\u2717 Not authenticated. Run: vm0 auth login")
16263
16398
  );
16264
16399
  } else {
16265
- console.error(chalk14.red(`\u2717 ${error43.message}`));
16400
+ console.error(chalk16.red(`\u2717 ${error43.message}`));
16266
16401
  }
16267
16402
  } else {
16268
- console.error(chalk14.red("\u2717 An unexpected error occurred"));
16403
+ console.error(chalk16.red("\u2717 An unexpected error occurred"));
16269
16404
  }
16270
16405
  process.exit(1);
16271
16406
  }
@@ -16273,9 +16408,9 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16273
16408
  );
16274
16409
 
16275
16410
  // src/commands/image/list.ts
16276
- import { Command as Command13 } from "commander";
16277
- import chalk15 from "chalk";
16278
- var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
16411
+ import { Command as Command15 } from "commander";
16412
+ import chalk17 from "chalk";
16413
+ var listCommand = new Command15().name("list").alias("ls").description("List your custom images").action(async () => {
16279
16414
  try {
16280
16415
  const response = await apiClient.get("/api/images");
16281
16416
  if (!response.ok) {
@@ -16287,53 +16422,53 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16287
16422
  const data = await response.json();
16288
16423
  const { images } = data;
16289
16424
  if (images.length === 0) {
16290
- console.log(chalk15.gray("No images found."));
16425
+ console.log(chalk17.gray("No images found."));
16291
16426
  console.log();
16292
16427
  console.log("Build your first image:");
16293
16428
  console.log(
16294
- chalk15.cyan(" vm0 image build --file Dockerfile --name my-image")
16429
+ chalk17.cyan(" vm0 image build --file Dockerfile --name my-image")
16295
16430
  );
16296
16431
  return;
16297
16432
  }
16298
- console.log(chalk15.bold("Your images:"));
16433
+ console.log(chalk17.bold("Your images:"));
16299
16434
  console.log();
16300
16435
  console.log(
16301
- chalk15.gray(
16436
+ chalk17.gray(
16302
16437
  `${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16303
16438
  )
16304
16439
  );
16305
- console.log(chalk15.gray("-".repeat(62)));
16440
+ console.log(chalk17.gray("-".repeat(62)));
16306
16441
  for (const image of images) {
16307
- const statusColor = image.status === "ready" ? chalk15.green : image.status === "building" ? chalk15.yellow : chalk15.red;
16442
+ const statusColor = image.status === "ready" ? chalk17.green : image.status === "building" ? chalk17.yellow : chalk17.red;
16308
16443
  const createdAt = new Date(image.createdAt).toLocaleString();
16309
16444
  console.log(
16310
16445
  `${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16311
16446
  );
16312
16447
  if (image.status === "error" && image.errorMessage) {
16313
- console.log(chalk15.red(` Error: ${image.errorMessage}`));
16448
+ console.log(chalk17.red(` Error: ${image.errorMessage}`));
16314
16449
  }
16315
16450
  }
16316
16451
  console.log();
16317
- console.log(chalk15.gray(`Total: ${images.length} image(s)`));
16452
+ console.log(chalk17.gray(`Total: ${images.length} image(s)`));
16318
16453
  } catch (error43) {
16319
16454
  if (error43 instanceof Error) {
16320
16455
  if (error43.message.includes("Not authenticated")) {
16321
- console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16456
+ console.error(chalk17.red("Not authenticated. Run: vm0 auth login"));
16322
16457
  } else {
16323
- console.error(chalk15.red(`Error: ${error43.message}`));
16458
+ console.error(chalk17.red(`Error: ${error43.message}`));
16324
16459
  }
16325
16460
  } else {
16326
- console.error(chalk15.red("An unexpected error occurred"));
16461
+ console.error(chalk17.red("An unexpected error occurred"));
16327
16462
  }
16328
16463
  process.exit(1);
16329
16464
  }
16330
16465
  });
16331
16466
 
16332
16467
  // src/commands/image/delete.ts
16333
- import { Command as Command14 } from "commander";
16334
- import chalk16 from "chalk";
16468
+ import { Command as Command16 } from "commander";
16469
+ import chalk18 from "chalk";
16335
16470
  import * as readline from "readline";
16336
- 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) => {
16471
+ var deleteCommand = new Command16().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) => {
16337
16472
  try {
16338
16473
  const listResponse = await apiClient.get("/api/images");
16339
16474
  if (!listResponse.ok) {
@@ -16345,7 +16480,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16345
16480
  const data = await listResponse.json();
16346
16481
  const image = data.images.find((img) => img.alias === name);
16347
16482
  if (!image) {
16348
- console.error(chalk16.red(`Image not found: ${name}`));
16483
+ console.error(chalk18.red(`Image not found: ${name}`));
16349
16484
  process.exit(1);
16350
16485
  }
16351
16486
  if (!options.force) {
@@ -16355,7 +16490,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16355
16490
  });
16356
16491
  const answer = await new Promise((resolve2) => {
16357
16492
  rl.question(
16358
- chalk16.yellow(`Delete image "${name}"? [y/N] `),
16493
+ chalk18.yellow(`Delete image "${name}"? [y/N] `),
16359
16494
  (answer2) => {
16360
16495
  rl.close();
16361
16496
  resolve2(answer2);
@@ -16363,7 +16498,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16363
16498
  );
16364
16499
  });
16365
16500
  if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16366
- console.log(chalk16.gray("Cancelled."));
16501
+ console.log(chalk18.gray("Cancelled."));
16367
16502
  return;
16368
16503
  }
16369
16504
  }
@@ -16374,27 +16509,27 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16374
16509
  error43.error?.message || "Failed to delete image"
16375
16510
  );
16376
16511
  }
16377
- console.log(chalk16.green(`Deleted image: ${name}`));
16512
+ console.log(chalk18.green(`Deleted image: ${name}`));
16378
16513
  } catch (error43) {
16379
16514
  if (error43 instanceof Error) {
16380
16515
  if (error43.message.includes("Not authenticated")) {
16381
- console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16516
+ console.error(chalk18.red("Not authenticated. Run: vm0 auth login"));
16382
16517
  } else {
16383
- console.error(chalk16.red(`Error: ${error43.message}`));
16518
+ console.error(chalk18.red(`Error: ${error43.message}`));
16384
16519
  }
16385
16520
  } else {
16386
- console.error(chalk16.red("An unexpected error occurred"));
16521
+ console.error(chalk18.red("An unexpected error occurred"));
16387
16522
  }
16388
16523
  process.exit(1);
16389
16524
  }
16390
16525
  });
16391
16526
 
16392
16527
  // src/commands/image/index.ts
16393
- var imageCommand = new Command15().name("image").description("Manage custom images").addCommand(buildCommand).addCommand(listCommand).addCommand(deleteCommand);
16528
+ var imageCommand = new Command17().name("image").description("Manage custom images").addCommand(buildCommand).addCommand(listCommand).addCommand(deleteCommand);
16394
16529
 
16395
16530
  // src/commands/logs/index.ts
16396
- import { Command as Command16 } from "commander";
16397
- import chalk17 from "chalk";
16531
+ import { Command as Command18 } from "commander";
16532
+ import chalk19 from "chalk";
16398
16533
 
16399
16534
  // src/lib/time-parser.ts
16400
16535
  function parseTime(timeStr) {
@@ -16441,7 +16576,7 @@ function parseRelativeTime(value, unit) {
16441
16576
  }
16442
16577
 
16443
16578
  // src/commands/logs/index.ts
16444
- function formatBytes5(bytes) {
16579
+ function formatBytes7(bytes) {
16445
16580
  if (bytes === 0) return "0 B";
16446
16581
  const k = 1024;
16447
16582
  const sizes = ["B", "KB", "MB", "GB"];
@@ -16451,28 +16586,28 @@ function formatBytes5(bytes) {
16451
16586
  function formatMetric(metric) {
16452
16587
  const memPercent = (metric.mem_used / metric.mem_total * 100).toFixed(1);
16453
16588
  const diskPercent = (metric.disk_used / metric.disk_total * 100).toFixed(1);
16454
- return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${formatBytes5(metric.mem_used)}/${formatBytes5(metric.mem_total)} (${memPercent}%) | Disk: ${formatBytes5(metric.disk_used)}/${formatBytes5(metric.disk_total)} (${diskPercent}%)`;
16589
+ return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${formatBytes7(metric.mem_used)}/${formatBytes7(metric.mem_total)} (${memPercent}%) | Disk: ${formatBytes7(metric.disk_used)}/${formatBytes7(metric.disk_total)} (${diskPercent}%)`;
16455
16590
  }
16456
16591
  function formatNetworkLog(entry) {
16457
16592
  let statusColor;
16458
16593
  if (entry.status >= 200 && entry.status < 300) {
16459
- statusColor = chalk17.green;
16594
+ statusColor = chalk19.green;
16460
16595
  } else if (entry.status >= 300 && entry.status < 400) {
16461
- statusColor = chalk17.yellow;
16596
+ statusColor = chalk19.yellow;
16462
16597
  } else if (entry.status >= 400) {
16463
- statusColor = chalk17.red;
16598
+ statusColor = chalk19.red;
16464
16599
  } else {
16465
- statusColor = chalk17.gray;
16600
+ statusColor = chalk19.gray;
16466
16601
  }
16467
16602
  let latencyColor;
16468
16603
  if (entry.latency_ms < 500) {
16469
- latencyColor = chalk17.green;
16604
+ latencyColor = chalk19.green;
16470
16605
  } else if (entry.latency_ms < 2e3) {
16471
- latencyColor = chalk17.yellow;
16606
+ latencyColor = chalk19.yellow;
16472
16607
  } else {
16473
- latencyColor = chalk17.red;
16608
+ latencyColor = chalk19.red;
16474
16609
  }
16475
- return `[${entry.timestamp}] ${chalk17.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk17.gray(entry.url)}`;
16610
+ return `[${entry.timestamp}] ${chalk19.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes7(entry.request_size)}/${formatBytes7(entry.response_size)} ${chalk19.gray(entry.url)}`;
16476
16611
  }
16477
16612
  function renderAgentEvent(event) {
16478
16613
  const parsed = ClaudeEventParser.parse(
@@ -16492,7 +16627,7 @@ function getLogType(options) {
16492
16627
  ].filter(Boolean).length;
16493
16628
  if (selected > 1) {
16494
16629
  console.error(
16495
- chalk17.red(
16630
+ chalk19.red(
16496
16631
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
16497
16632
  )
16498
16633
  );
@@ -16503,7 +16638,7 @@ function getLogType(options) {
16503
16638
  if (options.network) return "network";
16504
16639
  return "agent";
16505
16640
  }
16506
- var logsCommand = new Command16().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(
16641
+ var logsCommand = new Command18().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(
16507
16642
  "--since <time>",
16508
16643
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
16509
16644
  ).option(
@@ -16545,7 +16680,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
16545
16680
  async function showAgentEvents(runId, options) {
16546
16681
  const response = await apiClient.getAgentEvents(runId, options);
16547
16682
  if (response.events.length === 0) {
16548
- console.log(chalk17.yellow("No agent events found for this run."));
16683
+ console.log(chalk19.yellow("No agent events found for this run."));
16549
16684
  return;
16550
16685
  }
16551
16686
  for (const event of response.events) {
@@ -16554,7 +16689,7 @@ async function showAgentEvents(runId, options) {
16554
16689
  if (response.hasMore) {
16555
16690
  console.log();
16556
16691
  console.log(
16557
- chalk17.gray(
16692
+ chalk19.gray(
16558
16693
  `Showing ${response.events.length} events. Use --limit to see more.`
16559
16694
  )
16560
16695
  );
@@ -16563,21 +16698,21 @@ async function showAgentEvents(runId, options) {
16563
16698
  async function showSystemLog(runId, options) {
16564
16699
  const response = await apiClient.getSystemLog(runId, options);
16565
16700
  if (!response.systemLog) {
16566
- console.log(chalk17.yellow("No system log found for this run."));
16701
+ console.log(chalk19.yellow("No system log found for this run."));
16567
16702
  return;
16568
16703
  }
16569
16704
  console.log(response.systemLog);
16570
16705
  if (response.hasMore) {
16571
16706
  console.log();
16572
16707
  console.log(
16573
- chalk17.gray("More log entries available. Use --limit to see more.")
16708
+ chalk19.gray("More log entries available. Use --limit to see more.")
16574
16709
  );
16575
16710
  }
16576
16711
  }
16577
16712
  async function showMetrics(runId, options) {
16578
16713
  const response = await apiClient.getMetrics(runId, options);
16579
16714
  if (response.metrics.length === 0) {
16580
- console.log(chalk17.yellow("No metrics found for this run."));
16715
+ console.log(chalk19.yellow("No metrics found for this run."));
16581
16716
  return;
16582
16717
  }
16583
16718
  for (const metric of response.metrics) {
@@ -16586,7 +16721,7 @@ async function showMetrics(runId, options) {
16586
16721
  if (response.hasMore) {
16587
16722
  console.log();
16588
16723
  console.log(
16589
- chalk17.gray(
16724
+ chalk19.gray(
16590
16725
  `Showing ${response.metrics.length} metrics. Use --limit to see more.`
16591
16726
  )
16592
16727
  );
@@ -16596,7 +16731,7 @@ async function showNetworkLogs(runId, options) {
16596
16731
  const response = await apiClient.getNetworkLogs(runId, options);
16597
16732
  if (response.networkLogs.length === 0) {
16598
16733
  console.log(
16599
- chalk17.yellow(
16734
+ chalk19.yellow(
16600
16735
  "No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
16601
16736
  )
16602
16737
  );
@@ -16608,7 +16743,7 @@ async function showNetworkLogs(runId, options) {
16608
16743
  if (response.hasMore) {
16609
16744
  console.log();
16610
16745
  console.log(
16611
- chalk17.gray(
16746
+ chalk19.gray(
16612
16747
  `Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
16613
16748
  )
16614
16749
  );
@@ -16617,25 +16752,25 @@ async function showNetworkLogs(runId, options) {
16617
16752
  function handleError(error43, runId) {
16618
16753
  if (error43 instanceof Error) {
16619
16754
  if (error43.message.includes("Not authenticated")) {
16620
- console.error(chalk17.red("Not authenticated. Run: vm0 auth login"));
16755
+ console.error(chalk19.red("Not authenticated. Run: vm0 auth login"));
16621
16756
  } else if (error43.message.includes("not found")) {
16622
- console.error(chalk17.red(`Run not found: ${runId}`));
16757
+ console.error(chalk19.red(`Run not found: ${runId}`));
16623
16758
  } else if (error43.message.includes("Invalid time format")) {
16624
- console.error(chalk17.red(error43.message));
16759
+ console.error(chalk19.red(error43.message));
16625
16760
  } else {
16626
- console.error(chalk17.red("Failed to fetch logs"));
16627
- console.error(chalk17.gray(` ${error43.message}`));
16761
+ console.error(chalk19.red("Failed to fetch logs"));
16762
+ console.error(chalk19.gray(` ${error43.message}`));
16628
16763
  }
16629
16764
  } else {
16630
- console.error(chalk17.red("An unexpected error occurred"));
16765
+ console.error(chalk19.red("An unexpected error occurred"));
16631
16766
  }
16632
16767
  }
16633
16768
 
16634
16769
  // src/index.ts
16635
- var program = new Command17();
16636
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.13.1");
16770
+ var program = new Command19();
16771
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.14.1");
16637
16772
  program.command("info").description("Display environment information").action(async () => {
16638
- console.log(chalk18.cyan("System Information:"));
16773
+ console.log(chalk20.cyan("System Information:"));
16639
16774
  console.log(`Node Version: ${process.version}`);
16640
16775
  console.log(`Platform: ${process.platform}`);
16641
16776
  console.log(`Architecture: ${process.arch}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.13.1",
3
+ "version": "4.14.1",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",