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