@vm0/cli 9.37.2 → 9.37.4

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 +193 -159
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -45,7 +45,7 @@ if (DSN) {
45
45
  Sentry.init({
46
46
  dsn: DSN,
47
47
  environment: process.env.SENTRY_ENVIRONMENT ?? "production",
48
- release: "9.37.2",
48
+ release: "9.37.4",
49
49
  sendDefaultPii: false,
50
50
  tracesSampleRate: 0,
51
51
  shutdownTimeout: 500,
@@ -64,7 +64,7 @@ if (DSN) {
64
64
  }
65
65
  });
66
66
  Sentry.setContext("cli", {
67
- version: "9.37.2",
67
+ version: "9.37.4",
68
68
  command: process.argv.slice(2).join(" ")
69
69
  });
70
70
  Sentry.setContext("runtime", {
@@ -603,9 +603,11 @@ async function waitForSilentUpgrade(timeout = TIMEOUT_MS) {
603
603
  }
604
604
 
605
605
  // src/commands/info/index.ts
606
- var CONFIG_PATH = join2(homedir2(), ".vm0", "config.json");
606
+ function getConfigPath() {
607
+ return join2(homedir2(), ".vm0", "config.json");
608
+ }
607
609
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
608
- console.log(chalk7.bold(`VM0 CLI v${"9.37.2"}`));
610
+ console.log(chalk7.bold(`VM0 CLI v${"9.37.4"}`));
609
611
  console.log();
610
612
  const config = await loadConfig();
611
613
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -618,7 +620,7 @@ var infoCommand = new Command6().name("info").description("Display environment a
618
620
  } else {
619
621
  console.log(` ${chalk7.red("\u2717")} Not authenticated`);
620
622
  }
621
- const configExists = existsSync2(CONFIG_PATH);
623
+ const configExists = existsSync2(getConfigPath());
622
624
  const configDisplay = configExists ? `~/.vm0/config.json` : `~/.vm0/config.json (not found)`;
623
625
  console.log(` Config: ${configDisplay}`);
624
626
  console.log();
@@ -4591,6 +4593,10 @@ var FEATURE_SWITCHES = {
4591
4593
  ["computerConnector" /* ComputerConnector */]: {
4592
4594
  maintainer: "ethan@vm0.ai",
4593
4595
  enabled: false
4596
+ },
4597
+ ["agentDetailPage" /* AgentDetailPage */]: {
4598
+ maintainer: "yuma@vm0.ai",
4599
+ enabled: false
4594
4600
  }
4595
4601
  };
4596
4602
 
@@ -5250,6 +5256,36 @@ var cliComposeSchema = z29.object({
5250
5256
  }
5251
5257
  }
5252
5258
  });
5259
+ function formatInvalidTypeIssue(path16, issue) {
5260
+ const received = issue.received;
5261
+ const isMissing = received === "undefined" || issue.message.includes("received undefined") || issue.message === "Required";
5262
+ if (path16 === "version" && isMissing) {
5263
+ return "Missing config.version";
5264
+ }
5265
+ if (path16 === "agents" && isMissing) {
5266
+ return "Missing agents object in config";
5267
+ }
5268
+ if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
5269
+ const volumeKey = path16.split(".")[1];
5270
+ return `Volume "${volumeKey}" must have a 'name' field (string)`;
5271
+ }
5272
+ if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
5273
+ const volumeKey = path16.split(".")[1];
5274
+ return `Volume "${volumeKey}" must have a 'version' field (string)`;
5275
+ }
5276
+ if (issue.expected === "array") {
5277
+ const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5278
+ return `${fieldName} must be an array`;
5279
+ }
5280
+ if (issue.expected === "string" && received === "number") {
5281
+ const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5282
+ const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
5283
+ if (match) {
5284
+ return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
5285
+ }
5286
+ }
5287
+ return null;
5288
+ }
5253
5289
  function formatZodError(error) {
5254
5290
  const issue = error.issues[0];
5255
5291
  if (!issue) return "Validation failed";
@@ -5257,33 +5293,8 @@ function formatZodError(error) {
5257
5293
  const message = issue.message;
5258
5294
  if (!path16) return message;
5259
5295
  if (issue.code === "invalid_type") {
5260
- const received = issue.received;
5261
- const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
5262
- if (path16 === "version" && isMissing) {
5263
- return "Missing config.version";
5264
- }
5265
- if (path16 === "agents" && isMissing) {
5266
- return "Missing agents object in config";
5267
- }
5268
- if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
5269
- const volumeKey = path16.split(".")[1];
5270
- return `Volume "${volumeKey}" must have a 'name' field (string)`;
5271
- }
5272
- if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
5273
- const volumeKey = path16.split(".")[1];
5274
- return `Volume "${volumeKey}" must have a 'version' field (string)`;
5275
- }
5276
- if (issue.expected === "array") {
5277
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5278
- return `${fieldName} must be an array`;
5279
- }
5280
- if (issue.expected === "string" && received === "number") {
5281
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5282
- const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
5283
- if (match) {
5284
- return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
5285
- }
5286
- }
5296
+ const formatted = formatInvalidTypeIssue(path16, issue);
5297
+ if (formatted) return formatted;
5287
5298
  }
