@vm0/cli 9.37.1 → 9.37.3

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 +197 -161
  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.1",
48
+ release: "9.37.3",
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.1",
67
+ version: "9.37.3",
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.1"}`));
610
+ console.log(chalk7.bold(`VM0 CLI v${"9.37.3"}`));
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();
@@ -1070,7 +1072,8 @@ var composesVersionsContract = c2.router({
1070
1072
  var composeListItemSchema = z4.object({
1071
1073
  name: z4.string(),
1072
1074
  headVersionId: z4.string().nullable(),
1073
- updatedAt: z4.string()
1075
+ updatedAt: z4.string(),
1076
+ isOwner: z4.boolean()
1074
1077
  });
1075
1078
  var composesListContract = c2.router({
1076
1079
  /**
@@ -3413,7 +3416,8 @@ var platformLogsListContract = c17.router({
3413
3416
  method: "GET",
3414
3417
  path: "/api/platform/logs",
3415
3418
  query: listQuerySchema.extend({
3416
- search: z21.string().optional()
3419
+ search: z21.string().optional(),
3420
+ agent: z21.string().optional()
3417
3421
  }),
3418
3422
  responses: {
3419
3423
  200: platformLogsListResponseSchema,
@@ -4589,6 +4593,10 @@ var FEATURE_SWITCHES = {
4589
4593
  ["computerConnector" /* ComputerConnector */]: {
4590
4594
  maintainer: "ethan@vm0.ai",
4591
4595
  enabled: false
4596
+ },
4597
+ ["agentDetailPage" /* AgentDetailPage */]: {
4598
+ maintainer: "yuma@vm0.ai",
4599
+ enabled: false
4592
4600
  }
4593
4601
  };
4594
4602
 
@@ -5248,6 +5256,36 @@ var cliComposeSchema = z29.object({
5248
5256
  }
5249
5257
  }
5250
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
+ }
5251
5289
  function formatZodError(error) {
5252
5290
  const issue = error.issues[0];
5253
5291
  if (!issue) return "Validation failed";
@@ -5255,33 +5293,8 @@ function formatZodError(error) {
5255
5293
  const message = issue.message;
5256
5294
  if (!path16) return message;
5257
5295
  if (issue.code === "invalid_type") {
5258
- const received = issue.received;
5259
- const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
5260
- if (path16 === "version" && isMissing) {
5261
- return "Missing config.version";
5262
- }
5263
- if (path16 === "agents" && isMissing) {
5264
- return "Missing agents object in config";
5265
- }
5266
- if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
5267
- const volumeKey = path16.split(".")[1];
5268
- return `Volume "${volumeKey}" must have a 'name' field (string)`;
5269
- }
5270
- if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
5271
- const volumeKey = path16.split(".")[1];
5272
- return `Volume "${volumeKey}" must have a 'version' field (string)`;
5273
- }
5274
- if (issue.expected === "array") {
5275
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5276
- return `${fieldName} must be an array`;
5277
- }
5278
- if (issue.expected === "string" && received === "number") {
5279
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5280
- const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
5281
- if (match) {
5282
- return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
5283
- }
5284
- }
5296
+ const formatted = formatInvalidTypeIssue(path16, issue);
5297
+ if (formatted) return formatted;
5285
5298
  }
5286
5299
  if (issue.code === "invalid_key" && path16.startsWith("agents.")) {
5287
5300
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
@@ -6430,7 +6443,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
6430
6443
  options.autoUpdate = false;
6431
6444
  }
6432
6445
  if (options.autoUpdate !== false) {
6433
- await startSilentUpgrade("9.37.1");
6446
+ await startSilentUpgrade("9.37.3");
6434
6447
  }
6435
6448
  try {
6436
6449
  let result;
@@ -7128,7 +7141,6 @@ var CodexEventParser = class {
7128
7141
  }
7129
7142
  };
7130
7143
  }
