@vm0/cli 9.33.0 → 9.34.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 +164 -59
  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.33.0",
48
+ release: "9.34.0",
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.33.0",
67
+ version: "9.34.0",
68
68
  command: process.argv.slice(2).join(" ")
69
69
  });
70
70
  Sentry.setContext("runtime", {
@@ -605,7 +605,7 @@ async function waitForSilentUpgrade(timeout = TIMEOUT_MS) {
605
605
  // src/commands/info/index.ts
606
606
  var CONFIG_PATH = join2(homedir2(), ".vm0", "config.json");
607
607
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
608
- console.log(chalk7.bold(`VM0 CLI v${"9.33.0"}`));
608
+ console.log(chalk7.bold(`VM0 CLI v${"9.34.0"}`));
609
609
  console.log();
610
610
  const config = await loadConfig();
611
611
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -6265,7 +6265,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
6265
6265
  options.autoUpdate = false;
6266
6266
  }
6267
6267
  if (options.autoUpdate !== false) {
6268
- await startSilentUpgrade("9.33.0");
6268
+ await startSilentUpgrade("9.34.0");
6269
6269
  }
6270
6270
  try {
6271
6271
  let result;
@@ -8462,7 +8462,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
8462
8462
  async (identifier, prompt, options) => {
8463
8463
  try {
8464
8464
  if (options.autoUpdate !== false) {
8465
- await startSilentUpgrade("9.33.0");
8465
+ await startSilentUpgrade("9.34.0");
8466
8466
  }
8467
8467
  const { scope, name, version } = parseIdentifier(identifier);
8468
8468
  if (scope && !options.experimentalSharedAgent) {
@@ -10038,7 +10038,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
10038
10038
  ).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(
10039
10039
  async (prompt, options) => {
10040
10040
  if (options.autoUpdate !== false) {
10041
- const shouldExit = await checkAndUpgrade("9.33.0", prompt);
10041
+ const shouldExit = await checkAndUpgrade("9.34.0", prompt);
10042
10042
  if (shouldExit) {
10043
10043
  process.exit(0);
10044
10044
  }
@@ -10264,6 +10264,32 @@ var cookCommand = cookAction;
10264
10264
  // src/commands/logs/index.ts
10265
10265
  import { Command as Command31 } from "commander";
10266
10266
  import chalk37 from "chalk";
10267
+
10268
+ // src/lib/utils/paginate.ts
10269
+ async function paginate(options) {
10270
+ const { fetchPage, getTimestamp, targetCount, initialSince } = options;
10271
+ const collected = [];
10272
+ let since = initialSince;
10273
+ let hasMore = true;
10274
+ while (hasMore) {
10275
+ const response = await fetchPage(since);
10276
+ collected.push(...response.items);
10277
+ hasMore = response.hasMore;
10278
+ if (targetCount !== "all" && collected.length >= targetCount) {
10279
+ return collected.slice(0, targetCount);
10280
+ }
10281
+ if (response.items.length > 0) {
10282
+ const lastItem = response.items[response.items.length - 1];
10283
+ since = getTimestamp(lastItem);
10284
+ } else {
10285
+ hasMore = false;
10286
+ }
10287
+ }
10288
+ return collected;
10289
+ }
10290
+
10291
+ // src/commands/logs/index.ts
10292
+ var PAGE_LIMIT = 100;
10267
10293
  function buildPlatformLogsUrl(apiUrl, runId) {
10268
10294
  const url = new URL(apiUrl);
10269
10295
  const hostname = url.hostname;
@@ -10359,13 +10385,20 @@ function getLogType(options) {
10359
10385
  var logsCommand2 = new Command31().name("logs").description("View logs for an agent run").argument("<runId>", "Run ID to fetch logs for").option("-a, --agent", "Show agent events (default)").option("-s, --system", "Show system log").option("-m, --metrics", "Show metrics").option("-n, --network", "Show network logs (proxy traffic)").option(
10360
10386
  "--since <time>",
10361
10387
  "Show logs since timestamp (e.g., 5m, 2h, 1d, 2024-01-15T10:30:00Z, 1705312200)"
10362
- ).option("--tail <n>", "Show last N entries (default: 5, max: 100)").option("--head <n>", "Show first N entries (max: 100)").action(
10388
+ ).option("--tail <n>", "Show last N entries (default: 5)").option("--head <n>", "Show first N entries").option("--all", "Fetch all log entries").action(
10363
10389
  async (runId, options) => {
10364
10390
  try {
10365
10391
  const logType = getLogType(options);
10366
- if (options.tail !== void 0 && options.head !== void 0) {
10392
+ const countModes = [
10393
+ options.tail !== void 0,
10394
+ options.head !== void 0,
10395
+ options.all === true
10396
+ ].filter(Boolean).length;
10397
+ if (countModes > 1) {
10367
10398
  console.error(
10368
- chalk37.red("Options --tail and --head are mutually exclusive")
10399
+ chalk37.red(
10400
+ "Options --tail, --head, and --all are mutually exclusive"
10401
+ )
10369
10402
  );
10370
10403
  process.exit(1);
10371
10404
  }
@@ -10373,26 +10406,38 @@ var logsCommand2 = new Command31().name("logs").description("View logs for an ag
10373
10406
  if (options.since) {
10374
10407
  since = parseTime(options.since);
10375
10408
  }
10409
+ const isAll = options.all === true;
10376
10410
  const isHead = options.head !== void 0;
10377
- const limit = Math.min(
10378
- Math.max(1, parseInt(options.head || options.tail || "5", 10)),
10379
- 100
10380
- );
10411
+ const isTail = options.tail !== void 0;
10412
+ let targetCount;
10413
+ if (isAll) {
10414
+ targetCount = "all";
10415
+ } else if (isHead) {
10416
+ targetCount = Math.max(1, parseInt(options.head, 10));
10417
+ } else if (isTail) {
10418
+ targetCount = Math.max(1, parseInt(options.tail, 10));
10419
+ } else {
10420
+ targetCount = 5;
10421
+ }
10381
10422
  const order = isHead ? "asc" : "desc";
10382
10423
  const apiUrl = await getApiUrl();
10383
10424
  const platformUrl = buildPlatformLogsUrl(apiUrl, runId);
10384
10425
  switch (logType) {
10385
10426
  case "agent":
10386
- await showAgentEvents(runId, { since, limit, order }, platformUrl);
10427
+ await showAgentEvents(
10428
+ runId,
10429
+ { since, targetCount, order },
10430
+ platformUrl
10431
+ );
10387
10432
  break;
10388
10433
  case "system":
10389
- await showSystemLog(runId, { since, limit, order });
10434
+ await showSystemLog(runId, { since, targetCount, order });
10390
10435
  break;
10391
10436
  case "metrics":
10392
- await showMetrics(runId, { since, limit, order });
10437
+ await showMetrics(runId, { since, targetCount, order });
10393
10438
  break;
10394
10439
  case "network":
10395
- await showNetworkLogs(runId, { since, limit, order });
10440
+ await showNetworkLogs(runId, { since, targetCount, order });
10396
10441
  break;
10397
10442
  }
10398
10443
  } catch (error) {
@@ -10402,62 +10447,106 @@ var logsCommand2 = new Command31().name("logs").description("View logs for an ag
10402
10447
  }
10403
10448
  );
10404
10449
  async function showAgentEvents(runId, options, platformUrl) {
10405
- const response = await apiClient.getAgentEvents(runId, options);
10406
- if (response.events.length === 0) {
10450
+ const firstResponse = await apiClient.getAgentEvents(runId, {
10451
+ since: options.since,
10452
+ limit: PAGE_LIMIT,
10453
+ order: options.order
10454
+ });
10455
+ if (firstResponse.events.length === 0) {
10407
10456
  console.log(chalk37.yellow("No agent events found for this run"));
10408
10457
  return;
10409
10458
  }
10410
- const events = options.order === "desc" ? [...response.events].reverse() : response.events;
10459
+ const framework = firstResponse.framework;
10460
+ let allEvents;
10461
+ if (!firstResponse.hasMore || options.targetCount !== "all" && firstResponse.events.length >= options.targetCount) {
10462
+ allEvents = options.targetCount === "all" ? firstResponse.events : firstResponse.events.slice(0, options.targetCount);
10463
+ } else {
10464
+ const lastEvent = firstResponse.events[firstResponse.events.length - 1];
10465
+ const firstPageTimestamp = lastEvent ? new Date(lastEvent.createdAt).getTime() : void 0;
10466
+ const remainingEvents = await paginate({
10467
+ fetchPage: async (since) => {
10468
+ const response = await apiClient.getAgentEvents(runId, {
10469
+ since,
10470
+ limit: PAGE_LIMIT,
10471
+ order: options.order
10472
+ });
10473
+ return { items: response.events, hasMore: response.hasMore };
10474
+ },
10475
+ getTimestamp: (event) => new Date(event.createdAt).getTime(),
10476
+ targetCount: options.targetCount === "all" ? "all" : options.targetCount - firstResponse.events.length,
10477
+ initialSince: firstPageTimestamp
10478
+ });
10479
+ allEvents = [...firstResponse.events, ...remainingEvents];
10480
+ if (options.targetCount !== "all" && allEvents.length > options.targetCount) {
10481
+ allEvents = allEvents.slice(0, options.targetCount);
10482
+ }
10483
+ }
10484
+ const events = options.order === "desc" ? [...allEvents].reverse() : allEvents;
10411
10485
  const renderer = createLogRenderer(true);
10412
10486
  for (const event of events) {
10413
- renderAgentEvent(event, response.framework, renderer);
10414
- }
10415
- if (response.hasMore) {
10416
- console.log();
10417
- console.log(
10418
- chalk37.dim(
10419
- `Showing ${response.events.length} events. Use --tail to see more.`
10420
- )
10421
- );
10487
+ renderAgentEvent(event, framework, renderer);
10422
10488
  }
10423
10489
  console.log(chalk37.dim(`View on platform: ${platformUrl}`));
10424
10490
  }
10425
10491
  async function showSystemLog(runId, options) {
10426
- const response = await apiClient.getSystemLog(runId, options);
10492
+ const limit = options.targetCount === "all" ? PAGE_LIMIT : Math.min(options.targetCount, PAGE_LIMIT);
10493
+ const response = await apiClient.getSystemLog(runId, {
10494
+ since: options.since,
10495
+ limit,
10496
+ order: options.order
10497
+ });
10427
10498
  if (!response.systemLog) {
10428
10499
  console.log(chalk37.yellow("No system log found for this run"));
10429
10500
  return;
10430
10501
  }
10431
10502
  console.log(response.systemLog);
10432
- if (response.hasMore) {
10433
- console.log();
10434
- console.log(
10435
- chalk37.dim("More log entries available. Use --tail to see more.")
10436
- );
10437
- }
10438
10503
  }
10439
10504
  async function showMetrics(runId, options) {
10440
- const response = await apiClient.getMetrics(runId, options);
10441
- if (response.metrics.length === 0) {
10505
+ const firstResponse = await apiClient.getMetrics(runId, {
10506
+ since: options.since,
10507
+ limit: PAGE_LIMIT,
10508
+ order: options.order
10509
+ });
10510
+ if (firstResponse.metrics.length === 0) {
10442
10511
  console.log(chalk37.yellow("No metrics found for this run"));
10443
10512
  return;
10444
10513
  }
10445
- const metrics = options.order === "desc" ? [...response.metrics].reverse() : response.metrics;
10514
+ let allMetrics;
10515
+ if (!firstResponse.hasMore || options.targetCount !== "all" && firstResponse.metrics.length >= options.targetCount) {
10516
+ allMetrics = options.targetCount === "all" ? firstResponse.metrics : firstResponse.metrics.slice(0, options.targetCount);
10517
+ } else {
10518
+ const lastMetric = firstResponse.metrics[firstResponse.metrics.length - 1];
10519
+ const firstPageTimestamp = lastMetric ? new Date(lastMetric.ts).getTime() : void 0;
10520
+ const remainingMetrics = await paginate({
10521
+ fetchPage: async (since) => {
10522
+ const response = await apiClient.getMetrics(runId, {
10523
+ since,
10524
+ limit: PAGE_LIMIT,
10525
+ order: options.order
10526
+ });
10527
+ return { items: response.metrics, hasMore: response.hasMore };
10528
+ },
10529
+ getTimestamp: (metric) => new Date(metric.ts).getTime(),
10530
+ targetCount: options.targetCount === "all" ? "all" : options.targetCount - firstResponse.metrics.length,
10531
+ initialSince: firstPageTimestamp
10532
+ });
10533
+ allMetrics = [...firstResponse.metrics, ...remainingMetrics];
10534
+ if (options.targetCount !== "all" && allMetrics.length > options.targetCount) {
10535
+ allMetrics = allMetrics.slice(0, options.targetCount);
10536
+ }
10537
+ }
10538
+ const metrics = options.order === "desc" ? [...allMetrics].reverse() : allMetrics;
10446
10539
  for (const metric of metrics) {
10447
10540
  console.log(formatMetric(metric));
10448
10541
  }
10449
- if (response.hasMore) {
10450
- console.log();
10451
- console.log(
10452
- chalk37.dim(
10453
- `Showing ${response.metrics.length} metrics. Use --tail to see more.`
10454
- )
10455
- );
10456
- }
10457
10542
  }
10458
10543
  async function showNetworkLogs(runId, options) {
10459
- const response = await apiClient.getNetworkLogs(runId, options);
10460
- if (response.networkLogs.length === 0) {
10544
+ const firstResponse = await apiClient.getNetworkLogs(runId, {
10545
+ since: options.since,
10546
+ limit: PAGE_LIMIT,
10547
+ order: options.order
10548
+ });
10549
+ if (firstResponse.networkLogs.length === 0) {
10461
10550
  console.log(
10462
10551
  chalk37.yellow(
10463
10552
  "No network logs found for this run. Network logs are only captured when experimental_firewall is enabled on an experimental_runner"
@@ -10465,18 +10554,34 @@ async function showNetworkLogs(runId, options) {
10465
10554
  );
10466
10555
  return;
10467
10556
  }
10468
- const networkLogs = options.order === "desc" ? [...response.networkLogs].reverse() : response.networkLogs;
10557
+ let allNetworkLogs;
10558
+ if (!firstResponse.hasMore || options.targetCount !== "all" && firstResponse.networkLogs.length >= options.targetCount) {
10559
+ allNetworkLogs = options.targetCount === "all" ? firstResponse.networkLogs : firstResponse.networkLogs.slice(0, options.targetCount);
10560
+ } else {
10561
+ const lastLog = firstResponse.networkLogs[firstResponse.networkLogs.length - 1];
10562
+ const firstPageTimestamp = lastLog ? new Date(lastLog.timestamp).getTime() : void 0;
10563
+ const remainingLogs = await paginate({
10564
+ fetchPage: async (since) => {
10565
+ const response = await apiClient.getNetworkLogs(runId, {
10566
+ since,
10567
+ limit: PAGE_LIMIT,
10568
+ order: options.order
10569
+ });
10570
+ return { items: response.networkLogs, hasMore: response.hasMore };
10571
+ },
10572
+ getTimestamp: (entry) => new Date(entry.timestamp).getTime(),
10573
+ targetCount: options.targetCount === "all" ? "all" : options.targetCount - firstResponse.networkLogs.length,
10574
+ initialSince: firstPageTimestamp
10575
+ });
10576
+ allNetworkLogs = [...firstResponse.networkLogs, ...remainingLogs];
10577
+ if (options.targetCount !== "all" && allNetworkLogs.length > options.targetCount) {
10578
+ allNetworkLogs = allNetworkLogs.slice(0, options.targetCount);
10579
+ }
10580
+ }
10581
+ const networkLogs = options.order === "desc" ? [...allNetworkLogs].reverse() : allNetworkLogs;
10469
10582
  for (const entry of networkLogs) {
10470
10583
  console.log(formatNetworkLog(entry));
10471
10584
  }
10472
- if (response.hasMore) {
10473
- console.log();
10474
- console.log(
10475
- chalk37.dim(
10476
- `Showing ${response.networkLogs.length} network logs. Use --tail to see more.`
10477
- )
10478
- );
10479
- }
10480
10585
  }
10481
10586
  function handleError2(error, runId) {
10482
10587
  if (error instanceof Error) {
@@ -14500,7 +14605,7 @@ var devToolCommand = new Command76().name("dev-tool").description("Developer too
14500
14605
 
14501
14606
  // src/index.ts
14502
14607
  var program = new Command77();
14503
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.33.0");
14608
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.34.0");
14504
14609
  program.addCommand(authCommand);
14505
14610
  program.addCommand(infoCommand);
14506
14611
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.33.0",
3
+ "version": "9.34.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",