@vm0/cli 4.10.0 → 4.12.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 +219 -99
  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";
@@ -163,6 +163,21 @@ async function checkAuthStatus() {
163
163
  console.log(chalk.blue("Using token from VM0_TOKEN environment variable"));
164
164
  }
165
165
  }
166
+ async function setupToken() {
167
+ const token = await getToken();
168
+ if (!token) {
169
+ console.error(chalk.red("Error: Not authenticated."));
170
+ console.error("");
171
+ console.error("To get a token for CI/CD:");
172
+ console.error(" 1. Run 'vm0 auth login' to authenticate");
173
+ console.error(" 2. Run 'vm0 auth setup-token' to get your token");
174
+ console.error(
175
+ " 3. Store the token in your CI/CD secrets (e.g., VM0_TOKEN)"
176
+ );
177
+ process.exit(1);
178
+ }
179
+ console.log(token);
180
+ }
166
181
 
167
182
  // src/commands/compose.ts
168
183
  import { Command } from "commander";
@@ -15725,18 +15740,116 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
15725
15740
 
15726
15741
  // src/commands/cook.ts
15727
15742
  import { Command as Command11 } from "commander";
15728
- import chalk12 from "chalk";
15743
+ import chalk13 from "chalk";
15729
15744
  import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
15730
15745
  import { existsSync as existsSync5, readFileSync } from "fs";
15731
15746
  import path12 from "path";
15732
- import { spawn } from "child_process";
15747
+ import { spawn as spawn2 } from "child_process";
15733
15748
  import { parse as parseYaml3 } from "yaml";
15734
15749
  import { config as dotenvConfig2 } from "dotenv";
