@vm0/cli 4.9.0 → 4.11.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 +266 -101
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
 
8
8
  // src/index.ts
9
9
  import { Command as Command17 } from "commander";
10
- import chalk17 from "chalk";
10
+ import chalk18 from "chalk";
11
11
 
12
12
  // src/lib/auth.ts
13
13
  import chalk from "chalk";
@@ -1200,10 +1200,13 @@ var EventRenderer = class {
1200
1200
  * Render run failed state
1201
1201
  * Note: This is run lifecycle status, not an event
1202
1202
  */
1203
- static renderRunFailed(error43) {
1203
+ static renderRunFailed(error43, runId) {
1204
1204
  console.log("");
1205
1205
  console.log(chalk3.red("\u2717 Run failed"));
1206
1206
  console.log(` Error: ${chalk3.red(error43 || "Unknown error")}`);
1207
+ console.log(
1208
+ chalk3.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
1209
+ );
1207
1210
  }
1208
1211
  static renderInit(event, prefix, suffix) {
1209
1212
  console.log(
@@ -14596,11 +14599,14 @@ async function pollEvents(runId, options) {
14596
14599
  };
14597
14600
  } else if (runStatus === "failed") {
14598
14601
  complete = true;
14599
- EventRenderer.renderRunFailed(response.run.error);
14602
+ EventRenderer.renderRunFailed(response.run.error, runId);
14600
14603
  result = { succeeded: false, runId };
14601
14604
  } else if (runStatus === "timeout") {
14602
14605
  complete = true;
14603
14606
  console.error(chalk4.red("\n\u2717 Run timed out"));
14607
+ console.error(
14608
+ chalk4.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
14609
+ );
14604
14610
  result = { succeeded: false, runId };
14605
14611
  }
14606
14612
  if (!complete) {
@@ -15719,17 +15725,116 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
15719
15725
 
15720
15726
  // src/commands/cook.ts
15721
15727
  import { Command as Command11 } from "commander";
15722
- import chalk12 from "chalk";
15723
- import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
15724
- import { existsSync as existsSync5 } from "fs";
15728
+ import chalk13 from "chalk";
15729
+ import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
15730
+ import { existsSync as existsSync5, readFileSync } from "fs";
15725
15731
  import path12 from "path";
15726
- import { spawn } from "child_process";
15732
+ import { spawn as spawn2 } from "child_process";
15727
15733
  import { parse as parseYaml3 } from "yaml";
15734
+ import { config as dotenvConfig2 } from "dotenv";
15735
+
15736
+ // src/lib/update-checker.ts
15737
+ import https from "https";
15738
+ import { spawn } from "child_process";
15739
+ import chalk12 from "chalk";
15740
+ var PACKAGE_NAME = "@vm0/cli";
15741
+ var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
15742
+ var TIMEOUT_MS = 5e3;
15743
+ function escapeForShell(str) {
15744
+ return `"${str.replace(/"/g, '\\"')}"`;
15745
+ }
15746
+ function buildRerunCommand(prompt) {
15747
+ if (prompt) {
15748
+ return `vm0 cook ${escapeForShell(prompt)}`;
15749
+ }
15750
+ return "vm0 cook";
15751
+ }
15752
+ function getLatestVersion() {
15753
+ return new Promise((resolve2) => {
15754
+ const req = https.get(NPM_REGISTRY_URL, (res) => {
15755
+ let data = "";
15756
+ res.on("data", (chunk) => {
15757
+ data += chunk.toString();
15758
+ });
15759
+ res.on("end", () => {
15760
+ try {
15761
+ const json2 = JSON.parse(data);
15762
+ resolve2(json2.version ?? null);
15763
+ } catch {
15764
+ resolve2(null);
15765
+ }
15766
+ });
15767
+ });
15768
+ req.on("error", () => {
15769
+ resolve2(null);
15770
+ });
15771
+ req.setTimeout(TIMEOUT_MS, () => {
15772
+ req.destroy();
15773
+ resolve2(null);
15774
+ });
15775
+ });
15776
+ }
15777
+ function performUpgrade() {
15778
+ return new Promise((resolve2) => {
15779
+ const npm = process.platform === "win32" ? "npm.cmd" : "npm";
15780
+ const child = spawn(npm, ["install", "-g", `${PACKAGE_NAME}@latest`], {
15781
+ stdio: "inherit",
15782
+ shell: process.platform === "win32"
15783
+ });
15784
+ child.on("close", (code) => {
15785
+ resolve2(code === 0);
15786
+ });
15787
+ child.on("error", () => {
15788
+ resolve2(false);
15789
+ });
15790
+ });
15791
+ }
15792
+ async function checkAndUpgrade(currentVersion, prompt) {
15793
+ const latestVersion = await getLatestVersion();
15794
+ if (latestVersion === null) {
15795
+ console.log(chalk12.yellow("Warning: Could not check for updates"));
15796
+ console.log();
15797
+ return false;
15798
+ }
15799
+ if (latestVersion === currentVersion) {
15800
+ return false;
15801
+ }
15802
+ console.log(chalk12.yellow("vm0 is currently in Early Access (EA)."));
15803
+ console.log(
15804
+ chalk12.yellow(
15805
+ `Current version: ${currentVersion} -> Latest version: ${latestVersion}`
15806
+ )
15807
+ );
15808
+ console.log(
15809
+ chalk12.yellow(
15810
+ "Please always use the latest version for best compatibility."
15811
+ )
15812
+ );
15813
+ console.log();
15814
+ console.log("Upgrading...");
15815
+ const success2 = await performUpgrade();
15816
+ if (success2) {
15817
+ console.log(chalk12.green(`Upgraded to ${latestVersion}`));
15818
+ console.log();
15819
+ console.log("To continue, run:");
15820
+ console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
15821
+ return true;
15822
+ }
15823
+ console.log();
15824
+ console.log(chalk12.red("Upgrade failed. Please run manually:"));
15825
+ console.log(chalk12.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
15826
+ console.log();
15827
+ console.log("Then re-run:");
15828
+ console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
15829
+ return true;
15830
+ }
15831
+
15832
+ // src/commands/cook.ts
15728
15833
  var CONFIG_FILE3 = "vm0.yaml";
15729
15834
  var ARTIFACT_DIR = "artifact";
15730
15835
  function execVm0Command(args, options = {}) {
15731
15836
  return new Promise((resolve2, reject) => {
15732
- const proc = spawn("vm0", args, {
15837
+ const proc = spawn2("vm0", args, {
15733
15838
  cwd: options.cwd,
15734
15839
  stdio: options.silent ? "pipe" : ["inherit", "inherit", "inherit"],
15735
15840
  shell: process.platform === "win32"
@@ -15758,7 +15863,7 @@ function execVm0Command(args, options = {}) {
15758
15863
  }
15759
15864
  function execVm0RunWithCapture(args, options = {}) {
15760
15865
  return new Promise((resolve2, reject) => {
15761
- const proc = spawn("vm0", args, {
15866
+ const proc = spawn2("vm0", args, {
15762
15867
  cwd: options.cwd,
15763
15868
  stdio: ["inherit", "pipe", "pipe"],
15764
15869
  shell: process.platform === "win32"
@@ -15802,11 +15907,53 @@ function parseArtifactVersionFromCompletion(output, artifactName) {
15802
15907
  function escapeRegExp(str) {
15803
15908
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15804
15909
  }
15910
+ function extractRequiredVarNames(config2) {
15911
+ const refs = extractVariableReferences(config2);
15912
+ const grouped = groupVariablesBySource(refs);
15913
+ const varNames = grouped.vars.map((r) => r.name);
15914
+ const secretNames = grouped.secrets.map((r) => r.name);
15915
+ return [.../* @__PURE__ */ new Set([...varNames, ...secretNames])];
15916
+ }
15917
+ function checkMissingVariables(varNames, envFilePath) {
15918
+ let dotenvValues = {};
15919
+ if (existsSync5(envFilePath)) {
15920
+ const result = dotenvConfig2({ path: envFilePath });
15921
+ if (result.parsed) {
15922
+ dotenvValues = result.parsed;
15923
+ }
15924
+ }
15925
+ const missing = [];
15926
+ for (const name of varNames) {
15927
+ const inEnv = process.env[name] !== void 0;
15928
+ const inDotenv = dotenvValues[name] !== void 0;
15929
+ if (!inEnv && !inDotenv) {
15930
+ missing.push(name);
15931
+ }
15932
+ }
15933
+ return missing;
15934
+ }
15935
+ async function generateEnvPlaceholders(missingVars, envFilePath) {
15936
+ const placeholders = missingVars.map((name) => `${name}=`).join("\n");
15937
+ if (existsSync5(envFilePath)) {
15938
+ const existingContent = readFileSync(envFilePath, "utf8");
15939
+ const needsNewline = existingContent.length > 0 && !existingContent.endsWith("\n");
15940
+ const prefix = needsNewline ? "\n" : "";
15941
+ await appendFile(envFilePath, `${prefix}${placeholders}
15942
+ `);
15943
+ } else {
15944
+ await writeFile5(envFilePath, `${placeholders}
15945
+ `);
15946
+ }
15947
+ }
15805
15948
  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) => {
15949
+ const shouldExit = await checkAndUpgrade("4.11.0", prompt);
15950
+ if (shouldExit) {
15951
+ process.exit(0);
15952
+ }
15806
15953
  const cwd = process.cwd();
15807
- console.log(chalk12.blue(`Reading config: ${CONFIG_FILE3}`));
15954
+ console.log(chalk13.blue(`Reading config: ${CONFIG_FILE3}`));
15808
15955
  if (!existsSync5(CONFIG_FILE3)) {
15809
- console.error(chalk12.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15956
+ console.error(chalk13.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15810
15957
  process.exit(1);
15811
15958
  }
15812
15959
  let config2;
@@ -15814,32 +15961,50 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15814
15961
  const content = await readFile5(CONFIG_FILE3, "utf8");
15815
15962
  config2 = parseYaml3(content);
15816
15963
  } catch (error43) {
15817
- console.error(chalk12.red("\u2717 Invalid YAML format"));
15964
+ console.error(chalk13.red("\u2717 Invalid YAML format"));
15818
15965
  if (error43 instanceof Error) {
15819
- console.error(chalk12.gray(` ${error43.message}`));
15966
+ console.error(chalk13.gray(` ${error43.message}`));
15820
15967
  }
15821
15968
  process.exit(1);
15822
15969
  }
15823
15970
  const validation = validateAgentCompose(config2);
15824
15971
  if (!validation.valid) {
15825
- console.error(chalk12.red(`\u2717 ${validation.error}`));
15972
+ console.error(chalk13.red(`\u2717 ${validation.error}`));
15826
15973
  process.exit(1);
15827
15974
  }
15828
15975
  const agentNames = Object.keys(config2.agents);
15829
15976
  const agentName = agentNames[0];
15830
15977
  const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
15831
15978
  console.log(
15832
- chalk12.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15979
+ chalk13.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15833
15980
  );
15981
+ const requiredVarNames = extractRequiredVarNames(config2);
15982
+ if (requiredVarNames.length > 0) {
15983
+ const envFilePath = path12.join(cwd, ".env");
15984
+ const missingVars = checkMissingVariables(requiredVarNames, envFilePath);
15985
+ if (missingVars.length > 0) {
15986
+ await generateEnvPlaceholders(missingVars, envFilePath);
15987
+ console.log();
15988
+ console.log(
15989
+ chalk13.yellow(
15990
+ `\u26A0 Missing environment variables. Please fill in values in .env file:`
15991
+ )
15992
+ );
15993
+ for (const varName of missingVars) {
15994
+ console.log(chalk13.yellow(` ${varName}`));
15995
+ }
15996
+ process.exit(1);
15997
+ }
15998
+ }
15834
15999
  if (config2.volumes && Object.keys(config2.volumes).length > 0) {
15835
16000
  console.log();
15836
- console.log(chalk12.blue("Processing volumes..."));
16001
+ console.log(chalk13.blue("Processing volumes..."));
15837
16002
  for (const volumeConfig of Object.values(config2.volumes)) {
15838
16003
  const volumeDir = path12.join(cwd, volumeConfig.name);
15839
- console.log(chalk12.gray(` ${volumeConfig.name}/`));
16004
+ console.log(chalk13.gray(` ${volumeConfig.name}/`));
15840
16005
  if (!existsSync5(volumeDir)) {
15841
16006
  console.error(
15842
- chalk12.red(
16007
+ chalk13.red(
15843
16008
  ` \u2717 Directory not found. Create the directory and add files first.`
15844
16009
  )
15845
16010
  );
@@ -15852,30 +16017,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15852
16017
  cwd: volumeDir,
15853
16018
  silent: true
15854
16019
  });
15855
- console.log(chalk12.green(` \u2713 Initialized`));
16020
+ console.log(chalk13.green(` \u2713 Initialized`));
15856
16021
  }
15857
16022
  await execVm0Command(["volume", "push"], {
15858
16023
  cwd: volumeDir,
15859
16024
  silent: true
15860
16025
  });
15861
- console.log(chalk12.green(` \u2713 Pushed`));
16026
+ console.log(chalk13.green(` \u2713 Pushed`));
15862
16027
  } catch (error43) {
15863
- console.error(chalk12.red(` \u2717 Failed`));
16028
+ console.error(chalk13.red(` \u2717 Failed`));
15864
16029
  if (error43 instanceof Error) {
15865
- console.error(chalk12.gray(` ${error43.message}`));
16030
+ console.error(chalk13.gray(` ${error43.message}`));
15866
16031
  }
15867
16032
  process.exit(1);
15868
16033
  }
15869
16034
  }
15870
16035
  }
15871
16036
  console.log();
15872
- console.log(chalk12.blue("Processing artifact..."));
16037
+ console.log(chalk13.blue("Processing artifact..."));
15873
16038
  const artifactDir = path12.join(cwd, ARTIFACT_DIR);
15874
- console.log(chalk12.gray(` ${ARTIFACT_DIR}/`));
16039
+ console.log(chalk13.gray(` ${ARTIFACT_DIR}/`));
15875
16040
  try {
15876
16041
  if (!existsSync5(artifactDir)) {
15877
16042
  await mkdir5(artifactDir, { recursive: true });
15878
- console.log(chalk12.green(` \u2713 Created directory`));
16043
+ console.log(chalk13.green(` \u2713 Created directory`));
15879
16044
  }
15880
16045
  const existingConfig = await readStorageConfig(artifactDir);
15881
16046
  if (!existingConfig) {
@@ -15883,38 +16048,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15883
16048
  cwd: artifactDir,
15884
16049
  silent: true
15885
16050
  });
15886
- console.log(chalk12.green(` \u2713 Initialized`));
16051
+ console.log(chalk13.green(` \u2713 Initialized`));
15887
16052
  }
15888
16053
  await execVm0Command(["artifact", "push"], {
15889
16054
  cwd: artifactDir,
15890
16055
  silent: true
15891
16056
  });
15892
- console.log(chalk12.green(` \u2713 Pushed`));
16057
+ console.log(chalk13.green(` \u2713 Pushed`));
15893
16058
  } catch (error43) {
15894
- console.error(chalk12.red(` \u2717 Failed`));
16059
+ console.error(chalk13.red(` \u2717 Failed`));
15895
16060
  if (error43 instanceof Error) {
15896
- console.error(chalk12.gray(` ${error43.message}`));
16061
+ console.error(chalk13.gray(` ${error43.message}`));
15897
16062
  }
15898
16063
  process.exit(1);
15899
16064
  }
15900
16065
  console.log();
15901
- console.log(chalk12.blue("Uploading compose..."));
16066
+ console.log(chalk13.blue("Uploading compose..."));
15902
16067
  try {
15903
16068
  await execVm0Command(["compose", CONFIG_FILE3], {
15904
16069
  cwd,
15905
16070
  silent: true
15906
16071
  });
15907
- console.log(chalk12.green(`\u2713 Compose uploaded: ${agentName}`));
16072
+ console.log(chalk13.green(`\u2713 Compose uploaded: ${agentName}`));
15908
16073
  } catch (error43) {
15909
- console.error(chalk12.red(`\u2717 Compose failed`));
16074
+ console.error(chalk13.red(`\u2717 Compose failed`));
15910
16075
  if (error43 instanceof Error) {
15911
- console.error(chalk12.gray(` ${error43.message}`));
16076
+ console.error(chalk13.gray(` ${error43.message}`));
15912
16077
  }
15913
16078
  process.exit(1);
15914
16079
  }
15915
16080
  if (prompt) {
15916
16081
  console.log();
15917
- console.log(chalk12.blue(`Running agent: ${agentName}`));
16082
+ console.log(chalk13.blue(`Running agent: ${agentName}`));
15918
16083
  console.log();
15919
16084
  let runOutput;
15920
16085
  try {
@@ -15935,17 +16100,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15935
16100
  );
15936
16101
  if (serverVersion) {
15937
16102
  console.log();
15938
- console.log(chalk12.blue("Pulling updated artifact..."));
16103
+ console.log(chalk13.blue("Pulling updated artifact..."));
15939
16104
  try {
15940
16105
  await execVm0Command(["artifact", "pull"], {
15941
16106
  cwd: artifactDir,
15942
16107
  silent: true
15943
16108
  });
15944
- console.log(chalk12.green(`\u2713 Artifact pulled (${serverVersion})`));
16109
+ console.log(chalk13.green(`\u2713 Artifact pulled (${serverVersion})`));
15945
16110
  } catch (error43) {
15946
- console.error(chalk12.red(`\u2717 Artifact pull failed`));
16111
+ console.error(chalk13.red(`\u2717 Artifact pull failed`));
15947
16112
  if (error43 instanceof Error) {
15948
- console.error(chalk12.gray(` ${error43.message}`));
16113
+ console.error(chalk13.gray(` ${error43.message}`));
15949
16114
  }
15950
16115
  }
15951
16116
  }
@@ -15953,7 +16118,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15953
16118
  console.log();
15954
16119
  console.log(" Run your agent:");
15955
16120
  console.log(
15956
- chalk12.cyan(
16121
+ chalk13.cyan(
15957
16122
  ` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
15958
16123
  )
15959
16124
  );
@@ -15965,7 +16130,7 @@ import { Command as Command15 } from "commander";
15965
16130
 
15966
16131
  // src/commands/image/build.ts
15967
16132
  import { Command as Command12 } from "commander";
15968
- import chalk13 from "chalk";
16133
+ import chalk14 from "chalk";
15969
16134
  import { readFile as readFile6 } from "fs/promises";
15970
16135
  import { existsSync as existsSync6 } from "fs";
15971
16136
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
@@ -15973,13 +16138,13 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15973
16138
  async (options) => {
15974
16139
  const { file: file2, name, deleteExisting } = options;
15975
16140
  if (!existsSync6(file2)) {
15976
- console.error(chalk13.red(`\u2717 Dockerfile not found: ${file2}`));
16141
+ console.error(chalk14.red(`\u2717 Dockerfile not found: ${file2}`));
15977
16142
  process.exit(1);
15978
16143
  }
15979
16144
  const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
15980
16145
  if (!nameRegex.test(name)) {
15981
16146
  console.error(
15982
- chalk13.red(
16147
+ chalk14.red(
15983
16148
  "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
15984
16149
  )
15985
16150
  );
@@ -15987,7 +16152,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15987
16152
  }
15988
16153
  if (name.startsWith("vm0-")) {
15989
16154
  console.error(
15990
- chalk13.red(
16155
+ chalk14.red(
15991
16156
  '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
15992
16157
  )
15993
16158
  );
@@ -15995,8 +16160,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15995
16160
  }
15996
16161
  try {
15997
16162
  const dockerfile = await readFile6(file2, "utf8");
15998
- console.log(chalk13.blue(`Building image: ${name}`));
15999
- console.log(chalk13.gray(` Dockerfile: ${file2}`));
16163
+ console.log(chalk14.blue(`Building image: ${name}`));
16164
+ console.log(chalk14.gray(` Dockerfile: ${file2}`));
16000
16165
  console.log();
16001
16166
  const buildInfo = await apiClient.createImage({
16002
16167
  dockerfile,
@@ -16004,7 +16169,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16004
16169
  deleteExisting
16005
16170
  });
16006
16171
  const { imageId, buildId } = buildInfo;
16007
- console.log(chalk13.gray(` Build ID: ${buildId}`));
16172
+ console.log(chalk14.gray(` Build ID: ${buildId}`));
16008
16173
  console.log();
16009
16174
  let logsOffset = 0;
16010
16175
  let status = "building";
@@ -16020,7 +16185,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16020
16185
  }
16021
16186
  const statusData = await statusResponse.json();
16022
16187
  for (const log of statusData.logs) {
16023
- console.log(chalk13.gray(` ${log}`));
16188
+ console.log(chalk14.gray(` ${log}`));
16024
16189
  }
16025
16190
  logsOffset = statusData.logsOffset;
16026
16191
  status = statusData.status;
@@ -16030,27 +16195,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16030
16195
  }
16031
16196
  console.log();
16032
16197
  if (status === "ready") {
16033
- console.log(chalk13.green(`\u2713 Image built: ${name}`));
16198
+ console.log(chalk14.green(`\u2713 Image built: ${name}`));
16034
16199
  console.log();
16035
16200
  console.log("Use in vm0.yaml:");
16036
- console.log(chalk13.cyan(` agents:`));
16037
- console.log(chalk13.cyan(` your-agent:`));
16038
- console.log(chalk13.cyan(` image: "${name}"`));
16201
+ console.log(chalk14.cyan(` agents:`));
16202
+ console.log(chalk14.cyan(` your-agent:`));
16203
+ console.log(chalk14.cyan(` image: "${name}"`));
16039
16204
  } else {
16040
- console.error(chalk13.red(`\u2717 Build failed`));
16205
+ console.error(chalk14.red(`\u2717 Build failed`));
16041
16206
  process.exit(1);
16042
16207
  }
16043
16208
  } catch (error43) {
16044
16209
  if (error43 instanceof Error) {
16045
16210
  if (error43.message.includes("Not authenticated")) {
16046
16211
  console.error(
16047
- chalk13.red("\u2717 Not authenticated. Run: vm0 auth login")
16212
+ chalk14.red("\u2717 Not authenticated. Run: vm0 auth login")
16048
16213
  );
16049
16214
  } else {
16050
- console.error(chalk13.red(`\u2717 ${error43.message}`));
16215
+ console.error(chalk14.red(`\u2717 ${error43.message}`));
16051
16216
  }
16052
16217
  } else {
16053
- console.error(chalk13.red("\u2717 An unexpected error occurred"));
16218
+ console.error(chalk14.red("\u2717 An unexpected error occurred"));
16054
16219
  }
16055
16220
  process.exit(1);
16056
16221
  }
@@ -16059,7 +16224,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16059
16224
 
16060
16225
  // src/commands/image/list.ts
16061
16226
  import { Command as Command13 } from "commander";
16062
- import chalk14 from "chalk";
16227
+ import chalk15 from "chalk";
16063
16228
  var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
16064
16229
  try {
16065
16230
  const response = await apiClient.get("/api/images");
@@ -16072,43 +16237,43 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16072
16237
  const data = await response.json();
16073
16238
  const { images } = data;
16074
16239
  if (images.length === 0) {
16075
- console.log(chalk14.gray("No images found."));
16240
+ console.log(chalk15.gray("No images found."));
16076
16241
  console.log();
16077
16242
  console.log("Build your first image:");
16078
16243
  console.log(
16079
- chalk14.cyan(" vm0 image build --file Dockerfile --name my-image")
16244
+ chalk15.cyan(" vm0 image build --file Dockerfile --name my-image")
16080
16245
  );
16081
16246
  return;
16082
16247
  }
16083
- console.log(chalk14.bold("Your images:"));
16248
+ console.log(chalk15.bold("Your images:"));
16084
16249
  console.log();
16085
16250
  console.log(
16086
- chalk14.gray(
16251
+ chalk15.gray(
16087
16252
  `${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16088
16253
  )
16089
16254
  );
16090
- console.log(chalk14.gray("-".repeat(62)));
16255
+ console.log(chalk15.gray("-".repeat(62)));
16091
16256
  for (const image of images) {
16092
- const statusColor = image.status === "ready" ? chalk14.green : image.status === "building" ? chalk14.yellow : chalk14.red;
16257
+ const statusColor = image.status === "ready" ? chalk15.green : image.status === "building" ? chalk15.yellow : chalk15.red;
16093
16258
  const createdAt = new Date(image.createdAt).toLocaleString();
16094
16259
  console.log(
16095
16260
  `${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16096
16261
  );
16097
16262
  if (image.status === "error" && image.errorMessage) {
16098
- console.log(chalk14.red(` Error: ${image.errorMessage}`));
16263
+ console.log(chalk15.red(` Error: ${image.errorMessage}`));
16099
16264
  }
16100
16265
  }
16101
16266
  console.log();
16102
- console.log(chalk14.gray(`Total: ${images.length} image(s)`));
16267
+ console.log(chalk15.gray(`Total: ${images.length} image(s)`));
16103
16268
  } catch (error43) {
16104
16269
  if (error43 instanceof Error) {
16105
16270
  if (error43.message.includes("Not authenticated")) {
16106
- console.error(chalk14.red("Not authenticated. Run: vm0 auth login"));
16271
+ console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16107
16272
  } else {
16108
- console.error(chalk14.red(`Error: ${error43.message}`));
16273
+ console.error(chalk15.red(`Error: ${error43.message}`));
16109
16274
  }
16110
16275
  } else {
16111
- console.error(chalk14.red("An unexpected error occurred"));
16276
+ console.error(chalk15.red("An unexpected error occurred"));
16112
16277
  }
16113
16278
  process.exit(1);
16114
16279
  }
@@ -16116,7 +16281,7 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16116
16281
 
16117
16282
  // src/commands/image/delete.ts
16118
16283
  import { Command as Command14 } from "commander";
16119
- import chalk15 from "chalk";
16284
+ import chalk16 from "chalk";
16120
16285
  import * as readline from "readline";
16121
16286
  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) => {
16122
16287
  try {
@@ -16130,7 +16295,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16130
16295
  const data = await listResponse.json();
16131
16296
  const image = data.images.find((img) => img.alias === name);
16132
16297
  if (!image) {
16133
- console.error(chalk15.red(`Image not found: ${name}`));
16298
+ console.error(chalk16.red(`Image not found: ${name}`));
16134
16299
  process.exit(1);
16135
16300
  }
16136
16301
  if (!options.force) {
@@ -16140,7 +16305,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16140
16305
  });
16141
16306
  const answer = await new Promise((resolve2) => {
16142
16307
  rl.question(
16143
- chalk15.yellow(`Delete image "${name}"? [y/N] `),
16308
+ chalk16.yellow(`Delete image "${name}"? [y/N] `),
16144
16309
  (answer2) => {
16145
16310
  rl.close();
16146
16311
  resolve2(answer2);
@@ -16148,7 +16313,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16148
16313
  );
16149
16314
  });
16150
16315
  if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16151
- console.log(chalk15.gray("Cancelled."));
16316
+ console.log(chalk16.gray("Cancelled."));
16152
16317
  return;
16153
16318
  }
16154
16319
  }
@@ -16159,16 +16324,16 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16159
16324
  error43.error?.message || "Failed to delete image"
16160
16325
  );
16161
16326
  }
16162
- console.log(chalk15.green(`Deleted image: ${name}`));
16327
+ console.log(chalk16.green(`Deleted image: ${name}`));
16163
16328
  } catch (error43) {
16164
16329
  if (error43 instanceof Error) {
16165
16330
  if (error43.message.includes("Not authenticated")) {
16166
- console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16331
+ console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16167
16332
  } else {
16168
- console.error(chalk15.red(`Error: ${error43.message}`));
16333
+ console.error(chalk16.red(`Error: ${error43.message}`));
16169
16334
  }
16170
16335
  } else {
16171
- console.error(chalk15.red("An unexpected error occurred"));
16336
+ console.error(chalk16.red("An unexpected error occurred"));
16172
16337
  }
16173
16338
  process.exit(1);
16174
16339
  }
@@ -16179,7 +16344,7 @@ var imageCommand = new Command15().name("image").description("Manage custom imag
16179
16344
 
16180
16345
  // src/commands/logs/index.ts
16181
16346
  import { Command as Command16 } from "commander";
16182
- import chalk16 from "chalk";
16347
+ import chalk17 from "chalk";
16183
16348
 
16184
16349
  // src/lib/time-parser.ts
16185
16350
  function parseTime(timeStr) {
@@ -16241,23 +16406,23 @@ function formatMetric(metric) {
16241
16406
  function formatNetworkLog(entry) {
16242
16407
  let statusColor;
16243
16408
  if (entry.status >= 200 && entry.status < 300) {
16244
- statusColor = chalk16.green;
16409
+ statusColor = chalk17.green;
16245
16410
  } else if (entry.status >= 300 && entry.status < 400) {
16246
- statusColor = chalk16.yellow;
16411
+ statusColor = chalk17.yellow;
16247
16412
  } else if (entry.status >= 400) {
16248
- statusColor = chalk16.red;
16413
+ statusColor = chalk17.red;
16249
16414
  } else {
16250
- statusColor = chalk16.gray;
16415
+ statusColor = chalk17.gray;
16251
16416
  }
16252
16417
  let latencyColor;
16253
16418
  if (entry.latency_ms < 500) {
16254
- latencyColor = chalk16.green;
16419
+ latencyColor = chalk17.green;
16255
16420
  } else if (entry.latency_ms < 2e3) {
16256
- latencyColor = chalk16.yellow;
16421
+ latencyColor = chalk17.yellow;
16257
16422
  } else {
16258
- latencyColor = chalk16.red;
16423
+ latencyColor = chalk17.red;
16259
16424
  }
16260
- return `[${entry.timestamp}] ${chalk16.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk16.gray(entry.url)}`;
16425
+ 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)}`;
16261
16426
  }
16262
16427
  function renderAgentEvent(event) {
16263
16428
  const parsed = ClaudeEventParser.parse(
@@ -16277,7 +16442,7 @@ function getLogType(options) {
16277
16442
  ].filter(Boolean).length;
16278
16443
  if (selected > 1) {
16279
16444
  console.error(
16280
- chalk16.red(
16445
+ chalk17.red(
16281
16446
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
16282
16447
  )
16283
16448
  );
@@ -16330,7 +16495,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
16330
16495
  async function showAgentEvents(runId, options) {
16331
16496
  const response = await apiClient.getAgentEvents(runId, options);
16332
16497
  if (response.events.length === 0) {
16333
- console.log(chalk16.yellow("No agent events found for this run."));
16498
+ console.log(chalk17.yellow("No agent events found for this run."));
16334
16499
  return;
16335
16500
  }
16336
16501
  for (const event of response.events) {
@@ -16339,7 +16504,7 @@ async function showAgentEvents(runId, options) {
16339
16504
  if (response.hasMore) {
16340
16505
  console.log();
16341
16506
  console.log(
16342
- chalk16.gray(
16507
+ chalk17.gray(
16343
16508
  `Showing ${response.events.length} events. Use --limit to see more.`
16344
16509
  )
16345
16510
  );
@@ -16348,21 +16513,21 @@ async function showAgentEvents(runId, options) {
16348
16513
  async function showSystemLog(runId, options) {
16349
16514
  const response = await apiClient.getSystemLog(runId, options);
16350
16515
  if (!response.systemLog) {
16351
- console.log(chalk16.yellow("No system log found for this run."));
16516
+ console.log(chalk17.yellow("No system log found for this run."));
16352
16517
  return;
16353
16518
  }
16354
16519
  console.log(response.systemLog);
16355
16520
  if (response.hasMore) {
16356
16521
  console.log();
16357
16522
  console.log(
16358
- chalk16.gray("More log entries available. Use --limit to see more.")
16523
+ chalk17.gray("More log entries available. Use --limit to see more.")
16359
16524
  );
16360
16525
  }
16361
16526
  }
16362
16527
  async function showMetrics(runId, options) {
16363
16528
  const response = await apiClient.getMetrics(runId, options);
16364
16529
  if (response.metrics.length === 0) {
16365
- console.log(chalk16.yellow("No metrics found for this run."));
16530
+ console.log(chalk17.yellow("No metrics found for this run."));
16366
16531
  return;
16367
16532
  }
16368
16533
  for (const metric of response.metrics) {
@@ -16371,7 +16536,7 @@ async function showMetrics(runId, options) {
16371
16536
  if (response.hasMore) {
16372
16537
  console.log();
16373
16538
  console.log(
16374
- chalk16.gray(
16539
+ chalk17.gray(
16375
16540
  `Showing ${response.metrics.length} metrics. Use --limit to see more.`
16376
16541
  )
16377
16542
  );
@@ -16381,7 +16546,7 @@ async function showNetworkLogs(runId, options) {
16381
16546
  const response = await apiClient.getNetworkLogs(runId, options);
16382
16547
  if (response.networkLogs.length === 0) {
16383
16548
  console.log(
16384
- chalk16.yellow(
16549
+ chalk17.yellow(
16385
16550
  "No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
16386
16551
  )
16387
16552
  );
@@ -16393,7 +16558,7 @@ async function showNetworkLogs(runId, options) {
16393
16558
  if (response.hasMore) {
16394
16559
  console.log();
16395
16560
  console.log(
16396
- chalk16.gray(
16561
+ chalk17.gray(
16397
16562
  `Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
16398
16563
  )
16399
16564
  );
@@ -16402,25 +16567,25 @@ async function showNetworkLogs(runId, options) {
16402
16567
  function handleError(error43, runId) {
16403
16568
  if (error43 instanceof Error) {
16404
16569
  if (error43.message.includes("Not authenticated")) {
16405
- console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16570
+ console.error(chalk17.red("Not authenticated. Run: vm0 auth login"));
16406
16571
  } else if (error43.message.includes("not found")) {
16407
- console.error(chalk16.red(`Run not found: ${runId}`));
16572
+ console.error(chalk17.red(`Run not found: ${runId}`));
16408
16573
  } else if (error43.message.includes("Invalid time format")) {
16409
- console.error(chalk16.red(error43.message));
16574
+ console.error(chalk17.red(error43.message));
16410
16575
  } else {
16411
- console.error(chalk16.red("Failed to fetch logs"));
16412
- console.error(chalk16.gray(` ${error43.message}`));
16576
+ console.error(chalk17.red("Failed to fetch logs"));
16577
+ console.error(chalk17.gray(` ${error43.message}`));
16413
16578
  }
16414
16579
  } else {
16415
- console.error(chalk16.red("An unexpected error occurred"));
16580
+ console.error(chalk17.red("An unexpected error occurred"));
16416
16581
  }
16417
16582
  }
16418
16583
 
16419
16584
  // src/index.ts
16420
16585
  var program = new Command17();
16421
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.9.0");
16586
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.11.0");
16422
16587
  program.command("info").description("Display environment information").action(async () => {
16423
- console.log(chalk17.cyan("System Information:"));
16588
+ console.log(chalk18.cyan("System Information:"));
16424
16589
  console.log(`Node Version: ${process.version}`);
16425
16590
  console.log(`Platform: ${process.platform}`);
16426
16591
  console.log(`Architecture: ${process.arch}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.9.0",
3
+ "version": "4.11.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",