5288
5299
  if (issue.code === "invalid_key" && path16.startsWith("agents.")) {
5289
5300
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
@@ -6432,7 +6443,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
6432
6443
  options.autoUpdate = false;
6433
6444
  }
6434
6445
  if (options.autoUpdate !== false) {
6435
- await startSilentUpgrade("9.37.2");
6446
+ await startSilentUpgrade("9.37.4");
6436
6447
  }
6437
6448
  try {
6438
6449
  let result;
@@ -7130,7 +7141,6 @@ var CodexEventParser = class {
7130
7141
  }
7131
7142
  };
7132
7143
  }
7133
- // eslint-disable-next-line complexity -- TODO: refactor complex function
7134
7144
  static parseItemEvent(event) {
7135
7145
  const item = event.item;
7136
7146
  if (!item) {
@@ -7138,106 +7148,123 @@ var CodexEventParser = class {
7138
7148
  }
7139
7149
  const itemType = item.type;
7140
7150
  if (itemType === "agent_message" && item.text) {
7141
- return {
7142
- type: "text",
7143
- timestamp: /* @__PURE__ */ new Date(),
7144
- data: { text: item.text }
7145
- };
7151
+ return { type: "text", timestamp: /* @__PURE__ */ new Date(), data: { text: item.text } };
7146
7152
  }
7147
7153
  if (itemType === "command_execution") {
7148
- if (event.type === "item.started" && item.command) {
7149
- return {
7150
- type: "tool_use",
7151
- timestamp: /* @__PURE__ */ new Date(),
7152
- data: {
7153
- tool: "Bash",
7154
- toolUseId: item.id,
7155
- input: { command: item.command }
7156
- }
7157
- };
7158
- }
7159
- if (event.type === "item.completed") {
7160
- const output = item.aggregated_output ?? item.output ?? "";
7161
- return {
7162
- type: "tool_result",
7163
- timestamp: /* @__PURE__ */ new Date(),
7164
- data: {
7165
- toolUseId: item.id,
7166
- result: output,
7167
- isError: item.exit_code !== 0
7168
- }
7169
- };
7170
- }
7154
+ return this.parseCommandExecution(event);
7171
7155
  }
7172
7156
  if (itemType === "file_edit" || itemType === "file_write") {
7173
- if (event.type === "item.started" && item.path) {
7174
- return {
7175
- type: "tool_use",
7176
- timestamp: /* @__PURE__ */ new Date(),
7177
- data: {
7178
- tool: itemType === "file_edit" ? "Edit" : "Write",
7179
- toolUseId: item.id,
7180
- input: { file_path: item.path }
7181
- }
7182
- };
7183
- }
7184
- if (event.type === "item.completed") {
7185
- return {
7186
- type: "tool_result",
7187
- timestamp: /* @__PURE__ */ new Date(),
7188
- data: {
7189
- toolUseId: item.id,
7190
- result: item.diff || "File operation completed",
7191
- isError: false
7192
- }
7193
- };
7194
- }
7157
+ return this.parseFileEditOrWrite(event);
7195
7158
  }
7196
7159
  if (itemType === "file_read") {
7197
- if (event.type === "item.started" && item.path) {
7198
- return {
7199
- type: "tool_use",
7200
- timestamp: /* @__PURE__ */ new Date(),
7201
- data: {
7202
- tool: "Read",
7203
- toolUseId: item.id,
7204
- input: { file_path: item.path }
7205
- }
7206
- };
7207
- }
7208
- if (event.type === "item.completed") {
7209
- return {
7210
- type: "tool_result",
7211
- timestamp: /* @__PURE__ */ new Date(),
7212
- data: {
7213
- toolUseId: item.id,
7214
- result: "File read completed",
7215
- isError: false
7216
- }
7217
- };
7218
- }
7160
+ return this.parseFileRead(event);
7161
+ }
7162
+ if (itemType === "file_change") {
7163
+ return this.parseFileChange(item);
7219
7164
  }
7220
- if (itemType === "file_change" && item.changes && item.changes.length > 0) {
7221
- const changes = item.changes.map((c25) => {
7222
- const action = c25.kind === "add" ? "Created" : c25.kind === "modify" ? "Modified" : "Deleted";
7223
- return `${action}: ${c25.path}`;
7224
- }).join("\n");
7165
+ if (itemType === "reasoning" && item.text) {
7225
7166
  return {
7226
7167
  type: "text",
7227
7168
  timestamp: /* @__PURE__ */ new Date(),
7228
- data: { text: `[files]
7229
- ${changes}` }
7169
+ data: { text: `[thinking] ${item.text}` }
7230
7170
  };
7231
7171
  }
7232
- if (itemType === "reasoning" && item.text) {
7172
+ return null;
7173
+ }
7174
+ static parseCommandExecution(event) {
7175
+ const item = event.item;
7176
+ if (event.type === "item.started" && item.command) {
7233
7177
  return {
7234
- type: "text",
7178
+ type: "tool_use",
7235
7179
  timestamp: /* @__PURE__ */ new Date(),
7236
- data: { text: `[thinking] ${item.text}` }
7180
+ data: {
7181
+ tool: "Bash",
7182
+ toolUseId: item.id,
7183
+ input: { command: item.command }
7184
+ }
7185
+ };
7186
+ }
7187
+ if (event.type === "item.completed") {
7188
+ const output = item.aggregated_output ?? item.output ?? "";
7189
+ return {
7190
+ type: "tool_result",
7191
+ timestamp: /* @__PURE__ */ new Date(),
7192
+ data: {
7193
+ toolUseId: item.id,
7194
+ result: output,
7195
+ isError: item.exit_code !== 0
7196
+ }
7237
7197
  };
7238
7198
  }
7239
7199
  return null;
7240
7200
  }
7201
+ static parseFileEditOrWrite(event) {
7202
+ const item = event.item;
7203
+ if (event.type === "item.started" && item.path) {
7204
+ return {
7205
+ type: "tool_use",
7206
+ timestamp: /* @__PURE__ */ new Date(),
7207
+ data: {
7208
+ tool: item.type === "file_edit" ? "Edit" : "Write",
7209
+ toolUseId: item.id,
7210
+ input: { file_path: item.path }
7211
+ }
7212
+ };
7213
+ }
7214
+ if (event.type === "item.completed") {
7215
+ return {
7216
+ type: "tool_result",
7217
+ timestamp: /* @__PURE__ */ new Date(),
7218
+ data: {
7219
+ toolUseId: item.id,
7220
+ result: item.diff || "File operation completed",
7221
+ isError: false
7222
+ }
7223
+ };
7224
+ }
7225
+ return null;
7226
+ }
7227
+ static parseFileRead(event) {
7228
+ const item = event.item;
7229
+ if (event.type === "item.started" && item.path) {
7230
+ return {
7231
+ type: "tool_use",
7232
+ timestamp: /* @__PURE__ */ new Date(),
7233
+ data: {
7234
+ tool: "Read",
7235
+ toolUseId: item.id,
7236
+ input: { file_path: item.path }
7237
+ }
7238
+ };
7239
+ }
7240
+ if (event.type === "item.completed") {
7241
+ return {
7242
+ type: "tool_result",
7243
+ timestamp: /* @__PURE__ */ new Date(),
7244
+ data: {
7245
+ toolUseId: item.id,
7246
+ result: "File read completed",
7247
+ isError: false
7248
+ }
7249
+ };
7250
+ }
7251
+ return null;
7252
+ }
7253
+ static parseFileChange(item) {
7254
+ if (!item.changes || item.changes.length === 0) {
7255
+ return null;
7256
+ }
7257
+ const changes = item.changes.map((c25) => {
7258
+ const action = c25.kind === "add" ? "Created" : c25.kind === "modify" ? "Modified" : "Deleted";
7259
+ return `${action}: ${c25.path}`;
7260
+ }).join("\n");
7261
+ return {
7262
+ type: "text",
7263
+ timestamp: /* @__PURE__ */ new Date(),
7264
+ data: { text: `[files]
7265
+ ${changes}` }
7266
+ };
7267
+ }
7241
7268
  static parseErrorEvent(event) {
7242
7269
  return {
7243
7270
  type: "result",
@@ -7337,7 +7364,6 @@ var CodexEventRenderer = class {
7337
7364
  chalk11.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
7338
7365
  );
7339
7366
  }
7340
- // eslint-disable-next-line complexity -- TODO: refactor complex function
7341
7367
  static renderItem(event) {
7342
7368
  const item = event.item;
7343
7369
  if (!item) return;
@@ -7345,48 +7371,50 @@ var CodexEventRenderer = class {
7345
7371
  const eventType = event.type;
7346
7372
  if (itemType === "reasoning" && item.text) {
7347
7373
  console.log(`[reasoning] ${item.text}`);
7348
- return;
7349
- }
7350
- if (itemType === "agent_message" && item.text) {
7374
+ } else if (itemType === "agent_message" && item.text) {
7351
7375
  console.log(`[message] ${item.text}`);
7352
- return;
7353
- }
7354
- if (itemType === "command_execution") {
7355
- if (eventType === "item.started" && item.command) {
7356
- console.log(`[exec] ${item.command}`);
7357
- } else if (eventType === "item.completed") {
7358
- const output = item.aggregated_output || "";
7359
- const exitCode = item.exit_code ?? 0;
7360
- if (output) {
7361
- const lines = output.split("\n").filter((l) => l.trim());
7362
- const preview = lines.slice(0, 3).join("\n ");
7363
- const more = lines.length > 3 ? chalk11.dim(` ... (${lines.length - 3} more lines)`) : "";
7364
- console.log(
7365
- "[output]" + (exitCode !== 0 ? chalk11.red(` exit=${exitCode}`) : "")
7366
- );
7367
- if (preview) {
7368
- console.log(" " + preview + more);
7369
- }
7370
- } else if (exitCode !== 0) {
7371
- console.log(chalk11.red("[output]") + chalk11.red(` exit=${exitCode}`));
7376
+ } else if (itemType === "command_execution") {
7377
+ this.renderCommandExecution(item, eventType);
7378
+ } else if (itemType === "file_change") {
7379
+ this.renderFileChange(item);
7380
+ } else if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
7381
+ this.renderFileOperation(item, eventType);
7382
+ }
7383
+ }
7384
+ static renderCommandExecution(item, eventType) {
7385
+ if (eventType === "item.started" && item.command) {
7386
+ console.log(`[exec] ${item.command}`);
7387
+ } else if (eventType === "item.completed") {
7388
+ const output = item.aggregated_output || "";
7389
+ const exitCode = item.exit_code ?? 0;
7390
+ if (output) {
7391
+ const lines = output.split("\n").filter((l) => l.trim());
7392
+ const preview = lines.slice(0, 3).join("\n ");
7393
+ const more = lines.length > 3 ? chalk11.dim(` ... (${lines.length - 3} more lines)`) : "";
7394
+ console.log(
7395
+ "[output]" + (exitCode !== 0 ? chalk11.red(` exit=${exitCode}`) : "")
7396
+ );
7397
+ if (preview) {
7398
+ console.log(" " + preview + more);
7372
7399
  }
7400
+ } else if (exitCode !== 0) {
7401
+ console.log(chalk11.red("[output]") + chalk11.red(` exit=${exitCode}`));
7373
7402
  }
7374
- return;
7375
7403
  }
7376
- if (itemType === "file_change" && item.changes && item.changes.length > 0) {
7404
+ }
7405
+ static renderFileChange(item) {
7406
+ if (item.changes && item.changes.length > 0) {
7377
7407
  const summary = item.changes.map((c25) => {
7378
7408
  const icon = c25.kind === "add" ? "+" : c25.kind === "delete" ? "-" : "~";
7379
7409
  return `${icon}${c25.path}`;
7380
7410
  }).join(", ");
7381
7411
  console.log(chalk11.green("[files]") + ` ${summary}`);
7382
- return;
7383
7412
  }
7384
- if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
7385
- const action = itemType.replace("file_", "");
7386
- if (eventType === "item.started" && item.path) {
7387
- console.log(`[${action}] ${item.path}`);
7388
- }
7389
- return;
7413
+ }
7414
+ static renderFileOperation(item, eventType) {
7415
+ const action = item.type.replace("file_", "");
7416
+ if (eventType === "item.started" && item.path) {
7417
+ console.log(`[${action}] ${item.path}`);
7390
7418
  }
7391
7419
  }
7392
7420
  static renderError(event) {
@@ -8629,7 +8657,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
8629
8657
  async (identifier, prompt, options) => {
8630
8658
  try {
8631
8659
  if (options.autoUpdate !== false) {
8632
- await startSilentUpgrade("9.37.2");
8660
+ await startSilentUpgrade("9.37.4");
8633
8661
  }
8634
8662
  const { scope, name, version } = parseIdentifier(identifier);
8635
8663
  if (scope && !options.experimentalSharedAgent) {
@@ -10205,7 +10233,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
10205
10233
  ).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option5("--debug-no-mock-claude").hideHelp()).addOption(new Option5("--no-auto-update").hideHelp()).action(
10206
10234
  async (prompt, options) => {
10207
10235
  if (options.autoUpdate !== false) {
10208
- const shouldExit = await checkAndUpgrade("9.37.2", prompt);
10236
+ const shouldExit = await checkAndUpgrade("9.37.4", prompt);
10209
10237
  if (shouldExit) {
10210
10238
  process.exit(0);
10211
10239
  }
@@ -10478,13 +10506,13 @@ function formatMetric(metric) {
10478
10506
  const diskPercent = (metric.disk_used / metric.disk_total * 100).toFixed(1);
10479
10507
  return `[${metric.ts}] CPU: ${metric.cpu.toFixed(1)}% | Mem: ${formatBytes(metric.mem_used)}/${formatBytes(metric.mem_total)} (${memPercent}%) | Disk: ${formatBytes(metric.disk_used)}/${formatBytes(metric.disk_total)} (${diskPercent}%)`;
10480
10508
  }
10481
- function formatNetworkLog(entry) {
10482
- if (entry.mode === "sni" || !entry.method) {
10483
- const actionColor = entry.action === "ALLOW" ? chalk37.green : chalk37.red;
10484
- const host = entry.host || "unknown";
10485
- const port = entry.port || 443;
10486
- return `[${entry.timestamp}] ${chalk37.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk37.dim(entry.rule_matched || "")}`;
10487
- }
10509
+ function formatSniLog(entry) {
10510
+ const actionColor = entry.action === "ALLOW" ? chalk37.green : chalk37.red;
10511
+ const host = entry.host || "unknown";
10512
+ const port = entry.port || 443;
10513
+ return `[${entry.timestamp}] ${chalk37.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk37.dim(entry.rule_matched || "")}`;
10514
+ }
10515
+ function formatMitmLog(entry) {
10488
10516
  let statusColor;
10489
10517
  const status = entry.status || 0;
10490
10518
  if (status >= 200 && status < 300) {
@@ -10511,6 +10539,12 @@ function formatNetworkLog(entry) {
10511
10539
  const url = entry.url || entry.host || "unknown";
10512
10540
  return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk37.dim(url)}`;
10513
10541
  }
10542
+ function formatNetworkLog(entry) {
10543
+ if (entry.mode === "sni" || !entry.method) {
10544
+ return formatSniLog(entry);
10545
+ }
10546
+ return formatMitmLog(entry);
10547
+ }
10514
10548
  function createLogRenderer(verbose) {
10515
10549
  return new EventRenderer({
10516
10550
  showTimestamp: true,
@@ -14924,7 +14958,7 @@ var preferenceCommand = new Command77().name("preference").description("View or
14924
14958
 
14925
14959
  // src/index.ts
14926
14960
  var program = new Command78();
14927
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.37.2");
14961
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.37.4");
14928
14962
  program.addCommand(authCommand);
14929
14963
  program.addCommand(infoCommand);
14930
14964
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.37.2",
3
+ "version": "9.37.4",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",