15750
+
15751
+ // src/lib/update-checker.ts
15752
+ import https from "https";
15753
+ import { spawn } from "child_process";
15754
+ import chalk12 from "chalk";
15755
+ var PACKAGE_NAME = "@vm0/cli";
15756
+ var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
15757
+ var TIMEOUT_MS = 5e3;
15758
+ function escapeForShell(str) {
15759
+ return `"${str.replace(/"/g, '\\"')}"`;
15760
+ }
15761
+ function buildRerunCommand(prompt) {
15762
+ if (prompt) {
15763
+ return `vm0 cook ${escapeForShell(prompt)}`;
15764
+ }
15765
+ return "vm0 cook";
15766
+ }
15767
+ function getLatestVersion() {
15768
+ return new Promise((resolve2) => {
15769
+ const req = https.get(NPM_REGISTRY_URL, (res) => {
15770
+ let data = "";
15771
+ res.on("data", (chunk) => {
15772
+ data += chunk.toString();
15773
+ });
15774
+ res.on("end", () => {
15775
+ try {
15776
+ const json2 = JSON.parse(data);
15777
+ resolve2(json2.version ?? null);
15778
+ } catch {
15779
+ resolve2(null);
15780
+ }
15781
+ });
15782
+ });
15783
+ req.on("error", () => {
15784
+ resolve2(null);
15785
+ });
15786
+ req.setTimeout(TIMEOUT_MS, () => {
15787
+ req.destroy();
15788
+ resolve2(null);
15789
+ });
15790
+ });
15791
+ }
15792
+ function performUpgrade() {
15793
+ return new Promise((resolve2) => {
15794
+ const npm = process.platform === "win32" ? "npm.cmd" : "npm";
15795
+ const child = spawn(npm, ["install", "-g", `${PACKAGE_NAME}@latest`], {
15796
+ stdio: "inherit",
15797
+ shell: process.platform === "win32"
15798
+ });
15799
+ child.on("close", (code) => {
15800
+ resolve2(code === 0);
15801
+ });
15802
+ child.on("error", () => {
15803
+ resolve2(false);
15804
+ });
15805
+ });
15806
+ }
15807
+ async function checkAndUpgrade(currentVersion, prompt) {
15808
+ const latestVersion = await getLatestVersion();
15809
+ if (latestVersion === null) {
15810
+ console.log(chalk12.yellow("Warning: Could not check for updates"));
15811
+ console.log();
15812
+ return false;
15813
+ }
15814
+ if (latestVersion === currentVersion) {
15815
+ return false;
15816
+ }
15817
+ console.log(chalk12.yellow("vm0 is currently in Early Access (EA)."));
15818
+ console.log(
15819
+ chalk12.yellow(
15820
+ `Current version: ${currentVersion} -> Latest version: ${latestVersion}`
15821
+ )
15822
+ );
15823
+ console.log(
15824
+ chalk12.yellow(
15825
+ "Please always use the latest version for best compatibility."
15826
+ )
15827
+ );
15828
+ console.log();
15829
+ console.log("Upgrading...");
15830
+ const success2 = await performUpgrade();
15831
+ if (success2) {
15832
+ console.log(chalk12.green(`Upgraded to ${latestVersion}`));
15833
+ console.log();
15834
+ console.log("To continue, run:");
15835
+ console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
15836
+ return true;
15837
+ }
15838
+ console.log();
15839
+ console.log(chalk12.red("Upgrade failed. Please run manually:"));
15840
+ console.log(chalk12.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
15841
+ console.log();
15842
+ console.log("Then re-run:");
15843
+ console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
15844
+ return true;
15845
+ }
15846
+
15847
+ // src/commands/cook.ts
15735
15848
  var CONFIG_FILE3 = "vm0.yaml";
15736
15849
  var ARTIFACT_DIR = "artifact";
15737
15850
  function execVm0Command(args, options = {}) {
15738
15851
  return new Promise((resolve2, reject) => {
15739
- const proc = spawn("vm0", args, {
15852
+ const proc = spawn2("vm0", args, {
15740
15853
  cwd: options.cwd,
15741
15854
  stdio: options.silent ? "pipe" : ["inherit", "inherit", "inherit"],
15742
15855
  shell: process.platform === "win32"
@@ -15765,7 +15878,7 @@ function execVm0Command(args, options = {}) {
15765
15878
  }
15766
15879
  function execVm0RunWithCapture(args, options = {}) {
15767
15880
  return new Promise((resolve2, reject) => {
15768
- const proc = spawn("vm0", args, {
15881
+ const proc = spawn2("vm0", args, {
15769
15882
  cwd: options.cwd,
15770
15883
  stdio: ["inherit", "pipe", "pipe"],
15771
15884
  shell: process.platform === "win32"
@@ -15848,10 +15961,14 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
15848
15961
  }
15849
15962
  }
15850
15963
  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) => {
15964
+ const shouldExit = await checkAndUpgrade("4.12.0", prompt);
15965
+ if (shouldExit) {
15966
+ process.exit(0);
15967
+ }
15851
15968
  const cwd = process.cwd();
15852
- console.log(chalk12.blue(`Reading config: ${CONFIG_FILE3}`));
15969
+ console.log(chalk13.blue(`Reading config: ${CONFIG_FILE3}`));
15853
15970
  if (!existsSync5(CONFIG_FILE3)) {
15854
- console.error(chalk12.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15971
+ console.error(chalk13.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
15855
15972
  process.exit(1);
15856
15973
  }
15857
15974
  let config2;
@@ -15859,22 +15976,22 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15859
15976
  const content = await readFile5(CONFIG_FILE3, "utf8");
15860
15977
  config2 = parseYaml3(content);
15861
15978
  } catch (error43) {
15862
- console.error(chalk12.red("\u2717 Invalid YAML format"));
15979
+ console.error(chalk13.red("\u2717 Invalid YAML format"));
15863
15980
  if (error43 instanceof Error) {
15864
- console.error(chalk12.gray(` ${error43.message}`));
15981
+ console.error(chalk13.gray(` ${error43.message}`));
15865
15982
  }
15866
15983
  process.exit(1);
15867
15984
  }
15868
15985
  const validation = validateAgentCompose(config2);
15869
15986
  if (!validation.valid) {
15870
- console.error(chalk12.red(`\u2717 ${validation.error}`));
15987
+ console.error(chalk13.red(`\u2717 ${validation.error}`));
15871
15988
  process.exit(1);
15872
15989
  }
15873
15990
  const agentNames = Object.keys(config2.agents);
15874
15991
  const agentName = agentNames[0];
15875
15992
  const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
15876
15993
  console.log(
15877
- chalk12.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15994
+ chalk13.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
15878
15995
  );
15879
15996
  const requiredVarNames = extractRequiredVarNames(config2);
15880
15997
  if (requiredVarNames.length > 0) {
@@ -15884,25 +16001,25 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15884
16001
  await generateEnvPlaceholders(missingVars, envFilePath);
15885
16002
  console.log();
15886
16003
  console.log(
15887
- chalk12.yellow(
16004
+ chalk13.yellow(
15888
16005
  `\u26A0 Missing environment variables. Please fill in values in .env file:`
15889
16006
  )
15890
16007
  );
15891
16008
  for (const varName of missingVars) {
15892
- console.log(chalk12.yellow(` ${varName}`));
16009
+ console.log(chalk13.yellow(` ${varName}`));
15893
16010
  }
15894
16011
  process.exit(1);
15895
16012
  }
15896
16013
  }
15897
16014
  if (config2.volumes && Object.keys(config2.volumes).length > 0) {
15898
16015
  console.log();
15899
- console.log(chalk12.blue("Processing volumes..."));
16016
+ console.log(chalk13.blue("Processing volumes..."));
15900
16017
  for (const volumeConfig of Object.values(config2.volumes)) {
15901
16018
  const volumeDir = path12.join(cwd, volumeConfig.name);
15902
- console.log(chalk12.gray(` ${volumeConfig.name}/`));
16019
+ console.log(chalk13.gray(` ${volumeConfig.name}/`));
15903
16020
  if (!existsSync5(volumeDir)) {
15904
16021
  console.error(
15905
- chalk12.red(
16022
+ chalk13.red(
15906
16023
  ` \u2717 Directory not found. Create the directory and add files first.`
15907
16024
  )
15908
16025
  );
@@ -15915,30 +16032,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15915
16032
  cwd: volumeDir,
15916
16033
  silent: true
15917
16034
  });
15918
- console.log(chalk12.green(` \u2713 Initialized`));
16035
+ console.log(chalk13.green(` \u2713 Initialized`));
15919
16036
  }
15920
16037
  await execVm0Command(["volume", "push"], {
15921
16038
  cwd: volumeDir,
15922
16039
  silent: true
15923
16040
  });
15924
- console.log(chalk12.green(` \u2713 Pushed`));
16041
+ console.log(chalk13.green(` \u2713 Pushed`));
15925
16042
  } catch (error43) {
15926
- console.error(chalk12.red(` \u2717 Failed`));
16043
+ console.error(chalk13.red(` \u2717 Failed`));
15927
16044
  if (error43 instanceof Error) {
15928
- console.error(chalk12.gray(` ${error43.message}`));
16045
+ console.error(chalk13.gray(` ${error43.message}`));
15929
16046
  }
15930
16047
  process.exit(1);
15931
16048
  }
15932
16049
  }
15933
16050
  }
15934
16051
  console.log();
15935
- console.log(chalk12.blue("Processing artifact..."));
16052
+ console.log(chalk13.blue("Processing artifact..."));
15936
16053
  const artifactDir = path12.join(cwd, ARTIFACT_DIR);
15937
- console.log(chalk12.gray(` ${ARTIFACT_DIR}/`));
16054
+ console.log(chalk13.gray(` ${ARTIFACT_DIR}/`));
15938
16055
  try {
15939
16056
  if (!existsSync5(artifactDir)) {
15940
16057
  await mkdir5(artifactDir, { recursive: true });
15941
- console.log(chalk12.green(` \u2713 Created directory`));
16058
+ console.log(chalk13.green(` \u2713 Created directory`));
15942
16059
  }
15943
16060
  const existingConfig = await readStorageConfig(artifactDir);
15944
16061
  if (!existingConfig) {
@@ -15946,38 +16063,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15946
16063
  cwd: artifactDir,
15947
16064
  silent: true
15948
16065
  });
15949
- console.log(chalk12.green(` \u2713 Initialized`));
16066
+ console.log(chalk13.green(` \u2713 Initialized`));
15950
16067
  }
15951
16068
  await execVm0Command(["artifact", "push"], {
15952
16069
  cwd: artifactDir,
15953
16070
  silent: true
15954
16071
  });
15955
- console.log(chalk12.green(` \u2713 Pushed`));
16072
+ console.log(chalk13.green(` \u2713 Pushed`));
15956
16073
  } catch (error43) {
15957
- console.error(chalk12.red(` \u2717 Failed`));
16074
+ console.error(chalk13.red(` \u2717 Failed`));
15958
16075
  if (error43 instanceof Error) {
15959
- console.error(chalk12.gray(` ${error43.message}`));
16076
+ console.error(chalk13.gray(` ${error43.message}`));
15960
16077
  }
15961
16078
  process.exit(1);
15962
16079
  }
15963
16080
  console.log();
15964
- console.log(chalk12.blue("Uploading compose..."));
16081
+ console.log(chalk13.blue("Uploading compose..."));
15965
16082
  try {
15966
16083
  await execVm0Command(["compose", CONFIG_FILE3], {
15967
16084
  cwd,
15968
16085
  silent: true
15969
16086
  });
15970
- console.log(chalk12.green(`\u2713 Compose uploaded: ${agentName}`));
16087
+ console.log(chalk13.green(`\u2713 Compose uploaded: ${agentName}`));
15971
16088
  } catch (error43) {
15972
- console.error(chalk12.red(`\u2717 Compose failed`));
16089
+ console.error(chalk13.red(`\u2717 Compose failed`));
15973
16090
  if (error43 instanceof Error) {
15974
- console.error(chalk12.gray(` ${error43.message}`));
16091
+ console.error(chalk13.gray(` ${error43.message}`));
15975
16092
  }
15976
16093
  process.exit(1);
15977
16094
  }
15978
16095
  if (prompt) {
15979
16096
  console.log();
15980
- console.log(chalk12.blue(`Running agent: ${agentName}`));
16097
+ console.log(chalk13.blue(`Running agent: ${agentName}`));
15981
16098
  console.log();
15982
16099
  let runOutput;
15983
16100
  try {
@@ -15998,17 +16115,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15998
16115
  );
15999
16116
  if (serverVersion) {
16000
16117
  console.log();
16001
- console.log(chalk12.blue("Pulling updated artifact..."));
16118
+ console.log(chalk13.blue("Pulling updated artifact..."));
16002
16119
  try {
16003
16120
  await execVm0Command(["artifact", "pull"], {
16004
16121
  cwd: artifactDir,
16005
16122
  silent: true
16006
16123
  });
16007
- console.log(chalk12.green(`\u2713 Artifact pulled (${serverVersion})`));
16124
+ console.log(chalk13.green(`\u2713 Artifact pulled (${serverVersion})`));
16008
16125
  } catch (error43) {
16009
- console.error(chalk12.red(`\u2717 Artifact pull failed`));
16126
+ console.error(chalk13.red(`\u2717 Artifact pull failed`));
16010
16127
  if (error43 instanceof Error) {
16011
- console.error(chalk12.gray(` ${error43.message}`));
16128
+ console.error(chalk13.gray(` ${error43.message}`));
16012
16129
  }
16013
16130
  }
16014
16131
  }
@@ -16016,7 +16133,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
16016
16133
  console.log();
16017
16134
  console.log(" Run your agent:");
16018
16135
  console.log(
16019
- chalk12.cyan(
16136
+ chalk13.cyan(
16020
16137
  ` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
16021
16138
  )
16022
16139
  );
@@ -16028,7 +16145,7 @@ import { Command as Command15 } from "commander";
16028
16145
 
16029
16146
  // src/commands/image/build.ts
16030
16147
  import { Command as Command12 } from "commander";
16031
- import chalk13 from "chalk";
16148
+ import chalk14 from "chalk";
16032
16149
  import { readFile as readFile6 } from "fs/promises";
16033
16150
  import { existsSync as existsSync6 } from "fs";
16034
16151
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
@@ -16036,13 +16153,13 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16036
16153
  async (options) => {
16037
16154
  const { file: file2, name, deleteExisting } = options;
16038
16155
  if (!existsSync6(file2)) {
16039
- console.error(chalk13.red(`\u2717 Dockerfile not found: ${file2}`));
16156
+ console.error(chalk14.red(`\u2717 Dockerfile not found: ${file2}`));
16040
16157
  process.exit(1);
16041
16158
  }
16042
16159
  const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
16043
16160
  if (!nameRegex.test(name)) {
16044
16161
  console.error(
16045
- chalk13.red(
16162
+ chalk14.red(
16046
16163
  "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
16047
16164
  )
16048
16165
  );
@@ -16050,7 +16167,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16050
16167
  }
16051
16168
  if (name.startsWith("vm0-")) {
16052
16169
  console.error(
16053
- chalk13.red(
16170
+ chalk14.red(
16054
16171
  '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
16055
16172
  )
16056
16173
  );
@@ -16058,8 +16175,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16058
16175
  }
16059
16176
  try {
16060
16177
  const dockerfile = await readFile6(file2, "utf8");
16061
- console.log(chalk13.blue(`Building image: ${name}`));
16062
- console.log(chalk13.gray(` Dockerfile: ${file2}`));
16178
+ console.log(chalk14.blue(`Building image: ${name}`));
16179
+ console.log(chalk14.gray(` Dockerfile: ${file2}`));
16063
16180
  console.log();
16064
16181
  const buildInfo = await apiClient.createImage({
16065
16182
  dockerfile,
@@ -16067,7 +16184,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16067
16184
  deleteExisting
16068
16185
  });
16069
16186
  const { imageId, buildId } = buildInfo;
16070
- console.log(chalk13.gray(` Build ID: ${buildId}`));
16187
+ console.log(chalk14.gray(` Build ID: ${buildId}`));
16071
16188
  console.log();
16072
16189
  let logsOffset = 0;
16073
16190
  let status = "building";
@@ -16083,7 +16200,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16083
16200
  }
16084
16201
  const statusData = await statusResponse.json();
16085
16202
  for (const log of statusData.logs) {
16086
- console.log(chalk13.gray(` ${log}`));
16203
+ console.log(chalk14.gray(` ${log}`));
16087
16204
  }
16088
16205
  logsOffset = statusData.logsOffset;
16089
16206
  status = statusData.status;
@@ -16093,27 +16210,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16093
16210
  }
16094
16211
  console.log();
16095
16212
  if (status === "ready") {
16096
- console.log(chalk13.green(`\u2713 Image built: ${name}`));
16213
+ console.log(chalk14.green(`\u2713 Image built: ${name}`));
16097
16214
  console.log();
16098
16215
  console.log("Use in vm0.yaml:");
16099
- console.log(chalk13.cyan(` agents:`));
16100
- console.log(chalk13.cyan(` your-agent:`));
16101
- console.log(chalk13.cyan(` image: "${name}"`));
16216
+ console.log(chalk14.cyan(` agents:`));
16217
+ console.log(chalk14.cyan(` your-agent:`));
16218
+ console.log(chalk14.cyan(` image: "${name}"`));
16102
16219
  } else {
16103
- console.error(chalk13.red(`\u2717 Build failed`));
16220
+ console.error(chalk14.red(`\u2717 Build failed`));
16104
16221
  process.exit(1);
16105
16222
  }
16106
16223
  } catch (error43) {
16107
16224
  if (error43 instanceof Error) {
16108
16225
  if (error43.message.includes("Not authenticated")) {
16109
16226
  console.error(
16110
- chalk13.red("\u2717 Not authenticated. Run: vm0 auth login")
16227
+ chalk14.red("\u2717 Not authenticated. Run: vm0 auth login")
16111
16228
  );
16112
16229
  } else {
16113
- console.error(chalk13.red(`\u2717 ${error43.message}`));
16230
+ console.error(chalk14.red(`\u2717 ${error43.message}`));
16114
16231
  }
16115
16232
  } else {
16116
- console.error(chalk13.red("\u2717 An unexpected error occurred"));
16233
+ console.error(chalk14.red("\u2717 An unexpected error occurred"));
16117
16234
  }
16118
16235
  process.exit(1);
16119
16236
  }
@@ -16122,7 +16239,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
16122
16239
 
16123
16240
  // src/commands/image/list.ts
16124
16241
  import { Command as Command13 } from "commander";
16125
- import chalk14 from "chalk";
16242
+ import chalk15 from "chalk";
16126
16243
  var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
16127
16244
  try {
16128
16245
  const response = await apiClient.get("/api/images");
@@ -16135,43 +16252,43 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16135
16252
  const data = await response.json();
16136
16253
  const { images } = data;
16137
16254
  if (images.length === 0) {
16138
- console.log(chalk14.gray("No images found."));
16255
+ console.log(chalk15.gray("No images found."));
16139
16256
  console.log();
16140
16257
  console.log("Build your first image:");
16141
16258
  console.log(
16142
- chalk14.cyan(" vm0 image build --file Dockerfile --name my-image")
16259
+ chalk15.cyan(" vm0 image build --file Dockerfile --name my-image")
16143
16260
  );
16144
16261
  return;
16145
16262
  }
16146
- console.log(chalk14.bold("Your images:"));
16263
+ console.log(chalk15.bold("Your images:"));
16147
16264
  console.log();
16148
16265
  console.log(
16149
- chalk14.gray(
16266
+ chalk15.gray(
16150
16267
  `${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
16151
16268
  )
16152
16269
  );
16153
- console.log(chalk14.gray("-".repeat(62)));
16270
+ console.log(chalk15.gray("-".repeat(62)));
16154
16271
  for (const image of images) {
16155
- const statusColor = image.status === "ready" ? chalk14.green : image.status === "building" ? chalk14.yellow : chalk14.red;
16272
+ const statusColor = image.status === "ready" ? chalk15.green : image.status === "building" ? chalk15.yellow : chalk15.red;
16156
16273
  const createdAt = new Date(image.createdAt).toLocaleString();
16157
16274
  console.log(
16158
16275
  `${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
16159
16276
  );
16160
16277
  if (image.status === "error" && image.errorMessage) {
16161
- console.log(chalk14.red(` Error: ${image.errorMessage}`));
16278
+ console.log(chalk15.red(` Error: ${image.errorMessage}`));
16162
16279
  }
16163
16280
  }
16164
16281
  console.log();
16165
- console.log(chalk14.gray(`Total: ${images.length} image(s)`));
16282
+ console.log(chalk15.gray(`Total: ${images.length} image(s)`));
16166
16283
  } catch (error43) {
16167
16284
  if (error43 instanceof Error) {
16168
16285
  if (error43.message.includes("Not authenticated")) {
16169
- console.error(chalk14.red("Not authenticated. Run: vm0 auth login"));
16286
+ console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16170
16287
  } else {
16171
- console.error(chalk14.red(`Error: ${error43.message}`));
16288
+ console.error(chalk15.red(`Error: ${error43.message}`));
16172
16289
  }
16173
16290
  } else {
16174
- console.error(chalk14.red("An unexpected error occurred"));
16291
+ console.error(chalk15.red("An unexpected error occurred"));
16175
16292
  }
16176
16293
  process.exit(1);
16177
16294
  }
@@ -16179,7 +16296,7 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
16179
16296
 
16180
16297
  // src/commands/image/delete.ts
16181
16298
  import { Command as Command14 } from "commander";
16182
- import chalk15 from "chalk";
16299
+ import chalk16 from "chalk";
16183
16300
  import * as readline from "readline";
16184
16301
  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) => {
16185
16302
  try {
@@ -16193,7 +16310,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16193
16310
  const data = await listResponse.json();
16194
16311
  const image = data.images.find((img) => img.alias === name);
16195
16312
  if (!image) {
16196
- console.error(chalk15.red(`Image not found: ${name}`));
16313
+ console.error(chalk16.red(`Image not found: ${name}`));
16197
16314
  process.exit(1);
16198
16315
  }
16199
16316
  if (!options.force) {
@@ -16203,7 +16320,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16203
16320
  });
16204
16321
  const answer = await new Promise((resolve2) => {
16205
16322
  rl.question(
16206
- chalk15.yellow(`Delete image "${name}"? [y/N] `),
16323
+ chalk16.yellow(`Delete image "${name}"? [y/N] `),
16207
16324
  (answer2) => {
16208
16325
  rl.close();
16209
16326
  resolve2(answer2);
@@ -16211,7 +16328,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16211
16328
  );
16212
16329
  });
16213
16330
  if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
16214
- console.log(chalk15.gray("Cancelled."));
16331
+ console.log(chalk16.gray("Cancelled."));
16215
16332
  return;
16216
16333
  }
16217
16334
  }
@@ -16222,16 +16339,16 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
16222
16339
  error43.error?.message || "Failed to delete image"
16223
16340
  );
16224
16341
  }
16225
- console.log(chalk15.green(`Deleted image: ${name}`));
16342
+ console.log(chalk16.green(`Deleted image: ${name}`));
16226
16343
  } catch (error43) {
16227
16344
  if (error43 instanceof Error) {
16228
16345
  if (error43.message.includes("Not authenticated")) {
16229
- console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
16346
+ console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16230
16347
  } else {
16231
- console.error(chalk15.red(`Error: ${error43.message}`));
16348
+ console.error(chalk16.red(`Error: ${error43.message}`));
16232
16349
  }
16233
16350
  } else {
16234
- console.error(chalk15.red("An unexpected error occurred"));
16351
+ console.error(chalk16.red("An unexpected error occurred"));
16235
16352
  }
16236
16353
  process.exit(1);
16237
16354
  }
@@ -16242,7 +16359,7 @@ var imageCommand = new Command15().name("image").description("Manage custom imag
16242
16359
 
16243
16360
  // src/commands/logs/index.ts
16244
16361
  import { Command as Command16 } from "commander";
16245
- import chalk16 from "chalk";
16362
+ import chalk17 from "chalk";
16246
16363
 
16247
16364
  // src/lib/time-parser.ts
16248
16365
  function parseTime(timeStr) {
@@ -16304,23 +16421,23 @@ function formatMetric(metric) {
16304
16421
  function formatNetworkLog(entry) {
16305
16422
  let statusColor;
16306
16423
  if (entry.status >= 200 && entry.status < 300) {
16307
- statusColor = chalk16.green;
16424
+ statusColor = chalk17.green;
16308
16425
  } else if (entry.status >= 300 && entry.status < 400) {
16309
- statusColor = chalk16.yellow;
16426
+ statusColor = chalk17.yellow;
16310
16427
  } else if (entry.status >= 400) {
16311
- statusColor = chalk16.red;
16428
+ statusColor = chalk17.red;
16312
16429
  } else {
16313
- statusColor = chalk16.gray;
16430
+ statusColor = chalk17.gray;
16314
16431
  }
16315
16432
  let latencyColor;
16316
16433
  if (entry.latency_ms < 500) {
16317
- latencyColor = chalk16.green;
16434
+ latencyColor = chalk17.green;
16318
16435
  } else if (entry.latency_ms < 2e3) {
16319
- latencyColor = chalk16.yellow;
16436
+ latencyColor = chalk17.yellow;
16320
16437
  } else {
16321
- latencyColor = chalk16.red;
16438
+ latencyColor = chalk17.red;
16322
16439
  }
16323
- return `[${entry.timestamp}] ${chalk16.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk16.gray(entry.url)}`;
16440
+ 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)}`;
16324
16441
  }
16325
16442
  function renderAgentEvent(event) {
16326
16443
  const parsed = ClaudeEventParser.parse(
@@ -16340,7 +16457,7 @@ function getLogType(options) {
16340
16457
  ].filter(Boolean).length;
16341
16458
  if (selected > 1) {
16342
16459
  console.error(
16343
- chalk16.red(
16460
+ chalk17.red(
16344
16461
  "Options --agent, --system, --metrics, and --network are mutually exclusive"
16345
16462
  )
16346
16463
  );
@@ -16393,7 +16510,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
16393
16510
  async function showAgentEvents(runId, options) {
16394
16511
  const response = await apiClient.getAgentEvents(runId, options);
16395
16512
  if (response.events.length === 0) {
16396
- console.log(chalk16.yellow("No agent events found for this run."));
16513
+ console.log(chalk17.yellow("No agent events found for this run."));
16397
16514
  return;
16398
16515
  }
16399
16516
  for (const event of response.events) {
@@ -16402,7 +16519,7 @@ async function showAgentEvents(runId, options) {
16402
16519
  if (response.hasMore) {
16403
16520
  console.log();
16404
16521
  console.log(
16405
- chalk16.gray(
16522
+ chalk17.gray(
16406
16523
  `Showing ${response.events.length} events. Use --limit to see more.`
16407
16524
  )
16408
16525
  );
@@ -16411,21 +16528,21 @@ async function showAgentEvents(runId, options) {
16411
16528
  async function showSystemLog(runId, options) {
16412
16529
  const response = await apiClient.getSystemLog(runId, options);
16413
16530
  if (!response.systemLog) {
16414
- console.log(chalk16.yellow("No system log found for this run."));
16531
+ console.log(chalk17.yellow("No system log found for this run."));
16415
16532
  return;
16416
16533
  }
16417
16534
  console.log(response.systemLog);
16418
16535
  if (response.hasMore) {
16419
16536
  console.log();
16420
16537
  console.log(
16421
- chalk16.gray("More log entries available. Use --limit to see more.")
16538
+ chalk17.gray("More log entries available. Use --limit to see more.")
16422
16539
  );
16423
16540
  }
16424
16541
  }
16425
16542
  async function showMetrics(runId, options) {
16426
16543
  const response = await apiClient.getMetrics(runId, options);
16427
16544
  if (response.metrics.length === 0) {
16428
- console.log(chalk16.yellow("No metrics found for this run."));
16545
+ console.log(chalk17.yellow("No metrics found for this run."));
16429
16546
  return;
16430
16547
  }
16431
16548
  for (const metric of response.metrics) {
@@ -16434,7 +16551,7 @@ async function showMetrics(runId, options) {
16434
16551
  if (response.hasMore) {
16435
16552
  console.log();
16436
16553
  console.log(
16437
- chalk16.gray(
16554
+ chalk17.gray(
16438
16555
  `Showing ${response.metrics.length} metrics. Use --limit to see more.`
16439
16556
  )
16440
16557
  );
@@ -16444,7 +16561,7 @@ async function showNetworkLogs(runId, options) {
16444
16561
  const response = await apiClient.getNetworkLogs(runId, options);
16445
16562
  if (response.networkLogs.length === 0) {
16446
16563
  console.log(
16447
- chalk16.yellow(
16564
+ chalk17.yellow(
16448
16565
  "No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
16449
16566
  )
16450
16567
  );
@@ -16456,7 +16573,7 @@ async function showNetworkLogs(runId, options) {
16456
16573
  if (response.hasMore) {
16457
16574
  console.log();
16458
16575
  console.log(
16459
- chalk16.gray(
16576
+ chalk17.gray(
16460
16577
  `Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
16461
16578
  )
16462
16579
  );
@@ -16465,25 +16582,25 @@ async function showNetworkLogs(runId, options) {
16465
16582
  function handleError(error43, runId) {
16466
16583
  if (error43 instanceof Error) {
16467
16584
  if (error43.message.includes("Not authenticated")) {
16468
- console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
16585
+ console.error(chalk17.red("Not authenticated. Run: vm0 auth login"));
16469
16586
  } else if (error43.message.includes("not found")) {
16470
- console.error(chalk16.red(`Run not found: ${runId}`));
16587
+ console.error(chalk17.red(`Run not found: ${runId}`));
16471
16588
  } else if (error43.message.includes("Invalid time format")) {
16472
- console.error(chalk16.red(error43.message));
16589
+ console.error(chalk17.red(error43.message));
16473
16590
  } else {
16474
- console.error(chalk16.red("Failed to fetch logs"));
16475
- console.error(chalk16.gray(` ${error43.message}`));
16591
+ console.error(chalk17.red("Failed to fetch logs"));
16592
+ console.error(chalk17.gray(` ${error43.message}`));
16476
16593
  }
16477
16594
  } else {
16478
- console.error(chalk16.red("An unexpected error occurred"));
16595
+ console.error(chalk17.red("An unexpected error occurred"));
16479
16596
  }
16480
16597
  }
16481
16598
 
16482
16599
  // src/index.ts
16483
16600
  var program = new Command17();
16484
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.10.0");
16601
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.12.0");
16485
16602
  program.command("info").description("Display environment information").action(async () => {
16486
- console.log(chalk17.cyan("System Information:"));
16603
+ console.log(chalk18.cyan("System Information:"));
16487
16604
  console.log(`Node Version: ${process.version}`);
16488
16605
  console.log(`Platform: ${process.platform}`);
16489
16606
  console.log(`Architecture: ${process.arch}`);
@@ -16500,6 +16617,9 @@ authCommand.command("logout").description("Log out of VM0").action(async () => {
16500
16617
  authCommand.command("status").description("Show current authentication status").action(async () => {
16501
16618
  await checkAuthStatus();
16502
16619
  });
16620
+ authCommand.command("setup-token").description("Output auth token for CI/CD environments").action(async () => {
16621
+ await setupToken();
16622
+ });
16503
16623
  program.addCommand(composeCommand);
16504
16624
  program.addCommand(runCommand);
16505
16625
  program.addCommand(volumeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.10.0",
3
+ "version": "4.12.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",