@vm0/cli 4.15.0 → 4.16.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 +256 -111
  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 Command22 } from "commander";
10
- import chalk22 from "chalk";
9
+ import { Command as Command23 } from "commander";
10
+ import chalk23 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -14652,6 +14652,8 @@ var buildStatusSchema = external_exports.enum(["building", "ready", "error"]);
14652
14652
  var imageInfoSchema = external_exports.object({
14653
14653
  id: external_exports.string(),
14654
14654
  alias: external_exports.string(),
14655
+ versionId: external_exports.string().nullable(),
14656
+ // null for legacy images without versioning
14655
14657
  status: external_exports.string(),
14656
14658
  errorMessage: external_exports.string().nullable(),
14657
14659
  createdAt: external_exports.coerce.date(),
@@ -14671,7 +14673,9 @@ var createImageRequestSchema = external_exports.object({
14671
14673
  var createImageResponseSchema = external_exports.object({
14672
14674
  buildId: external_exports.string(),
14673
14675
  imageId: external_exports.string(),
14674
- alias: external_exports.string()
14676
+ alias: external_exports.string(),
14677
+ versionId: external_exports.string()
14678
+ // nanoid(8), unique per build
14675
14679
  });
14676
14680
  var buildStatusResponseSchema = external_exports.object({
14677
14681
  status: buildStatusSchema,
@@ -14887,6 +14891,12 @@ var scopeContract = c11.router({
14887
14891
  }
14888
14892
  });
14889
14893
 
14894
+ // ../../packages/core/src/version-id.ts
14895
+ var VERSION_ID_DISPLAY_LENGTH = 8;
14896
+ function formatVersionIdForDisplay(versionId) {
14897
+ return versionId.slice(0, VERSION_ID_DISPLAY_LENGTH);
14898
+ }
14899
+
14890
14900
  // src/commands/run.ts
14891
14901
  function collectKeyValue(value, previous) {
14892
14902
  const [key, ...valueParts] = value.split("=");
@@ -16254,7 +16264,7 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
16254
16264
  }
16255
16265
  }
16256
16266
  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) => {
16257
- const shouldExit = await checkAndUpgrade("4.15.0", prompt);
16267
+ const shouldExit = await checkAndUpgrade("4.16.1", prompt);
16258
16268
  if (shouldExit) {
16259
16269
  process.exit(0);
16260
16270
  }
@@ -16410,7 +16420,7 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
16410
16420
  console.log();
16411
16421
  console.log(chalk15.blue("Pulling updated artifact..."));
16412
16422
  try {
16413
- await execVm0Command(["artifact", "pull"], {
16423
+ await execVm0Command(["artifact", "pull", serverVersion], {
16414
16424
  cwd: artifactDir,
16415
16425
  silent: true
16416
16426
  });
@@ -16434,7 +16444,7 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
16434
16444
  });
16435
16445
 
16436
16446
  // src/commands/image/index.ts
16437
- import { Command as Command17 } from "commander";
16447
+ import { Command as Command18 } from "commander";
16438
16448
 
16439
16449
  // src/commands/image/build.ts
16440
16450
  import { Command as Command14 } from "commander";
@@ -16467,16 +16477,16 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
16467
16477
  process.exit(1);
16468
16478
  }
16469
16479
  try {
16480
+ const scope = await apiClient.getScope();
16470
16481
  const dockerfile = await readFile6(file2, "utf8");
16471
- console.log(chalk16.blue(`Building image: ${name}`));
16472
- console.log(chalk16.gray(` Dockerfile: ${file2}`));
16482
+ console.log(chalk16.blue(`Building image: @${scope.slug}/${name}`));
16473
16483
  console.log();
16474
16484
  const buildInfo = await apiClient.createImage({
16475
16485
  dockerfile,
16476
16486
  alias: name,
16477
16487
  deleteExisting
16478
16488
  });
16479
- const { imageId, buildId } = buildInfo;
16489
+ const { imageId, buildId, versionId } = buildInfo;
16480
16490
  console.log(chalk16.gray(` Build ID: ${buildId}`));
16481
16491
  console.log();
16482
16492
  let logsOffset = 0;
@@ -16503,12 +16513,12 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
16503
16513
  }
16504
16514
  console.log();
16505
16515
  if (status === "ready") {
16506
- console.log(chalk16.green(`\u2713 Image built: ${name}`));
16507
- console.log();
16508
- console.log("Use in vm0.yaml:");
16509
- console.log(chalk16.cyan(` agents:`));
16510
- console.log(chalk16.cyan(` your-agent:`));
16511
- console.log(chalk16.cyan(` image: "${name}"`));
16516
+ const shortVersion = formatVersionIdForDisplay(versionId);
16517
+ console.log(
16518
+ chalk16.green(
16519
+ `\u2713 Image built: @${scope.slug}/${name}:${shortVersion}`
16520
+ )
16521
+ );
16512
16522
  } else {
16513
16523
  console.error(chalk16.red(`\u2717 Build failed`));
16514
16524
  process.exit(1);
@@ -16555,24 +16565,43 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
16555
16565
  }
16556
16566
  console.log(chalk17.bold("Your images:"));
16557
16567
  console.log();
16568
+ const imagesByAlias = /* @__PURE__ */ new Map();
16569
+ for (const image of images) {
16570
+ const list2 = imagesByAlias.get(image.alias) || [];
16571
+ list2.push(image);
16572
+ imagesByAlias.set(image.alias, list2);
16573
+ }
16574
+ const latestVersions = /* @__PURE__ */ new Map();
16575
+ for (const [alias, versions] of imagesByAlias) {
16576
+ const latestReady = versions.find((v) => v.status === "ready");
16577
+ latestVersions.set(alias, latestReady?.versionId || null);
16578
+ }
16558
16579
  console.log(
16559
16580
  chalk17.gray(
16560
- `${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16581
+ `${"NAME".padEnd(40)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16561
16582
  )
16562
16583
  );
16563
- console.log(chalk17.gray("-".repeat(62)));
16584
+ console.log(chalk17.gray("-".repeat(72)));
16564
16585
  for (const image of images) {
16565
16586
  const statusColor = image.status === "ready" ? chalk17.green : image.status === "building" ? chalk17.yellow : chalk17.red;
16566
16587
  const createdAt = new Date(image.createdAt).toLocaleString();
16588
+ let displayName = image.alias;
16589
+ if (image.versionId) {
16590
+ const shortVersion = formatVersionIdForDisplay(image.versionId);
16591
+ displayName = `${image.alias}:${shortVersion}`;
16592
+ if (image.status === "ready" && latestVersions.get(image.alias) === image.versionId) {
16593
+ displayName = `${displayName} ${chalk17.cyan("(latest)")}`;
16594
+ }
16595
+ }
16567
16596
  console.log(
16568
- `${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16597
+ `${displayName.padEnd(40)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16569
16598
  );
16570
16599
  if (image.status === "error" && image.errorMessage) {
16571
16600
  console.log(chalk17.red(` Error: ${image.errorMessage}`));
16572
16601
  }
16573
16602
  }
16574
16603
  console.log();
16575
- console.log(chalk17.gray(`Total: ${images.length} image(s)`));
16604
+ console.log(chalk17.gray(`Total: ${images.length} version(s)`));
16576
16605
  } catch (error43) {
16577
16606
  if (error43 instanceof Error) {
16578
16607
  if (error43.message.includes("Not authenticated")) {
@@ -16591,68 +16620,184 @@ var listCommand = new Command15().name("list").alias("ls").description("List you
16591
16620
  import { Command as Command16 } from "commander";
16592
16621
  import chalk18 from "chalk";
16593
16622
  import * as readline from "readline";
16594
- 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) => {
16623
+ var deleteCommand = new Command16().name("delete").alias("rm").description("Delete a custom image or specific version").argument("<name>", "Image name or name:version to delete").option("-f, --force", "Skip confirmation prompt").option("--all", "Delete all versions of the image").action(
16624
+ async (nameArg, options) => {
16625
+ try {
16626
+ const colonIndex = nameArg.lastIndexOf(":");
16627
+ const hasVersion = colonIndex > 0;
16628
+ const name = hasVersion ? nameArg.slice(0, colonIndex) : nameArg;
16629
+ const versionId = hasVersion ? nameArg.slice(colonIndex + 1) : null;
16630
+ const listResponse = await apiClient.get("/api/images");
16631
+ if (!listResponse.ok) {
16632
+ const error43 = await listResponse.json();
16633
+ throw new Error(
16634
+ error43.error?.message || "Failed to list images"
16635
+ );
16636
+ }
16637
+ const data = await listResponse.json();
16638
+ let imagesToDelete;
16639
+ if (versionId) {
16640
+ const matchingVersions = data.images.filter(
16641
+ (img) => img.alias === name && img.versionId && img.versionId.startsWith(versionId.toLowerCase())
16642
+ );
16643
+ if (matchingVersions.length === 0) {
16644
+ console.error(chalk18.red(`Image version not found: ${nameArg}`));
16645
+ process.exit(1);
16646
+ }
16647
+ if (matchingVersions.length > 1) {
16648
+ console.error(
16649
+ chalk18.red(
16650
+ `Ambiguous version prefix "${versionId}". Please use more characters.`
16651
+ )
16652
+ );
16653
+ process.exit(1);
16654
+ }
16655
+ imagesToDelete = [matchingVersions[0]];
16656
+ } else if (options.all) {
16657
+ imagesToDelete = data.images.filter((img) => img.alias === name);
16658
+ if (imagesToDelete.length === 0) {
16659
+ console.error(chalk18.red(`Image not found: ${name}`));
16660
+ process.exit(1);
16661
+ }
16662
+ } else {
16663
+ const matchingImages = data.images.filter(
16664
+ (img) => img.alias === name
16665
+ );
16666
+ if (matchingImages.length === 0) {
16667
+ console.error(chalk18.red(`Image not found: ${name}`));
16668
+ process.exit(1);
16669
+ }
16670
+ const latestReady = matchingImages.find(
16671
+ (img) => img.status === "ready"
16672
+ );
16673
+ if (latestReady) {
16674
+ imagesToDelete = [latestReady];
16675
+ } else {
16676
+ imagesToDelete = [matchingImages[0]];
16677
+ }
16678
+ }
16679
+ const firstImage = imagesToDelete[0];
16680
+ const firstVersionDisplay = firstImage.versionId ? `:${formatVersionIdForDisplay(firstImage.versionId)}` : "";
16681
+ const confirmMsg = imagesToDelete.length === 1 ? `Delete image "${firstImage.alias}${firstVersionDisplay}"?` : `Delete ${imagesToDelete.length} versions of "${name}"?`;
16682
+ if (!options.force) {
16683
+ const rl = readline.createInterface({
16684
+ input: process.stdin,
16685
+ output: process.stdout
16686
+ });
16687
+ const answer = await new Promise((resolve2) => {
16688
+ rl.question(chalk18.yellow(`${confirmMsg} [y/N] `), (answer2) => {
16689
+ rl.close();
16690
+ resolve2(answer2);
16691
+ });
16692
+ });
16693
+ if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16694
+ console.log(chalk18.gray("Cancelled."));
16695
+ return;
16696
+ }
16697
+ }
16698
+ for (const image of imagesToDelete) {
16699
+ const deleteResponse = await apiClient.delete(
16700
+ `/api/images/${image.id}`
16701
+ );
16702
+ if (!deleteResponse.ok) {
16703
+ const error43 = await deleteResponse.json();
16704
+ throw new Error(
16705
+ error43.error?.message || "Failed to delete image"
16706
+ );
16707
+ }
16708
+ const displayName = image.versionId ? `${image.alias}:${formatVersionIdForDisplay(image.versionId)}` : image.alias;
16709
+ console.log(chalk18.green(`Deleted image: ${displayName}`));
16710
+ }
16711
+ } catch (error43) {
16712
+ if (error43 instanceof Error) {
16713
+ if (error43.message.includes("Not authenticated")) {
16714
+ console.error(chalk18.red("Not authenticated. Run: vm0 auth login"));
16715
+ } else {
16716
+ console.error(chalk18.red(`Error: ${error43.message}`));
16717
+ }
16718
+ } else {
16719
+ console.error(chalk18.red("An unexpected error occurred"));
16720
+ }
16721
+ process.exit(1);
16722
+ }
16723
+ }
16724
+ );
16725
+
16726
+ // src/commands/image/versions.ts
16727
+ import { Command as Command17 } from "commander";
16728
+ import chalk19 from "chalk";
16729
+ var versionsCommand = new Command17().name("versions").description("List all versions of an image").argument("<name>", "Name of the image").action(async (name) => {
16595
16730
  try {
16596
- const listResponse = await apiClient.get("/api/images");
16597
- if (!listResponse.ok) {
16598
- const error43 = await listResponse.json();
16731
+ const response = await apiClient.get("/api/images");
16732
+ if (!response.ok) {
16733
+ const error43 = await response.json();
16599
16734
  throw new Error(
16600
16735
  error43.error?.message || "Failed to list images"
16601
16736
  );
16602
16737
  }
16603
- const data = await listResponse.json();
16604
- const image = data.images.find((img) => img.alias === name);
16605
- if (!image) {
16606
- console.error(chalk18.red(`Image not found: ${name}`));
16738
+ const data = await response.json();
16739
+ const versions = data.images.filter((img) => img.alias === name);
16740
+ if (versions.length === 0) {
16741
+ console.error(chalk19.red(`Image not found: ${name}`));
16607
16742
  process.exit(1);
16608
16743
  }
16609
- if (!options.force) {
16610
- const rl = readline.createInterface({
16611
- input: process.stdin,
16612
- output: process.stdout
16613
- });
16614
- const answer = await new Promise((resolve2) => {
16615
- rl.question(
16616
- chalk18.yellow(`Delete image "${name}"? [y/N] `),
16617
- (answer2) => {
16618
- rl.close();
16619
- resolve2(answer2);
16620
- }
16621
- );
16622
- });
16623
- if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16624
- console.log(chalk18.gray("Cancelled."));
16625
- return;
16744
+ const latestReady = versions.find((v) => v.status === "ready");
16745
+ const latestVersionId = latestReady?.versionId || null;
16746
+ console.log(chalk19.bold(`Versions of ${name}:`));
16747
+ console.log();
16748
+ console.log(
16749
+ chalk19.gray(
16750
+ `${"VERSION".padEnd(20)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(24)}`
16751
+ )
16752
+ );
16753
+ console.log(chalk19.gray("-".repeat(56)));
16754
+ for (const version2 of versions) {
16755
+ const statusColor = version2.status === "ready" ? chalk19.green : version2.status === "building" ? chalk19.yellow : chalk19.red;
16756
+ const createdAt = new Date(version2.createdAt).toLocaleString();
16757
+ let versionDisplay = version2.versionId ? formatVersionIdForDisplay(version2.versionId) : "(legacy)";
16758
+ if (version2.status === "ready" && version2.versionId === latestVersionId) {
16759
+ versionDisplay = `${versionDisplay} ${chalk19.cyan("(latest)")}`;
16760
+ }
16761
+ console.log(
16762
+ `${versionDisplay.padEnd(20)} ${statusColor(version2.status.padEnd(12))} ${createdAt.padEnd(24)}`
16763
+ );
16764
+ if (version2.status === "error" && version2.errorMessage) {
16765
+ console.log(chalk19.red(` Error: ${version2.errorMessage}`));
16626
16766
  }
16627
16767
  }
16628
- const deleteResponse = await apiClient.delete(`/api/images/${image.id}`);
16629
- if (!deleteResponse.ok) {
16630
- const error43 = await deleteResponse.json();
16631
- throw new Error(
16632
- error43.error?.message || "Failed to delete image"
16768
+ console.log();
16769
+ console.log(chalk19.gray(`Total: ${versions.length} version(s)`));
16770
+ console.log();
16771
+ console.log(chalk19.gray("Usage:"));
16772
+ console.log(chalk19.gray(` image: "${name}" # uses latest`));
16773
+ if (latestVersionId) {
16774
+ const shortVersion = formatVersionIdForDisplay(latestVersionId);
16775
+ console.log(
16776
+ chalk19.gray(
16777
+ ` image: "${name}:${shortVersion}" # pin to specific version`
16778
+ )
16633
16779
  );
16634
16780
  }
16635
- console.log(chalk18.green(`Deleted image: ${name}`));
16636
16781
  } catch (error43) {
16637
16782
  if (error43 instanceof Error) {
16638
16783
  if (error43.message.includes("Not authenticated")) {
16639
- console.error(chalk18.red("Not authenticated. Run: vm0 auth login"));
16784
+ console.error(chalk19.red("Not authenticated. Run: vm0 auth login"));
16640
16785
  } else {
16641
- console.error(chalk18.red(`Error: ${error43.message}`));
16786
+ console.error(chalk19.red(`Error: ${error43.message}`));
16642
16787
  }
16643
16788
  } else {
16644
- console.error(chalk18.red("An unexpected error occurred"));
16789
+ console.error(chalk19.red("An unexpected error occurred"));
16645
16790
  }
16646
16791
  process.exit(1);
16647
16792
  }
16648
16793
  });
16649
16794
 
16650
16795
  // src/commands/image/index.ts
16651
- var imageCommand = new Command17().name("image").description("Manage custom images").addCommand(buildCommand).addCommand(listCommand).addCommand(deleteCommand);
16796
+ var imageCommand = new Command18().name("image").description("Manage custom images").addCommand(buildCommand).addCommand(listCommand).addCommand(deleteCommand).addCommand(versionsCommand);
16652
16797
 
16653
16798
  // src/commands/logs/index.ts
16654
- import { Command as Command18 } from "commander";
16655
- import chalk19 from "chalk";
16799
+ import { Command as Command19 } from "commander";
16800
+ import chalk20 from "chalk";
16656
16801
 
16657
16802
  // src/lib/time-parser.ts
16658
16803
  function parseTime(timeStr) {
@@ -16714,23 +16859,23 @@ function formatMetric(metric) {
16714
16859
  function formatNetworkLog(entry) {
16715
16860
  let statusColor;
16716
16861
  if (entry.status >= 200 && entry.status < 300) {
16717
- statusColor = chalk19.green;
16862
+ statusColor = chalk20.green;
16718
16863
  } else if (entry.status >= 300 && entry.status < 400) {
16719
- statusColor = chalk19.yellow;
16864
+ statusColor = chalk20.yellow;
16720
16865
  } else if (entry.status >= 400) {
16721
- statusColor = chalk19.red;
16866
+ statusColor = chalk20.red;
16722
16867
  } else {
16723
- statusColor = chalk19.gray;
16868
+ statusColor = chalk20.gray;
16724
16869
  }
16725
16870
  let latencyColor;
16726
16871
  if (entry.latency_ms < 500) {
16727
- latencyColor = chalk19.green;
16872
+ latencyColor = chalk20.green;
16728
16873
  } else if (entry.latency_ms < 2e3) {
16729
- latencyColor = chalk19.yellow;
16874
+ latencyColor = chalk20.yellow;
16730
16875
  } else {
16731
- latencyColor = chalk19.red;
16876
+ latencyColor = chalk20.red;
16732
16877
  }
16733
- 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)}`;
16878
+ return `[${entry.timestamp}] ${chalk20.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes7(entry.request_size)}/${formatBytes7(entry.response_size)} ${chalk20.gray(entry.url)}`;
16734
16879
  }
16735
16880
  function renderAgentEvent(event) {
16736
16881
  const parsed = ClaudeEventParser.parse(
@@ -16750,7 +16895,7 @@ function getLogType(options) {
16750
16895
  ].filter(Boolean).length;
16751
16896
  if (selected > 1) {
16752
16897
  console.error(
16753
- chalk19.red(
16898
+ chalk20.red(
16754
16899
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
16755
16900
  )
16756
16901
  );
@@ -16761,7 +16906,7 @@ function getLogType(options) {
16761
16906
  if (options.network) return "network";
16762
16907
  return "agent";
16763
16908
  }
16764
- 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(
16909
+ var logsCommand = new Command19().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(
16765
16910
  "--since <time>",
16766
16911
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
16767
16912
  ).option(
@@ -16803,7 +16948,7 @@ var logsCommand = new Command18().name("logs").description("View logs for an age
16803
16948
  async function showAgentEvents(runId, options) {
16804
16949
  const response = await apiClient.getAgentEvents(runId, options);
16805
16950
  if (response.events.length === 0) {
16806
- console.log(chalk19.yellow("No agent events found for this run."));
16951
+ console.log(chalk20.yellow("No agent events found for this run."));
16807
16952
  return;
16808
16953
  }
16809
16954
  for (const event of response.events) {
@@ -16812,7 +16957,7 @@ async function showAgentEvents(runId, options) {
16812
16957
  if (response.hasMore) {
16813
16958
  console.log();
16814
16959
  console.log(
16815
- chalk19.gray(
16960
+ chalk20.gray(
16816
16961
  `Showing ${response.events.length} events. Use --limit to see more.`
16817
16962
  )
16818
16963
  );
@@ -16821,21 +16966,21 @@ async function showAgentEvents(runId, options) {
16821
16966
  async function showSystemLog(runId, options) {
16822
16967
  const response = await apiClient.getSystemLog(runId, options);
16823
16968
  if (!response.systemLog) {
16824
- console.log(chalk19.yellow("No system log found for this run."));
16969
+ console.log(chalk20.yellow("No system log found for this run."));
16825
16970
  return;
16826
16971
  }
16827
16972
  console.log(response.systemLog);
16828
16973
  if (response.hasMore) {
16829
16974
  console.log();
16830
16975
  console.log(
16831
- chalk19.gray("More log entries available. Use --limit to see more.")
16976
+ chalk20.gray("More log entries available. Use --limit to see more.")
16832
16977
  );
16833
16978
  }
16834
16979
  }
16835
16980
  async function showMetrics(runId, options) {
16836
16981
  const response = await apiClient.getMetrics(runId, options);
16837
16982
  if (response.metrics.length === 0) {
16838
- console.log(chalk19.yellow("No metrics found for this run."));
16983
+ console.log(chalk20.yellow("No metrics found for this run."));
16839
16984
  return;
16840
16985
  }
16841
16986
  for (const metric of response.metrics) {
@@ -16844,7 +16989,7 @@ async function showMetrics(runId, options) {
16844
16989
  if (response.hasMore) {
16845
16990
  console.log();
16846
16991
  console.log(
16847
- chalk19.gray(
16992
+ chalk20.gray(
16848
16993
  `Showing ${response.metrics.length} metrics. Use --limit to see more.`
16849
16994
  )
16850
16995
  );
@@ -16854,7 +16999,7 @@ async function showNetworkLogs(runId, options) {
16854
16999
  const response = await apiClient.getNetworkLogs(runId, options);
16855
17000
  if (response.networkLogs.length === 0) {
16856
17001
  console.log(
16857
- chalk19.yellow(
17002
+ chalk20.yellow(
16858
17003
  "No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
16859
17004
  )
16860
17005
  );
@@ -16866,7 +17011,7 @@ async function showNetworkLogs(runId, options) {
16866
17011
  if (response.hasMore) {
16867
17012
  console.log();
16868
17013
  console.log(
16869
- chalk19.gray(
17014
+ chalk20.gray(
16870
17015
  `Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
16871
17016
  )
16872
17017
  );
@@ -16875,31 +17020,31 @@ async function showNetworkLogs(runId, options) {
16875
17020
  function handleError(error43, runId) {
16876
17021
  if (error43 instanceof Error) {
16877
17022
  if (error43.message.includes("Not authenticated")) {
16878
- console.error(chalk19.red("Not authenticated. Run: vm0 auth login"));
17023
+ console.error(chalk20.red("Not authenticated. Run: vm0 auth login"));
16879
17024
  } else if (error43.message.includes("not found")) {
16880
- console.error(chalk19.red(`Run not found: ${runId}`));
17025
+ console.error(chalk20.red(`Run not found: ${runId}`));
16881
17026
  } else if (error43.message.includes("Invalid time format")) {
16882
- console.error(chalk19.red(error43.message));
17027
+ console.error(chalk20.red(error43.message));
16883
17028
  } else {
16884
- console.error(chalk19.red("Failed to fetch logs"));
16885
- console.error(chalk19.gray(` ${error43.message}`));
17029
+ console.error(chalk20.red("Failed to fetch logs"));
17030
+ console.error(chalk20.gray(` ${error43.message}`));
16886
17031
  }
16887
17032
  } else {
16888
- console.error(chalk19.red("An unexpected error occurred"));
17033
+ console.error(chalk20.red("An unexpected error occurred"));
16889
17034
  }
16890
17035
  }
16891
17036
 
16892
17037
  // src/commands/scope/index.ts
16893
- import { Command as Command21 } from "commander";
17038
+ import { Command as Command22 } from "commander";
16894
17039
 
16895
17040
  // src/commands/scope/status.ts
16896
- import { Command as Command19 } from "commander";
16897
- import chalk20 from "chalk";
16898
- var statusCommand3 = new Command19().name("status").description("View current scope status").action(async () => {
17041
+ import { Command as Command20 } from "commander";
17042
+ import chalk21 from "chalk";
17043
+ var statusCommand3 = new Command20().name("status").description("View current scope status").action(async () => {
16899
17044
  try {
16900
17045
  const scope = await apiClient.getScope();
16901
- console.log(chalk20.cyan("Scope Information:"));
16902
- console.log(` Slug: ${chalk20.green("@" + scope.slug)}`);
17046
+ console.log(chalk21.cyan("Scope Information:"));
17047
+ console.log(` Slug: ${chalk21.green("@" + scope.slug)}`);
16903
17048
  console.log(` Type: ${scope.type}`);
16904
17049
  if (scope.displayName) {
16905
17050
  console.log(` Display Name: ${scope.displayName}`);
@@ -16910,29 +17055,29 @@ var statusCommand3 = new Command19().name("status").description("View current sc
16910
17055
  } catch (error43) {
16911
17056
  if (error43 instanceof Error) {
16912
17057
  if (error43.message.includes("Not authenticated")) {
16913
- console.error(chalk20.red("\u2717 Not authenticated. Run: vm0 auth login"));
17058
+ console.error(chalk21.red("\u2717 Not authenticated. Run: vm0 auth login"));
16914
17059
  } else if (error43.message.includes("No scope configured")) {
16915
- console.log(chalk20.yellow("No scope configured."));
17060
+ console.log(chalk21.yellow("No scope configured."));
16916
17061
  console.log();
16917
17062
  console.log("Set your scope with:");
16918
- console.log(chalk20.cyan(" vm0 scope set <slug>"));
17063
+ console.log(chalk21.cyan(" vm0 scope set <slug>"));
16919
17064
  console.log();
16920
17065
  console.log("Example:");
16921
- console.log(chalk20.gray(" vm0 scope set myusername"));
17066
+ console.log(chalk21.gray(" vm0 scope set myusername"));
16922
17067
  } else {
16923
- console.error(chalk20.red(`\u2717 ${error43.message}`));
17068
+ console.error(chalk21.red(`\u2717 ${error43.message}`));
16924
17069
  }
16925
17070
  } else {
16926
- console.error(chalk20.red("\u2717 An unexpected error occurred"));
17071
+ console.error(chalk21.red("\u2717 An unexpected error occurred"));
16927
17072
  }
16928
17073
  process.exit(1);
16929
17074
  }
16930
17075
  });
16931
17076
 
16932
17077
  // src/commands/scope/set.ts
16933
- import { Command as Command20 } from "commander";
16934
- import chalk21 from "chalk";
16935
- var setCommand = new Command20().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").option("--display-name <name>", "Display name for the scope").action(
17078
+ import { Command as Command21 } from "commander";
17079
+ import chalk22 from "chalk";
17080
+ var setCommand = new Command21().name("set").description("Set your scope slug").argument("<slug>", "The scope slug (e.g., your username)").option("--force", "Force change existing scope (may break references)").option("--display-name <name>", "Display name for the scope").action(
16936
17081
  async (slug, options) => {
16937
17082
  try {
16938
17083
  let existingScope;
@@ -16944,56 +17089,56 @@ var setCommand = new Command20().name("set").description("Set your scope slug").
16944
17089
  if (existingScope) {
16945
17090
  if (!options.force) {
16946
17091
  console.error(
16947
- chalk21.yellow(`You already have a scope: @${existingScope.slug}`)
17092
+ chalk22.yellow(`You already have a scope: @${existingScope.slug}`)
16948
17093
  );
16949
17094
  console.error();
16950
17095
  console.error("To change your scope, use --force:");
16951
- console.error(chalk21.cyan(` vm0 scope set ${slug} --force`));
17096
+ console.error(chalk22.cyan(` vm0 scope set ${slug} --force`));
16952
17097
  console.error();
16953
17098
  console.error(
16954
- chalk21.yellow(
17099
+ chalk22.yellow(
16955
17100
  "Warning: Changing your scope may break existing image references."
16956
17101
  )
16957
17102
  );
16958
17103
  process.exit(1);
16959
17104
  }
16960
17105
  scope = await apiClient.updateScope({ slug, force: true });
16961
- console.log(chalk21.green(`\u2713 Scope updated to @${scope.slug}`));
17106
+ console.log(chalk22.green(`\u2713 Scope updated to @${scope.slug}`));
16962
17107
  } else {
16963
17108
  scope = await apiClient.createScope({
16964
17109
  slug,
16965
17110
  displayName: options.displayName
16966
17111
  });
16967
- console.log(chalk21.green(`\u2713 Scope created: @${scope.slug}`));
17112
+ console.log(chalk22.green(`\u2713 Scope created: @${scope.slug}`));
16968
17113
  }
16969
17114
  console.log();
16970
17115
  console.log("Your images will now be namespaced as:");
16971
- console.log(chalk21.cyan(` @${scope.slug}/<image-name>`));
17116
+ console.log(chalk22.cyan(` @${scope.slug}/<image-name>`));
16972
17117
  } catch (error43) {
16973
17118
  if (error43 instanceof Error) {
16974
17119
  if (error43.message.includes("Not authenticated")) {
16975
17120
  console.error(
16976
- chalk21.red("\u2717 Not authenticated. Run: vm0 auth login")
17121
+ chalk22.red("\u2717 Not authenticated. Run: vm0 auth login")
16977
17122
  );
16978
17123
  } else if (error43.message.includes("already exists")) {
16979
17124
  console.error(
16980
- chalk21.red(
17125
+ chalk22.red(
16981
17126
  `\u2717 Scope "${slug}" is already taken. Please choose a different slug.`
16982
17127
  )
16983
17128
  );
16984
17129
  } else if (error43.message.includes("reserved")) {
16985
- console.error(chalk21.red(`\u2717 ${error43.message}`));
17130
+ console.error(chalk22.red(`\u2717 ${error43.message}`));
16986
17131
  } else if (error43.message.includes("vm0")) {
16987
17132
  console.error(
16988
- chalk21.red(
17133
+ chalk22.red(
16989
17134
  "\u2717 Scope slugs cannot start with 'vm0' (reserved for system use)"
16990
17135
  )
16991
17136
  );
16992
17137
  } else {
16993
- console.error(chalk21.red(`\u2717 ${error43.message}`));
17138
+ console.error(chalk22.red(`\u2717 ${error43.message}`));
16994
17139
  }
16995
17140
  } else {
16996
- console.error(chalk21.red("\u2717 An unexpected error occurred"));
17141
+ console.error(chalk22.red("\u2717 An unexpected error occurred"));
16997
17142
  }
16998
17143
  process.exit(1);
16999
17144
  }
@@ -17001,13 +17146,13 @@ var setCommand = new Command20().name("set").description("Set your scope slug").
17001
17146
  );
17002
17147
 
17003
17148
  // src/commands/scope/index.ts
17004
- var scopeCommand = new Command21().name("scope").description("Manage your scope (namespace for images)").addCommand(statusCommand3).addCommand(setCommand);
17149
+ var scopeCommand = new Command22().name("scope").description("Manage your scope (namespace for images)").addCommand(statusCommand3).addCommand(setCommand);
17005
17150
 
17006
17151
  // src/index.ts
17007
- var program = new Command22();
17008
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.15.0");
17152
+ var program = new Command23();
17153
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.16.1");
17009
17154
  program.command("info").description("Display environment information").action(async () => {
17010
- console.log(chalk22.cyan("System Information:"));
17155
+ console.log(chalk23.cyan("System Information:"));
17011
17156
  console.log(`Node Version: ${process.version}`);
17012
17157
  console.log(`Platform: ${process.platform}`);
17013
17158
  console.log(`Architecture: ${process.arch}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.15.0",
3
+ "version": "4.16.1",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",