@vm0/cli 3.6.0 → 3.8.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 +127 -16
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -13115,7 +13115,7 @@ var DEFAULT_TIMEOUT_SECONDS = 120;
13115
13115
  async function pollEvents(runId, timeoutSeconds, options) {
13116
13116
  let nextSequence = -1;
13117
13117
  let complete = false;
13118
- let runSucceeded = true;
13118
+ let result = { succeeded: true };
13119
13119
  const pollIntervalMs = 500;
13120
13120
  const timeoutMs = timeoutSeconds * 1e3;
13121
13121
  const startTime = Date.now();
@@ -13149,10 +13149,14 @@ async function pollEvents(runId, timeoutSeconds, options) {
13149
13149
  previousTimestamp = parsed.timestamp;
13150
13150
  if (parsed.type === "vm0_result") {
13151
13151
  complete = true;
13152
- runSucceeded = true;
13152
+ result = {
13153
+ succeeded: true,
13154
+ sessionId: parsed.data.agentSessionId,
13155
+ checkpointId: parsed.data.checkpointId
13156
+ };
13153
13157
  } else if (parsed.type === "vm0_error") {
13154
13158
  complete = true;
13155
- runSucceeded = false;
13159
+ result = { succeeded: false };
13156
13160
  }
13157
13161
  }
13158
13162
  }
@@ -13161,7 +13165,7 @@ async function pollEvents(runId, timeoutSeconds, options) {
13161
13165
  await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
13162
13166
  }
13163
13167
  }
13164
- return runSucceeded;
13168
+ return result;
13165
13169
  }
13166
13170
  function logVerbosePreFlight(action, details) {
13167
13171
  console.log(chalk4.blue(`
@@ -13175,6 +13179,25 @@ ${action}...`));
13175
13179
  console.log(chalk4.blue("Executing in sandbox..."));
13176
13180
  console.log();
13177
13181
  }
13182
+ function showNextSteps(result) {
13183
+ const { sessionId, checkpointId } = result;
13184
+ if (sessionId || checkpointId) {
13185
+ console.log();
13186
+ console.log("Next steps:");
13187
+ if (sessionId) {
13188
+ console.log(" Continue with session (latest state):");
13189
+ console.log(
13190
+ chalk4.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
13191
+ );
13192
+ }
13193
+ if (checkpointId) {
13194
+ console.log(" Resume from checkpoint (exact snapshot state):");
13195
+ console.log(
13196
+ chalk4.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
13197
+ );
13198
+ }
13199
+ }
13200
+ }
13178
13201
  var runCmd = new Command2().name("run").description("Execute an agent").argument(
13179
13202
  "<identifier>",
13180
13203
  "Agent name, config ID, or name:version (e.g., 'my-agent', 'my-agent:abc123', 'my-agent:latest')"
@@ -13305,13 +13328,14 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
13305
13328
  volumeVersions: Object.keys(options.volumeVersion).length > 0 ? options.volumeVersion : void 0,
13306
13329
  conversationId: options.conversation
13307
13330
  });