7131
- // eslint-disable-next-line complexity -- TODO: refactor complex function
7132
7144
  static parseItemEvent(event) {
7133
7145
  const item = event.item;
7134
7146
  if (!item) {
@@ -7136,106 +7148,123 @@ var CodexEventParser = class {
7136
7148
  }
7137
7149
  const itemType = item.type;
7138
7150
  if (itemType === "agent_message" && item.text) {
7139
- return {
7140
- type: "text",
7141
- timestamp: /* @__PURE__ */ new Date(),
7142
- data: { text: item.text }
7143
- };
7151
+ return { type: "text", timestamp: /* @__PURE__ */ new Date(), data: { text: item.text } };
7144
7152
  }
7145
7153
  if (itemType === "command_execution") {
7146
- if (event.type === "item.started" && item.command) {
7147
- return {
7148
- type: "tool_use",
7149
- timestamp: /* @__PURE__ */ new Date(),
7150
- data: {
7151
- tool: "Bash",
7152
- toolUseId: item.id,
7153
- input: { command: item.command }
7154
- }
7155
- };
7156
- }
7157
- if (event.type === "item.completed") {
7158
- const output = item.aggregated_output ?? item.output ?? "";
7159
- return {
7160
- type: "tool_result",
7161
- timestamp: /* @__PURE__ */ new Date(),
7162
- data: {
7163
- toolUseId: item.id,
7164
- result: output,
7165
- isError: item.exit_code !== 0
7166
- }
7167
- };
7168
- }
7154
+ return this.parseCommandExecution(event);
7169
7155
  }
7170
7156
  if (itemType === "file_edit" || itemType === "file_write") {
7171
- if (event.type === "item.started" && item.path) {
7172
- return {
7173
- type: "tool_use",
7174
- timestamp: /* @__PURE__ */ new Date(),
7175
- data: {
7176
- tool: itemType === "file_edit" ? "Edit" : "Write",
7177
- toolUseId: item.id,
7178
- input: { file_path: item.path }
7179
- }
7180
- };
7181
- }
7182
- if (event.type === "item.completed") {
7183
- return {
7184
- type: "tool_result",
7185
- timestamp: /* @__PURE__ */ new Date(),
7186
- data: {
7187
- toolUseId: item.id,
7188
- result: item.diff || "File operation completed",
7189
- isError: false
7190
- }
7191
- };
7192
- }
7157
+ return this.parseFileEditOrWrite(event);
7193
7158
  }
7194
7159
  if (itemType === "file_read") {
7195
- if (event.type === "item.started" && item.path) {
7196
- return {
7197
- type: "tool_use",
7198
- timestamp: /* @__PURE__ */ new Date(),
7199
- data: {
7200
- tool: "Read",
7201
- toolUseId: item.id,
7202
- input: { file_path: item.path }
7203
- }
7204
- };
7205
- }
7206
- if (event.type === "item.completed") {
7207
- return {
7208
- type: "tool_result",
7209
- timestamp: /* @__PURE__ */ new Date(),
7210
- data: {
7211
- toolUseId: item.id,
7212
- result: "File read completed",
7213
- isError: false
7214
- }
7215
- };
7216
- }
7160
+ return this.parseFileRead(event);
7217
7161
  }
7218
- if (itemType === "file_change" && item.changes && item.changes.length > 0) {
7219
- const changes = item.changes.map((c25) => {
7220
- const action = c25.kind === "add" ? "Created" : c25.kind === "modify" ? "Modified" : "Deleted";
7221
- return `${action}: ${c25.path}`;
7222
- }).join("\n");
7162
+ if (itemType === "file_change") {
7163
+ return this.parseFileChange(item);
7164
+ }
7165
+ if (itemType === "reasoning" && item.text) {
7223
7166
  return {
7224
7167
  type: "text",
7225
7168
  timestamp: /* @__PURE__ */ new Date(),
7226
- data: { text: `[files]
7227
- ${changes}` }
7169
+ data: { text: `[thinking] ${item.text}` }
7228
7170
  };
7229
7171
  }
7230
- 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) {
7231
7177
  return {
7232
- type: "text",
7178
+ type: "tool_use",
7233
7179
  timestamp: /* @__PURE__ */ new Date(),
7234
- 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
+ }
7197
+ };
7198
+ }
7199
+ return null;
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
+ }
7235
7223
  };
7236
7224
  }
7237
7225
  return null;