13308
- const succeeded = await pollEvents(response.runId, timeoutSeconds, {
13331
+ const result = await pollEvents(response.runId, timeoutSeconds, {
13309
13332
  verbose,
13310
13333
  startTimestamp
13311
13334
  });
13312
- if (!succeeded) {
13335
+ if (!result.succeeded) {
13313
13336
  process.exit(1);
13314
13337
  }
13338
+ showNextSteps(result);
13315
13339
  } catch (error43) {
13316
13340
  if (error43 instanceof Error) {
13317
13341
  if (error43.message.includes("Not authenticated")) {
@@ -13378,13 +13402,14 @@ runCmd.command("resume").description("Resume an agent run from a checkpoint (use
13378
13402
  prompt,
13379
13403
  volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
13380
13404
  });
13381
- const succeeded = await pollEvents(response.runId, timeoutSeconds, {
13405
+ const result = await pollEvents(response.runId, timeoutSeconds, {
13382
13406
  verbose,
13383
13407
  startTimestamp
13384
13408
  });
13385
- if (!succeeded) {
13409
+ if (!result.succeeded) {
13386
13410
  process.exit(1);
13387
13411
  }
13412
+ showNextSteps(result);
13388
13413
  } catch (error43) {
13389
13414
  if (error43 instanceof Error) {
13390
13415
  if (error43.message.includes("Not authenticated")) {
@@ -13451,13 +13476,14 @@ runCmd.command("continue").description(
13451
13476
  prompt,
13452
13477
  volumeVersions: Object.keys(allOpts.volumeVersion).length > 0 ? allOpts.volumeVersion : void 0
13453
13478
  });
13454
- const succeeded = await pollEvents(response.runId, timeoutSeconds, {
13479
+ const result = await pollEvents(response.runId, timeoutSeconds, {
13455
13480
  verbose,
13456
13481
  startTimestamp
13457
13482
  });
13458
- if (!succeeded) {
13483
+ if (!result.succeeded) {
13459
13484
  process.exit(1);
13460
13485
  }
13486
+ showNextSteps(result);
13461
13487
  } catch (error43) {
13462
13488
  if (error43 instanceof Error) {
13463
13489
  if (error43.message.includes("Not authenticated")) {
@@ -14332,7 +14358,60 @@ function execVm0Command(args, options = {}) {
14332
14358
  });
14333
14359
  });
14334
14360
  }
14335
- var cookCommand = new Command15().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
14361
+ function execVm0RunWithCapture(args, options = {}) {
14362
+ return new Promise((resolve, reject) => {
14363
+ const proc = spawn("vm0", args, {
14364
+ cwd: options.cwd,
14365
+ stdio: ["inherit", "pipe", "pipe"],
14366
+ shell: process.platform === "win32"
14367
+ });
14368
+ let stdout = "";
14369
+ let stderr = "";
14370
+ proc.stdout?.on("data", (data) => {
14371
+ const chunk = data.toString();
14372
+ stdout += chunk;
14373
+ process.stdout.write(chunk);
14374
+ });
14375
+ proc.stderr?.on("data", (data) => {
14376
+ const chunk = data.toString();
14377
+ stderr += chunk;
14378
+ process.stderr.write(chunk);
14379
+ });
14380
+ proc.on("close", (code) => {
14381
+ if (code === 0) {
14382
+ resolve(stdout);
14383
+ } else {
14384
+ reject(new Error(stderr || `Command failed with exit code ${code}`));
14385
+ }
14386
+ });
14387
+ proc.on("error", (err) => {
14388
+ reject(err);
14389
+ });
14390
+ });
14391
+ }
14392
+ function parseArtifactVersion(output, artifactName, eventType) {
14393
+ const eventMarker = eventType === "vm0_start" ? "[vm0_start]" : "[vm0_result]";
14394
+ const eventIndex = output.indexOf(eventMarker);
14395
+ if (eventIndex === -1) return null;
14396
+ const nextEventIndex = output.indexOf(
14397
+ eventType === "vm0_start" ? "[vm0_result]" : "[vm0_error]",
14398
+ eventIndex
14399
+ );
14400
+ const section = nextEventIndex === -1 ? output.slice(eventIndex) : output.slice(eventIndex, nextEventIndex);
14401
+ const artifactPattern = new RegExp(
14402
+ `^\\s*${escapeRegExp(artifactName)}:\\s*(?:\\x1b\\[[0-9;]*m)?([a-f0-9]+)`,
14403
+ "m"
14404
+ );
14405
+ const match = section.match(artifactPattern);
14406
+ return match ? match[1] : null;
14407
+ }
14408
+ function escapeRegExp(str) {
14409
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14410
+ }
14411
+ var cookCommand = new Command15().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").option(
14412
+ "-t, --timeout <seconds>",
14413
+ "Polling timeout in seconds for agent run (default: 120)"
14414
+ ).action(async (prompt, options) => {
14336
14415
  const cwd = process.cwd();
14337
14416
  console.log(chalk14.blue(`Reading config: ${CONFIG_FILE3}`));
14338
14417
  if (!existsSync4(CONFIG_FILE3)) {
@@ -14446,14 +14525,46 @@ var cookCommand = new Command15().name("cook").description("One-click agent prep
14446
14525
  console.log();
14447
14526
  console.log(chalk14.blue(`Running agent: ${agentName}`));
14448
14527
  console.log();
14528
+ let runOutput;
14449
14529
  try {
14450
- await execVm0Command(
14451
- ["run", agentName, "--artifact-name", ARTIFACT_DIR, prompt],
14452
- { cwd, silent: false }
14453
- );
14530
+ const runArgs = [
14531
+ "run",
14532
+ agentName,
14533
+ "--artifact-name",
14534
+ ARTIFACT_DIR,
14535
+ ...options.timeout ? ["--timeout", options.timeout] : [],
14536
+ prompt
14537
+ ];
14538
+ runOutput = await execVm0RunWithCapture(runArgs, { cwd });
14454
14539
  } catch {
14455
14540
  process.exit(1);
14456
14541
  }
14542
+ const startVersion = parseArtifactVersion(
14543
+ runOutput,
14544
+ ARTIFACT_DIR,
14545
+ "vm0_start"
14546
+ );
14547
+ const endVersion = parseArtifactVersion(
14548
+ runOutput,
14549
+ ARTIFACT_DIR,
14550
+ "vm0_result"
14551
+ );
14552
+ if (startVersion && endVersion && startVersion !== endVersion) {
14553
+ console.log();
14554
+ console.log(chalk14.blue("Pulling updated artifact..."));
14555
+ try {
14556
+ await execVm0Command(["artifact", "pull"], {
14557
+ cwd: artifactDir,
14558
+ silent: true
14559
+ });
14560
+ console.log(chalk14.green(`\u2713 Artifact pulled (${endVersion})`));
14561
+ } catch (error43) {
14562
+ console.error(chalk14.red(`\u2717 Artifact pull failed`));
14563
+ if (error43 instanceof Error) {
14564
+ console.error(chalk14.gray(` ${error43.message}`));
14565
+ }
14566
+ }
14567
+ }
14457
14568
  } else {
14458
14569
  console.log();
14459
14570
  console.log(" Run your agent:");
@@ -14467,7 +14578,7 @@ var cookCommand = new Command15().name("cook").description("One-click agent prep
14467
14578
 
14468
14579
  // src/index.ts
14469
14580
  var program = new Command16();
14470
- program.name("vm0").description("VM0 CLI - A modern build tool").version("3.6.0");
14581
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("3.8.0");
14471
14582
  program.command("hello").description("Say hello from the App").action(() => {
14472
14583
  console.log(chalk15.blue("Welcome to the VM0 CLI!"));
14473
14584
  console.log(chalk15.green(`Core says: ${FOO}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "3.6.0",
3
+ "version": "3.8.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",