7238
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
+ }
7239
7268
  static parseErrorEvent(event) {
7240
7269
  return {
7241
7270
  type: "result",
@@ -7335,7 +7364,6 @@ var CodexEventRenderer = class {
7335
7364
  chalk11.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
7336
7365
  );
7337
7366
  }
7338
- // eslint-disable-next-line complexity -- TODO: refactor complex function
7339
7367
  static renderItem(event) {
7340
7368
  const item = event.item;
7341
7369
  if (!item) return;
@@ -7343,48 +7371,50 @@ var CodexEventRenderer = class {
7343
7371
  const eventType = event.type;
7344
7372
  if (itemType === "reasoning" && item.text) {
7345
7373
  console.log(`[reasoning] ${item.text}`);
7346
- return;
7347
- }
7348
- if (itemType === "agent_message" && item.text) {
7374
+ } else if (itemType === "agent_message" && item.text) {
7349
7375
  console.log(`[message] ${item.text}`);
7350
- return;
7351
- }
7352
- if (itemType === "command_execution") {
7353
- if (eventType === "item.started" && item.command) {
7354
- console.log(`[exec] ${item.command}`);
7355
- } else if (eventType === "item.completed") {
7356
- const output = item.aggregated_output || "";
7357
- const exitCode = item.exit_code ?? 0;
7358
- if (output) {
7359
- const lines = output.split("\n").filter((l) => l.trim());
7360
- const preview = lines.slice(0, 3).join("\n ");
7361
- const more = lines.length > 3 ? chalk11.dim(` ... (${lines.length - 3} more lines)`) : "";
7362
- console.log(
7363
- "[output]" + (exitCode !== 0 ? chalk11.red(` exit=${exitCode}`) : "")
7364
- );
7365
- if (preview) {
7366
- console.log(" " + preview + more);
7367
- }
7368
- } else if (exitCode !== 0) {
7369
- 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);
7370
7399
  }
7400
+ } else if (exitCode !== 0) {
7401
+ console.log(chalk11.red("[output]") + chalk11.red(` exit=${exitCode}`));
7371
7402
  }
7372
- return;
7373
7403
  }
7374
- if (itemType === "file_change" && item.changes && item.changes.length > 0) {
7404
+ }
7405
+ static renderFileChange(item) {
7406
+ if (item.changes && item.changes.length > 0) {
7375
7407
  const summary = item.changes.map((c25) => {
7376
7408
  const icon = c25.kind === "add" ? "+" : c25.kind === "delete" ? "-" : "~";
7377
7409
  return `${icon}${c25.path}`;
7378
7410
  }).join(", ");
7379
7411
  console.log(chalk11.green("[files]") + ` ${summary}`);
7380
- return;
7381
7412
  }
7382
- if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
7383
- const action = itemType.replace("file_", "");
7384
- if (eventType === "item.started" && item.path) {
7385
- console.log(`[${action}] ${item.path}`);
7386
- }
7387
- 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}`);
7388
7418
  }
7389
7419
  }
7390
7420
  static renderError(event) {
@@ -8627,7 +8657,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
8627
8657
  async (identifier, prompt, options) => {
8628
8658
  try {
8629
8659
  if (options.autoUpdate !== false) {
8630
- await startSilentUpgrade("9.37.1");
8660
+ await startSilentUpgrade("9.37.3");
8631
8661
  }
8632
8662
  const { scope, name, version } = parseIdentifier(identifier);
8633
8663
  if (scope && !options.experimentalSharedAgent) {
@@ -10203,7 +10233,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
10203
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(
10204
10234
  async (prompt, options) => {
10205
10235
  if (options.autoUpdate !== false) {
10206
- const shouldExit = await checkAndUpgrade("9.37.1", prompt);
10236
+ const shouldExit = await checkAndUpgrade("9.37.3", prompt);
10207
10237
  if (shouldExit) {
10208
10238
  process.exit(0);
10209
10239
  }
@@ -10476,13 +10506,13 @@ function formatMetric(metric) {
10476
10506
  const diskPercent = (metric.disk_used / metric.disk_total * 100).toFixed(1);
10477
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}%)`;
10478
10508
  }
10479
- function formatNetworkLog(entry) {
10480
- if (entry.mode === "sni" || !entry.method) {
10481
- const actionColor = entry.action === "ALLOW" ? chalk37.green : chalk37.red;
10482
- const host = entry.host || "unknown";
10483
- const port = entry.port || 443;
10484
- return `[${entry.timestamp}] ${chalk37.cyan("SNI")} ${actionColor(entry.action || "ALLOW")} ${host}:${port} ${chalk37.dim(entry.rule_matched || "")}`;
10485
- }
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) {
10486
10516
  let statusColor;
10487
10517
  const status = entry.status || 0;
10488
10518
  if (status >= 200 && status < 300) {
@@ -10509,6 +10539,12 @@ function formatNetworkLog(entry) {
10509
10539
  const url = entry.url || entry.host || "unknown";
10510
10540
  return `[${entry.timestamp}] ${method.padEnd(6)} ${statusColor(status)} ${latencyColor(latencyMs + "ms")} ${formatBytes(requestSize)}/${formatBytes(responseSize)} ${chalk37.dim(url)}`;
10511
10541
  }
10542
+ function formatNetworkLog(entry) {
10543
+ if (entry.mode === "sni" || !entry.method) {
10544
+ return formatSniLog(entry);
10545
+ }
10546
+ return formatMitmLog(entry);
10547
+ }
10512
10548
  function createLogRenderer(verbose) {
10513
10549
  return new EventRenderer({
10514
10550
  showTimestamp: true,
@@ -14922,7 +14958,7 @@ var preferenceCommand = new Command77().name("preference").description("View or
14922
14958
 
14923
14959
  // src/index.ts
14924
14960
  var program = new Command78();
14925
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.37.1");
14961
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.37.3");
14926
14962
  program.addCommand(authCommand);
14927
14963
  program.addCommand(infoCommand);
14928
14964
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.37.1",
3
+ "version": "9.37.3",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",