@vm0/cli 9.38.0 → 9.38.2

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 +206 -172
  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.38.0",
48
+ release: "9.38.2",
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.38.0",
67
+ version: "9.38.2",
68
68
  command: process.argv.slice(2).join(" ")
69
69
  });
70
70
  Sentry.setContext("runtime", {
@@ -607,7 +607,7 @@ function getConfigPath() {
607
607
  return join2(homedir2(), ".vm0", "config.json");
608
608
  }
609
609
  var infoCommand = new Command6().name("info").description("Display environment and debug information").action(async () => {
610
- console.log(chalk7.bold(`VM0 CLI v${"9.38.0"}`));
610
+ console.log(chalk7.bold(`VM0 CLI v${"9.38.2"}`));
611
611
  console.log();
612
612
  const config = await loadConfig();
613
613
  const hasEnvToken = !!process.env.VM0_TOKEN;
@@ -641,7 +641,7 @@ import { Command as Command7, Option } from "commander";
641
641
  import chalk8 from "chalk";
642
642
  import { readFile as readFile4, rm as rm3 } from "fs/promises";
643
643
  import { existsSync as existsSync5 } from "fs";
644
- import { dirname as dirname2, join as join7 } from "path";
644
+ import { dirname as dirname2, join as join8 } from "path";
645
645
  import { parse as parseYaml2 } from "yaml";
646
646
 
647
647
  // ../../packages/core/src/variable-expander.ts
@@ -4646,18 +4646,18 @@ async function getRawHeaders() {
4646
4646
  }
4647
4647
  return headers;
4648
4648
  }
4649
- async function httpGet(path16) {
4649
+ async function httpGet(path17) {
4650
4650
  const baseUrl = await getBaseUrl();
4651
4651
  const headers = await getRawHeaders();
4652
- return fetch(`${baseUrl}${path16}`, {
4652
+ return fetch(`${baseUrl}${path17}`, {
4653
4653
  method: "GET",
4654
4654
  headers
4655
4655
  });
4656
4656
  }
4657
- async function httpPost(path16, body) {
4657
+ async function httpPost(path17, body) {
4658
4658
  const baseUrl = await getBaseUrl();
4659
4659
  const headers = await getRawHeaders();
4660
- return fetch(`${baseUrl}${path16}`, {
4660
+ return fetch(`${baseUrl}${path17}`, {
4661
4661
  method: "POST",
4662
4662
  headers: {
4663
4663
  ...headers,
@@ -4666,10 +4666,10 @@ async function httpPost(path16, body) {
4666
4666
  body: JSON.stringify(body)
4667
4667
  });
4668
4668
  }
4669
- async function httpDelete(path16) {
4669
+ async function httpDelete(path17) {
4670
4670
  const baseUrl = await getBaseUrl();
4671
4671
  const headers = await getRawHeaders();
4672
- return fetch(`${baseUrl}${path16}`, {
4672
+ return fetch(`${baseUrl}${path17}`, {
4673
4673
  method: "DELETE",
4674
4674
  headers
4675
4675
  });
@@ -5287,29 +5287,29 @@ var cliComposeSchema = z29.object({
5287
5287
  }
5288
5288
  }
5289
5289
  });
5290
- function formatInvalidTypeIssue(path16, issue) {
5290
+ function formatInvalidTypeIssue(path17, issue) {
5291
5291
  const received = issue.received;
5292
5292
  const isMissing = received === "undefined" || issue.message.includes("received undefined") || issue.message === "Required";
5293
- if (path16 === "version" && isMissing) {
5293
+ if (path17 === "version" && isMissing) {
5294
5294
  return "Missing config.version";
5295
5295
  }
5296
- if (path16 === "agents" && isMissing) {
5296
+ if (path17 === "agents" && isMissing) {
5297
5297
  return "Missing agents object in config";
5298
5298
  }
5299
- if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
5300
- const volumeKey = path16.split(".")[1];
5299
+ if (path17.startsWith("volumes.") && path17.endsWith(".name")) {
5300
+ const volumeKey = path17.split(".")[1];
5301
5301
  return `Volume "${volumeKey}" must have a 'name' field (string)`;
5302
5302
  }
5303
- if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
5304
- const volumeKey = path16.split(".")[1];
5303
+ if (path17.startsWith("volumes.") && path17.endsWith(".version")) {
5304
+ const volumeKey = path17.split(".")[1];
5305
5305
  return `Volume "${volumeKey}" must have a 'version' field (string)`;
5306
5306
  }
5307
5307
  if (issue.expected === "array") {
5308
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5308
+ const fieldName = path17.replace(/^agents\.[^.]+\./, "agent.");
5309
5309
  return `${fieldName} must be an array`;
5310
5310
  }
5311
5311
  if (issue.expected === "string" && received === "number") {
5312
- const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
5312
+ const fieldName = path17.replace(/^agents\.[^.]+\./, "agent.");
5313
5313
  const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
5314
5314
  if (match) {
5315
5315
  return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
@@ -5320,24 +5320,24 @@ function formatInvalidTypeIssue(path16, issue) {
5320
5320
  function formatZodError(error) {
5321
5321
  const issue = error.issues[0];
5322
5322
  if (!issue) return "Validation failed";
5323
- const path16 = issue.path.join(".");
5323
+ const path17 = issue.path.join(".");
5324
5324
  const message = issue.message;
5325
- if (!path16) return message;
5325
+ if (!path17) return message;
5326
5326
  if (issue.code === "invalid_type") {
5327
- const formatted = formatInvalidTypeIssue(path16, issue);
5327
+ const formatted = formatInvalidTypeIssue(path17, issue);
5328
5328
  if (formatted) return formatted;
5329
5329
  }
5330
- if (issue.code === "invalid_key" && path16.startsWith("agents.")) {
5330
+ if (issue.code === "invalid_key" && path17.startsWith("agents.")) {
5331
5331
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
5332
5332
  }
5333
- if (message === "Invalid key in record" && path16.startsWith("agents.")) {
5333
+ if (message === "Invalid key in record" && path17.startsWith("agents.")) {
5334
5334
  return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
5335
5335
  }
5336
5336
  if (issue.code === "custom") {
5337
5337
  return message;
5338
5338
  }
5339
- if (path16.startsWith("agents.")) {
5340
- const cleanPath = path16.replace(/^agents\.[^.]+\./, "agent.");
5339
+ if (path17.startsWith("agents.")) {
5340
+ const cleanPath = path17.replace(/^agents\.[^.]+\./, "agent.");
5341
5341
  if (message.startsWith("Invalid input:")) {
5342
5342
  const match = message.match(/expected (\w+), received (\w+)/);
5343
5343
  if (match && match[1] === "string" && match[2] === "number") {
@@ -5349,7 +5349,7 @@ function formatZodError(error) {
5349
5349
  }
5350
5350
  return `${cleanPath}: ${message}`;
5351
5351
  }
5352
- return `${path16}: ${message}`;
5352
+ return `${path17}: ${message}`;
5353
5353
  }
5354
5354
  function validateAgentName(name) {
5355
5355
  return cliAgentNameSchema.safeParse(name).success;
@@ -5396,25 +5396,17 @@ function validateAgentCompose(config) {
5396
5396
  }
5397
5397
 
5398
5398
  // src/lib/domain/github-skills.ts
5399
+ import * as fs2 from "fs/promises";
5400
+ import * as path2 from "path";
5401
+ import { parse as parseYaml } from "yaml";
5402
+
5403
+ // src/lib/external/git-client.ts
5399
5404
  import * as fs from "fs/promises";
5400
5405
  import * as path from "path";
5401
5406
  import * as os2 from "os";
5402
5407
  import { exec } from "child_process";
5403
5408
  import { promisify } from "util";
5404
- import { parse as parseYaml } from "yaml";
5405
5409
  var execAsync = promisify(exec);
5406
- function parseGitHubTreeUrl2(url) {
5407
- const parsed = parseGitHubTreeUrl(url);
5408
- if (!parsed) {
5409
- throw new Error(
5410
- `Invalid GitHub tree URL: ${url}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
5411
- );
5412
- }
5413
- return parsed;
5414
- }
5415
- function getSkillStorageName2(parsed) {
5416
- return getSkillStorageName(parsed.fullPath);
5417
- }
5418
5410
  async function downloadGitHubSkill(parsed, destDir) {
5419
5411
  const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
5420
5412
  const skillDir = path.join(destDir, parsed.skillName);
@@ -5512,10 +5504,24 @@ async function downloadGitHubDirectory(url) {
5512
5504
  throw error;
5513
5505
  }
5514
5506
  }
5507
+
5508
+ // src/lib/domain/github-skills.ts
5509
+ function parseGitHubTreeUrl2(url) {
5510
+ const parsed = parseGitHubTreeUrl(url);
5511
+ if (!parsed) {
5512
+ throw new Error(
5513
+ `Invalid GitHub tree URL: ${url}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
5514
+ );
5515
+ }
5516
+ return parsed;
5517
+ }
5518
+ function getSkillStorageName2(parsed) {
5519
+ return getSkillStorageName(parsed.fullPath);
5520
+ }
5515
5521
  async function validateSkillDirectory(skillDir) {
5516
- const skillMdPath = path.join(skillDir, "SKILL.md");
5522
+ const skillMdPath = path2.join(skillDir, "SKILL.md");
5517
5523
  try {
5518
- await fs.access(skillMdPath);
5524
+ await fs2.access(skillMdPath);
5519
5525
  } catch {
5520
5526
  throw new Error(
5521
5527
  `Skill directory missing required SKILL.md file: ${skillDir}`
@@ -5549,36 +5555,36 @@ function parseSkillFrontmatter(content) {
5549
5555
  };
5550
5556
  }
5551
5557
  async function readSkillFrontmatter(skillDir) {
5552
- const skillMdPath = path.join(skillDir, "SKILL.md");
5553
- const content = await fs.readFile(skillMdPath, "utf8");
5558
+ const skillMdPath = path2.join(skillDir, "SKILL.md");
5559
+ const content = await fs2.readFile(skillMdPath, "utf8");
5554
5560
  return parseSkillFrontmatter(content);
5555
5561
  }
5556
5562
 
5557
5563
  // src/lib/storage/system-storage.ts
5558
- import * as fs4 from "fs/promises";
5559
- import * as path4 from "path";
5564
+ import * as fs5 from "fs/promises";
5565
+ import * as path5 from "path";
5560
5566
  import * as os4 from "os";
5561
5567
 
5562
5568
  // src/lib/storage/direct-upload.ts
5563
5569
  import { createHash } from "crypto";
5564
- import * as fs3 from "fs";
5565
- import * as path3 from "path";
5570
+ import * as fs4 from "fs";
5571
+ import * as path4 from "path";
5566
5572
  import * as os3 from "os";
5567
5573
  import * as tar2 from "tar";
5568
5574
 
5569
5575
  // src/lib/utils/file-utils.ts
5570
- import * as fs2 from "fs";
5571
- import * as path2 from "path";
5576
+ import * as fs3 from "fs";
5577
+ import * as path3 from "path";
5572
5578
  import * as tar from "tar";
5573
5579
  function checkDirectoryStatus(dirPath) {
5574
- if (!fs2.existsSync(dirPath)) {
5580
+ if (!fs3.existsSync(dirPath)) {
5575
5581
  return { exists: false, empty: true };
5576
5582
  }
5577
- const stat = fs2.statSync(dirPath);
5583
+ const stat = fs3.statSync(dirPath);
5578
5584
  if (!stat.isDirectory()) {
5579
5585
  return { exists: true, empty: false };
5580
5586
  }
5581
- const entries = fs2.readdirSync(dirPath);
5587
+ const entries = fs3.readdirSync(dirPath);
5582
5588
  return { exists: true, empty: entries.length === 0 };
5583
5589
  }
5584
5590
  function formatBytes(bytes) {
@@ -5623,14 +5629,14 @@ function listTarFiles(tarPath) {
5623
5629
  async function listLocalFiles(dir, excludeDirs = [".vm0"]) {
5624
5630
  const files = [];
5625
5631
  async function walkDir(currentDir, relativePath = "") {
5626
- const entries = await fs2.promises.readdir(currentDir, {
5632
+ const entries = await fs3.promises.readdir(currentDir, {
5627
5633
  withFileTypes: true
5628
5634
  });
5629
5635
  for (const entry of entries) {
5630
- const entryRelativePath = relativePath ? path2.join(relativePath, entry.name) : entry.name;
5636
+ const entryRelativePath = relativePath ? path3.join(relativePath, entry.name) : entry.name;
5631
5637
  if (entry.isDirectory()) {
5632
5638
  if (!excludeDirs.includes(entry.name)) {
5633
- await walkDir(path2.join(currentDir, entry.name), entryRelativePath);
5639
+ await walkDir(path3.join(currentDir, entry.name), entryRelativePath);
5634
5640
  }
5635
5641
  } else {
5636
5642
  files.push(entryRelativePath);
@@ -5646,8 +5652,8 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
5646
5652
  for (const localFile of localFiles) {
5647
5653
  const normalizedPath = localFile.replace(/\\/g, "/");
5648
5654
  if (!remoteFiles.has(normalizedPath)) {
5649
- const fullPath = path2.join(dir, localFile);
5650
- await fs2.promises.unlink(fullPath);
5655
+ const fullPath = path3.join(dir, localFile);
5656
+ await fs3.promises.unlink(fullPath);
5651
5657
  removedCount++;
5652
5658
  }
5653
5659
  }
@@ -5655,17 +5661,17 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
5655
5661
  return removedCount;
5656
5662
  }
5657
5663
  async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
5658
- const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
5664
+ const entries = await fs3.promises.readdir(dir, { withFileTypes: true });
5659
5665
  let isEmpty = true;
5660
5666
  for (const entry of entries) {
5661
- const fullPath = path2.join(dir, entry.name);
5667
+ const fullPath = path3.join(dir, entry.name);
5662
5668
  if (entry.isDirectory()) {
5663
5669
  if (excludeDirs.includes(entry.name)) {
5664
5670
  isEmpty = false;
5665
5671
  } else {
5666
5672
  const subDirEmpty = await removeEmptyDirs(fullPath, excludeDirs);
5667
5673
  if (subDirEmpty) {
5668
- await fs2.promises.rmdir(fullPath);
5674
+ await fs3.promises.rmdir(fullPath);
5669
5675
  } else {
5670
5676
  isEmpty = false;
5671
5677
  }
@@ -5681,7 +5687,7 @@ async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
5681
5687
  async function hashFileStream(filePath) {
5682
5688
  return new Promise((resolve, reject) => {
5683
5689
  const hash = createHash("sha256");
5684
- const stream = fs3.createReadStream(filePath);
5690
+ const stream = fs4.createReadStream(filePath);
5685
5691
  stream.on("data", (chunk) => hash.update(chunk));
5686
5692
  stream.on("end", () => resolve(hash.digest("hex")));
5687
5693
  stream.on("error", reject);
@@ -5689,10 +5695,10 @@ async function hashFileStream(filePath) {
5689
5695
  }
5690
5696
  async function getAllFiles(dirPath, baseDir = dirPath) {
5691
5697
  const files = [];
5692
- const entries = await fs3.promises.readdir(dirPath, { withFileTypes: true });
5698
+ const entries = await fs4.promises.readdir(dirPath, { withFileTypes: true });
5693
5699
  for (const entry of entries) {
5694
- const fullPath = path3.join(dirPath, entry.name);
5695
- const relativePath = path3.relative(baseDir, fullPath);
5700
+ const fullPath = path4.join(dirPath, entry.name);
5701
+ const relativePath = path4.relative(baseDir, fullPath);
5696
5702
  if (relativePath.startsWith(".vm0")) {
5697
5703
  continue;
5698
5704
  }
@@ -5709,10 +5715,10 @@ async function collectFileMetadata(cwd, files, onProgress) {
5709
5715
  const fileEntries = [];
5710
5716
  for (let i = 0; i < files.length; i++) {
5711
5717
  const file = files[i];
5712
- const relativePath = path3.relative(cwd, file);
5718
+ const relativePath = path4.relative(cwd, file);
5713
5719
  const [hash, stats] = await Promise.all([
5714
5720
  hashFileStream(file),
5715
- fs3.promises.stat(file)
5721
+ fs4.promises.stat(file)
5716
5722
  ]);
5717
5723
  fileEntries.push({
5718
5724
  path: relativePath,
@@ -5726,10 +5732,10 @@ async function collectFileMetadata(cwd, files, onProgress) {
5726
5732
  return fileEntries;
5727
5733
  }
5728
5734
  async function createArchive(cwd, files) {
5729
- const tmpDir = fs3.mkdtempSync(path3.join(os3.tmpdir(), "vm0-"));
5730
- const tarPath = path3.join(tmpDir, "archive.tar.gz");
5735
+ const tmpDir = fs4.mkdtempSync(path4.join(os3.tmpdir(), "vm0-"));
5736
+ const tarPath = path4.join(tmpDir, "archive.tar.gz");
5731
5737
  try {
5732
- const relativePaths = files.map((file) => path3.relative(cwd, file));
5738
+ const relativePaths = files.map((file) => path4.relative(cwd, file));
5733
5739
  if (relativePaths.length > 0) {
5734
5740
  await tar2.create(
5735
5741
  {
@@ -5750,13 +5756,13 @@ async function createArchive(cwd, files) {
5750
5756
  ["."]
5751
5757
  );
5752
5758
  }
5753
- const tarBuffer = await fs3.promises.readFile(tarPath);
5759
+ const tarBuffer = await fs4.promises.readFile(tarPath);
5754
5760
  return tarBuffer;
5755
5761
  } finally {
5756
- if (fs3.existsSync(tarPath)) {
5757
- await fs3.promises.unlink(tarPath);
5762
+ if (fs4.existsSync(tarPath)) {
5763
+ await fs4.promises.unlink(tarPath);
5758
5764
  }
5759
- await fs3.promises.rmdir(tmpDir);
5765
+ await fs4.promises.rmdir(tmpDir);
5760
5766
  }
5761
5767
  }
5762
5768
  function createManifest(files) {
@@ -5881,13 +5887,13 @@ function getInstructionsFilename(framework) {
5881
5887
  }
5882
5888
  async function uploadInstructions(agentName, instructionsFilePath, basePath, framework) {
5883
5889
  const storageName = getInstructionsStorageName(agentName.toLowerCase());
5884
- const absolutePath = path4.isAbsolute(instructionsFilePath) ? instructionsFilePath : path4.join(basePath, instructionsFilePath);
5885
- const content = await fs4.readFile(absolutePath, "utf8");
5886
- const tmpDir = await fs4.mkdtemp(path4.join(os4.tmpdir(), "vm0-instructions-"));
5887
- const instructionsDir = path4.join(tmpDir, "instructions");
5888
- await fs4.mkdir(instructionsDir);
5890
+ const absolutePath = path5.isAbsolute(instructionsFilePath) ? instructionsFilePath : path5.join(basePath, instructionsFilePath);
5891
+ const content = await fs5.readFile(absolutePath, "utf8");
5892
+ const tmpDir = await fs5.mkdtemp(path5.join(os4.tmpdir(), "vm0-instructions-"));
5893
+ const instructionsDir = path5.join(tmpDir, "instructions");
5894
+ await fs5.mkdir(instructionsDir);
5889
5895
  const filename = getInstructionsFilename(framework);
5890
- await fs4.writeFile(path4.join(instructionsDir, filename), content);
5896
+ await fs5.writeFile(path5.join(instructionsDir, filename), content);
5891
5897
  try {
5892
5898
  const result = await directUpload(storageName, "volume", instructionsDir);
5893
5899
  return {
@@ -5896,13 +5902,13 @@ async function uploadInstructions(agentName, instructionsFilePath, basePath, fra
5896
5902
  action: result.deduplicated ? "deduplicated" : "created"
5897
5903
  };
5898
5904
  } finally {
5899
- await fs4.rm(tmpDir, { recursive: true, force: true });
5905
+ await fs5.rm(tmpDir, { recursive: true, force: true });
5900
5906
  }
5901
5907
  }
5902
5908
  async function uploadSkill(skillUrl) {
5903
5909
  const parsed = parseGitHubTreeUrl2(skillUrl);
5904
5910
  const storageName = getSkillStorageName2(parsed);
5905
- const tmpDir = await fs4.mkdtemp(path4.join(os4.tmpdir(), "vm0-skill-"));
5911
+ const tmpDir = await fs5.mkdtemp(path5.join(os4.tmpdir(), "vm0-skill-"));
5906
5912
  try {
5907
5913
  const skillDir = await downloadGitHubSkill(parsed, tmpDir);
5908
5914
  await validateSkillDirectory(skillDir);
@@ -5916,7 +5922,7 @@ async function uploadSkill(skillUrl) {
5916
5922
  frontmatter
5917
5923
  };
5918
5924
  } finally {
5919
- await fs4.rm(tmpDir, { recursive: true, force: true });
5925
+ await fs5.rm(tmpDir, { recursive: true, force: true });
5920
5926
  }
5921
5927
  }
5922
5928
 
@@ -6347,7 +6353,7 @@ async function handleGitHubCompose(url, options) {
6347
6353
  console.log(`Downloading from GitHub: ${url}`);
6348
6354
  }
6349
6355
  const { dir: downloadedDir, tempRoot } = await downloadGitHubDirectory(url);
6350
- const configFile = join7(downloadedDir, "vm0.yaml");
6356
+ const configFile = join8(downloadedDir, "vm0.yaml");
6351
6357
  try {
6352
6358
  if (!existsSync5(configFile)) {
6353
6359
  if (options.json) {
@@ -6474,7 +6480,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
6474
6480
  options.autoUpdate = false;
6475
6481
  }
6476
6482
  if (options.autoUpdate !== false) {
6477
- await startSilentUpgrade("9.38.0");
6483
+ await startSilentUpgrade("9.38.2");
6478
6484
  }
6479
6485
  try {
6480
6486
  let result;
@@ -6998,7 +7004,7 @@ var EventRenderer = class _EventRenderer {
6998
7004
 
6999
7005
  // src/commands/run/shared.ts
7000
7006
  import chalk12 from "chalk";
7001
- import * as fs5 from "fs";
7007
+ import * as fs6 from "fs";
7002
7008
  import { config as dotenvConfig } from "dotenv";
7003
7009
 
7004
7010
  // src/lib/events/claude-event-parser.ts
@@ -8250,7 +8256,7 @@ var ApiClient = class {
8250
8256
  /**
8251
8257
  * Generic GET request
8252
8258
  */
8253
- async get(path16) {
8259
+ async get(path17) {
8254
8260
  const baseUrl = await this.getBaseUrl();
8255
8261
  const token = await getToken();
8256
8262
  if (!token) {
@@ -8263,7 +8269,7 @@ var ApiClient = class {
8263
8269
  if (bypassSecret) {
8264
8270
  headers["x-vercel-protection-bypass"] = bypassSecret;
8265
8271
  }
8266
- return fetch(`${baseUrl}${path16}`, {
8272
+ return fetch(`${baseUrl}${path17}`, {
8267
8273
  method: "GET",
8268
8274
  headers
8269
8275
  });
@@ -8271,7 +8277,7 @@ var ApiClient = class {
8271
8277
  /**
8272
8278
  * Generic POST request
8273
8279
  */
8274
- async post(path16, options) {
8280
+ async post(path17, options) {
8275
8281
  const baseUrl = await this.getBaseUrl();
8276
8282
  const token = await getToken();
8277
8283
  if (!token) {
@@ -8287,7 +8293,7 @@ var ApiClient = class {
8287
8293
  if (bypassSecret) {
8288
8294
  headers["x-vercel-protection-bypass"] = bypassSecret;
8289
8295
  }
8290
- return fetch(`${baseUrl}${path16}`, {
8296
+ return fetch(`${baseUrl}${path17}`, {
8291
8297
  method: "POST",
8292
8298
  headers,
8293
8299
  body: options?.body
@@ -8296,7 +8302,7 @@ var ApiClient = class {
8296
8302
  /**
8297
8303
  * Generic DELETE request
8298
8304
  */
8299
- async delete(path16) {
8305
+ async delete(path17) {
8300
8306
  const baseUrl = await this.getBaseUrl();
8301
8307
  const token = await getToken();
8302
8308
  if (!token) {
@@ -8309,7 +8315,7 @@ var ApiClient = class {
8309
8315
  if (bypassSecret) {
8310
8316
  headers["x-vercel-protection-bypass"] = bypassSecret;
8311
8317
  }
8312
- return fetch(`${baseUrl}${path16}`, {
8318
+ return fetch(`${baseUrl}${path17}`, {
8313
8319
  method: "DELETE",
8314
8320
  headers
8315
8321
  });
@@ -8456,7 +8462,7 @@ function loadValues(cliValues, configNames, envFilePath) {
8456
8462
  }
8457
8463
  let fileValues = {};
8458
8464
  if (envFilePath) {
8459
- if (!fs5.existsSync(envFilePath)) {
8465
+ if (!fs6.existsSync(envFilePath)) {
8460
8466
  throw new Error(`Environment file not found: ${envFilePath}`);
8461
8467
  }
8462
8468
  const dotenvResult = dotenvConfig({ path: envFilePath, quiet: true });
@@ -8688,7 +8694,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
8688
8694
  async (identifier, prompt, options) => {
8689
8695
  try {
8690
8696
  if (options.autoUpdate !== false) {
8691
- await startSilentUpgrade("9.38.0");
8697
+ await startSilentUpgrade("9.38.2");
8692
8698
  }
8693
8699
  const { scope, name, version } = parseIdentifier(identifier);
8694
8700
  if (scope && !options.experimentalSharedAgent) {
@@ -9169,13 +9175,13 @@ import { Command as Command19 } from "commander";
9169
9175
  // src/commands/volume/init.ts
9170
9176
  import { Command as Command13 } from "commander";
9171
9177
  import chalk18 from "chalk";
9172
- import path6 from "path";
9178
+ import path7 from "path";
9173
9179
 
9174
9180
  // src/lib/storage/storage-utils.ts
9175
9181
  import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
9176
9182
  import { existsSync as existsSync7 } from "fs";
9177
9183
  import { parse as parseYaml3, stringify as stringifyYaml } from "yaml";
9178
- import path5 from "path";
9184
+ import path6 from "path";
9179
9185
  var CONFIG_DIR = ".vm0";
9180
9186
  var CONFIG_FILE = "storage.yaml";
9181
9187
  function isValidStorageName(name) {
@@ -9186,8 +9192,8 @@ function isValidStorageName(name) {
9186
9192
  return pattern.test(name) && !name.includes("--");
9187
9193
  }
9188
9194
  async function readStorageConfig(basePath = process.cwd()) {
9189
- const configPath = path5.join(basePath, CONFIG_DIR, CONFIG_FILE);
9190
- const legacyConfigPath = path5.join(basePath, CONFIG_DIR, "volume.yaml");
9195
+ const configPath = path6.join(basePath, CONFIG_DIR, CONFIG_FILE);
9196
+ const legacyConfigPath = path6.join(basePath, CONFIG_DIR, "volume.yaml");
9191
9197
  let actualPath = null;
9192
9198
  if (existsSync7(configPath)) {
9193
9199
  actualPath = configPath;
@@ -9205,8 +9211,8 @@ async function readStorageConfig(basePath = process.cwd()) {
9205
9211
  return config;
9206
9212
  }
9207
9213
  async function writeStorageConfig(storageName, basePath = process.cwd(), type2 = "volume") {
9208
- const configDir = path5.join(basePath, CONFIG_DIR);
9209
- const configPath = path5.join(configDir, CONFIG_FILE);
9214
+ const configDir = path6.join(basePath, CONFIG_DIR);
9215
+ const configPath = path6.join(configDir, CONFIG_FILE);
9210
9216
  if (!existsSync7(configDir)) {
9211
9217
  await mkdir4(configDir, { recursive: true });
9212
9218
  }
@@ -9222,14 +9228,14 @@ async function writeStorageConfig(storageName, basePath = process.cwd(), type2 =
9222
9228
  var initCommand = new Command13().name("init").description("Initialize a volume in the current directory").option("-n, --name <name>", "Volume name (required in non-interactive mode)").action(
9223
9229
  withErrorHandler(async (options) => {
9224
9230
  const cwd = process.cwd();
9225
- const dirName = path6.basename(cwd);
9231
+ const dirName = path7.basename(cwd);
9226
9232
  const existingConfig = await readStorageConfig(cwd);
9227
9233
  if (existingConfig) {
9228
9234
  console.log(
9229
9235
  chalk18.yellow(`Volume already initialized: ${existingConfig.name}`)
9230
9236
  );
9231
9237
  console.log(
9232
- chalk18.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
9238
+ chalk18.dim(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
9233
9239
  );
9234
9240
  return;
9235
9241
  }
@@ -9278,7 +9284,7 @@ var initCommand = new Command13().name("init").description("Initialize a volume
9278
9284
  console.log(chalk18.green(`\u2713 Initialized volume: ${volumeName}`));
9279
9285
  console.log(
9280
9286
  chalk18.dim(
9281
- ` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
9287
+ ` Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
9282
9288
  )
9283
9289
  );
9284
9290
  })
@@ -9323,8 +9329,8 @@ var pushCommand = new Command14().name("push").description("Push local files to
9323
9329
  // src/commands/volume/pull.ts
9324
9330
  import { Command as Command15 } from "commander";
9325
9331
  import chalk21 from "chalk";
9326
- import path7 from "path";
9327
- import * as fs6 from "fs";
9332
+ import path8 from "path";
9333
+ import * as fs7 from "fs";
9328
9334
  import * as os5 from "os";
9329
9335
  import * as tar3 from "tar";
9330
9336
 
@@ -9377,9 +9383,9 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
9377
9383
  const arrayBuffer = await s3Response.arrayBuffer();
9378
9384
  const tarBuffer = Buffer.from(arrayBuffer);
9379
9385
  console.log(chalk21.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
9380
- const tmpDir = fs6.mkdtempSync(path7.join(os5.tmpdir(), "vm0-"));
9381
- const tarPath = path7.join(tmpDir, "volume.tar.gz");
9382
- await fs6.promises.writeFile(tarPath, tarBuffer);
9386
+ const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-"));
9387
+ const tarPath = path8.join(tmpDir, "volume.tar.gz");
9388
+ await fs7.promises.writeFile(tarPath, tarBuffer);
9383
9389
  console.log(chalk21.dim("Syncing local files..."));
9384
9390
  const remoteFiles = await listTarFiles(tarPath);
9385
9391
  const remoteFilesSet = new Set(
@@ -9397,8 +9403,8 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
9397
9403
  cwd,
9398
9404
  gzip: true
9399
9405
  });
9400
- await fs6.promises.unlink(tarPath);
9401
- await fs6.promises.rmdir(tmpDir);
9406
+ await fs7.promises.unlink(tarPath);
9407
+ await fs7.promises.rmdir(tmpDir);
9402
9408
  console.log(chalk21.green(`\u2713 Extracted ${remoteFiles.length} files`));
9403
9409
  })
9404
9410
  );
@@ -9504,8 +9510,8 @@ import chalk25 from "chalk";
9504
9510
 
9505
9511
  // src/lib/storage/clone-utils.ts
9506
9512
  import chalk24 from "chalk";
9507
- import path8 from "path";
9508
- import * as fs7 from "fs";
9513
+ import path9 from "path";
9514
+ import * as fs8 from "fs";
9509
9515
  import * as os6 from "os";
9510
9516
  import * as tar4 from "tar";
9511
9517
  async function cloneStorage(name, type2, destination, options = {}) {
@@ -9521,7 +9527,7 @@ async function cloneStorage(name, type2, destination, options = {}) {
9521
9527
  version: options.version
9522
9528
  });
9523
9529
  console.log(chalk24.dim(`Creating directory: ${destination}/`));
9524
- await fs7.promises.mkdir(destination, { recursive: true });
9530
+ await fs8.promises.mkdir(destination, { recursive: true });
9525
9531
  if ("empty" in downloadInfo) {
9526
9532
  await writeStorageConfig(name, destination, type2);
9527
9533
  console.log(chalk24.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
@@ -9540,15 +9546,15 @@ async function cloneStorage(name, type2, destination, options = {}) {
9540
9546
  console.log(chalk24.dim("Downloading from S3..."));
9541
9547
  const s3Response = await fetch(downloadUrl);
9542
9548
  if (!s3Response.ok) {
9543
- await fs7.promises.rm(destination, { recursive: true, force: true });
9549
+ await fs8.promises.rm(destination, { recursive: true, force: true });
9544
9550
  throw new Error(`S3 download failed: ${s3Response.status}`);
9545
9551
  }
9546
9552
  const arrayBuffer = await s3Response.arrayBuffer();
9547
9553
  const tarBuffer = Buffer.from(arrayBuffer);
9548
9554
  console.log(chalk24.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
9549
- const tmpDir = fs7.mkdtempSync(path8.join(os6.tmpdir(), "vm0-clone-"));
9550
- const tarPath = path8.join(tmpDir, "archive.tar.gz");
9551
- await fs7.promises.writeFile(tarPath, tarBuffer);
9555
+ const tmpDir = fs8.mkdtempSync(path9.join(os6.tmpdir(), "vm0-clone-"));
9556
+ const tarPath = path9.join(tmpDir, "archive.tar.gz");
9557
+ await fs8.promises.writeFile(tarPath, tarBuffer);
9552
9558
  const files = await listTarFiles(tarPath);
9553
9559
  console.log(chalk24.dim("Extracting files..."));
9554
9560
  await tar4.extract({
@@ -9556,8 +9562,8 @@ async function cloneStorage(name, type2, destination, options = {}) {
9556
9562
  cwd: destination,
9557
9563
  gzip: true
9558
9564
  });
9559
- await fs7.promises.unlink(tarPath);
9560
- await fs7.promises.rmdir(tmpDir);
9565
+ await fs8.promises.unlink(tarPath);
9566
+ await fs8.promises.rmdir(tmpDir);
9561
9567
  console.log(chalk24.green(`\u2713 Extracted ${files.length} files`));
9562
9568
  await writeStorageConfig(name, destination, type2);
9563
9569
  console.log(chalk24.green(`\u2713 Initialized .vm0/storage.yaml`));
@@ -9591,14 +9597,14 @@ import { Command as Command26 } from "commander";
9591
9597
  // src/commands/artifact/init.ts
9592
9598
  import { Command as Command20 } from "commander";
9593
9599
  import chalk26 from "chalk";
9594
- import path9 from "path";
9600
+ import path10 from "path";
9595
9601
  var initCommand2 = new Command20().name("init").description("Initialize an artifact in the current directory").option(
9596
9602
  "-n, --name <name>",
9597
9603
  "Artifact name (required in non-interactive mode)"
9598
9604
  ).action(
9599
9605
  withErrorHandler(async (options) => {
9600
9606
  const cwd = process.cwd();
9601
- const dirName = path9.basename(cwd);
9607
+ const dirName = path10.basename(cwd);
9602
9608
  const existingConfig = await readStorageConfig(cwd);
9603
9609
  if (existingConfig) {
9604
9610
  if (existingConfig.type === "artifact") {
@@ -9620,7 +9626,7 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
9620
9626
  );
9621
9627
  }
9622
9628
  console.log(
9623
- chalk26.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
9629
+ chalk26.dim(`Config file: ${path10.join(cwd, ".vm0", "storage.yaml")}`)
9624
9630
  );
9625
9631
  return;
9626
9632
  }
@@ -9669,7 +9675,7 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
9669
9675
  console.log(chalk26.green(`\u2713 Initialized artifact: ${artifactName}`));
9670
9676
  console.log(
9671
9677
  chalk26.dim(
9672
- ` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
9678
+ ` Config saved to ${path10.join(cwd, ".vm0", "storage.yaml")}`
9673
9679
  )
9674
9680
  );
9675
9681
  })
@@ -9723,8 +9729,8 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
9723
9729
  // src/commands/artifact/pull.ts
9724
9730
  import { Command as Command22 } from "commander";
9725
9731
  import chalk28 from "chalk";
9726
- import path10 from "path";
9727
- import * as fs8 from "fs";
9732
+ import path11 from "path";
9733
+ import * as fs9 from "fs";
9728
9734
  import * as os7 from "os";
9729
9735
  import * as tar5 from "tar";
9730
9736
  var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact to local directory").argument("[versionId]", "Version ID to pull (default: latest)").action(
@@ -9772,9 +9778,9 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
9772
9778
  const arrayBuffer = await s3Response.arrayBuffer();
9773
9779
  const tarBuffer = Buffer.from(arrayBuffer);
9774
9780
  console.log(chalk28.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
9775
- const tmpDir = fs8.mkdtempSync(path10.join(os7.tmpdir(), "vm0-"));
9776
- const tarPath = path10.join(tmpDir, "artifact.tar.gz");
9777
- await fs8.promises.writeFile(tarPath, tarBuffer);
9781
+ const tmpDir = fs9.mkdtempSync(path11.join(os7.tmpdir(), "vm0-"));
9782
+ const tarPath = path11.join(tmpDir, "artifact.tar.gz");
9783
+ await fs9.promises.writeFile(tarPath, tarBuffer);
9778
9784
  console.log(chalk28.dim("Syncing local files..."));
9779
9785
  const remoteFiles = await listTarFiles(tarPath);
9780
9786
  const remoteFilesSet = new Set(
@@ -9792,8 +9798,8 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
9792
9798
  cwd,
9793
9799
  gzip: true
9794
9800
  });
9795
- await fs8.promises.unlink(tarPath);
9796
- await fs8.promises.rmdir(tmpDir);
9801
+ await fs9.promises.unlink(tarPath);
9802
+ await fs9.promises.rmdir(tmpDir);
9797
9803
  console.log(chalk28.green(`\u2713 Extracted ${remoteFiles.length} files`));
9798
9804
  })
9799
9805
  );
@@ -9914,16 +9920,16 @@ import { Command as Command27, Option as Option5 } from "commander";
9914
9920
  import chalk33 from "chalk";
9915
9921
  import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
9916
9922
  import { existsSync as existsSync10 } from "fs";
9917
- import path11 from "path";
9923
+ import path12 from "path";
9918
9924
  import { parse as parseYaml4 } from "yaml";
9919
9925
 
9920
9926
  // src/lib/domain/cook-state.ts
9921
9927
  import { homedir as homedir3 } from "os";
9922
- import { join as join8 } from "path";
9928
+ import { join as join9 } from "path";
9923
9929
  import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
9924
9930
  import { existsSync as existsSync8 } from "fs";
9925
- var CONFIG_DIR2 = join8(homedir3(), ".vm0");
9926
- var COOK_STATE_FILE = join8(CONFIG_DIR2, "cook.json");
9931
+ var CONFIG_DIR2 = join9(homedir3(), ".vm0");
9932
+ var COOK_STATE_FILE = join9(CONFIG_DIR2, "cook.json");
9927
9933
  var STALE_THRESHOLD_MS = 48 * 60 * 60 * 1e3;
9928
9934
  async function loadCookStateFile() {
9929
9935
  if (!existsSync8(COOK_STATE_FILE)) {
@@ -10146,7 +10152,7 @@ async function processVolumes(config, cwd) {
10146
10152
  console.log();
10147
10153
  console.log(chalk33.bold("Processing volumes:"));
10148
10154
  for (const volumeConfig of Object.values(config.volumes)) {
10149
- const volumeDir = path11.join(cwd, volumeConfig.name);
10155
+ const volumeDir = path12.join(cwd, volumeConfig.name);
10150
10156
  if (!existsSync10(volumeDir)) {
10151
10157
  console.error(chalk33.red(`\u2717 Directory not found: ${volumeConfig.name}`));
10152
10158
  console.error(chalk33.dim(" Create the directory and add files first"));
@@ -10180,7 +10186,7 @@ async function processVolumes(config, cwd) {
10180
10186
  async function processArtifact(cwd) {
10181
10187
  console.log();
10182
10188
  console.log(chalk33.bold("Processing artifact:"));
10183
- const artifactDir = path11.join(cwd, ARTIFACT_DIR);
10189
+ const artifactDir = path12.join(cwd, ARTIFACT_DIR);
10184
10190
  try {
10185
10191
  if (!existsSync10(artifactDir)) {
10186
10192
  printCommand(`mkdir ${ARTIFACT_DIR}`);
@@ -10264,7 +10270,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
10264
10270
  ).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(
10265
10271
  async (prompt, options) => {
10266
10272
  if (options.autoUpdate !== false) {
10267
- const shouldExit = await checkAndUpgrade("9.38.0", prompt);
10273
+ const shouldExit = await checkAndUpgrade("9.38.2", prompt);
10268
10274
  if (shouldExit) {
10269
10275
  process.exit(0);
10270
10276
  }
@@ -10354,7 +10360,7 @@ var logsCommand = new Command28().name("logs").description("View logs from the l
10354
10360
  // src/commands/cook/continue.ts
10355
10361
  import { Command as Command29, Option as Option6 } from "commander";
10356
10362
  import chalk35 from "chalk";
10357
- import path12 from "path";
10363
+ import path13 from "path";
10358
10364
  var continueCommand2 = new Command29().name("continue").description(
10359
10365
  "Continue from the last session (latest conversation and artifact)"
10360
10366
  ).argument("<prompt>", "Prompt for the continued agent").option(
@@ -10370,7 +10376,7 @@ var continueCommand2 = new Command29().name("continue").description(
10370
10376
  process.exit(1);
10371
10377
  }
10372
10378
  const cwd = process.cwd();
10373
- const artifactDir = path12.join(cwd, ARTIFACT_DIR);
10379
+ const artifactDir = path13.join(cwd, ARTIFACT_DIR);
10374
10380
  const envFileArg = options.envFile ? ` --env-file ${options.envFile}` : "";
10375
10381
  printCommand(
10376
10382
  `vm0 run continue${envFileArg} ${state.lastSessionId} "${prompt}"`
@@ -10419,7 +10425,7 @@ var continueCommand2 = new Command29().name("continue").description(
10419
10425
  // src/commands/cook/resume.ts
10420
10426
  import { Command as Command30, Option as Option7 } from "commander";
10421
10427
  import chalk36 from "chalk";
10422
- import path13 from "path";
10428
+ import path14 from "path";
10423
10429
  var resumeCommand2 = new Command30().name("resume").description(
10424
10430
  "Resume from the last checkpoint (snapshotted conversation and artifact)"
10425
10431
  ).argument("<prompt>", "Prompt for the resumed agent").option(
@@ -10435,7 +10441,7 @@ var resumeCommand2 = new Command30().name("resume").description(
10435
10441
  process.exit(1);
10436
10442
  }
10437
10443
  const cwd = process.cwd();
10438
- const artifactDir = path13.join(cwd, ARTIFACT_DIR);
10444
+ const artifactDir = path14.join(cwd, ARTIFACT_DIR);
10439
10445
  const envFileArg = options.envFile ? ` --env-file ${options.envFile}` : "";
10440
10446
  printCommand(
10441
10447
  `vm0 run resume${envFileArg} ${state.lastCheckpointId} "${prompt}"`
@@ -10948,7 +10954,7 @@ import { Command as Command35 } from "commander";
10948
10954
  import chalk40 from "chalk";
10949
10955
  import { mkdtempSync as mkdtempSync5 } from "fs";
10950
10956
  import { mkdir as mkdir7, writeFile as writeFile6, readdir, copyFile, rm as rm4 } from "fs/promises";
10951
- import { join as join9, dirname as dirname3 } from "path";
10957
+ import { join as join10, dirname as dirname3 } from "path";
10952
10958
  import { tmpdir as tmpdir7 } from "os";
10953
10959
  import * as tar6 from "tar";
10954
10960
  import { stringify as yamlStringify } from "yaml";
@@ -10984,8 +10990,8 @@ async function downloadInstructions(agentName, instructionsPath, destination) {
10984
10990
  throw new Error(`Failed to download instructions: ${response.status}`);
10985
10991
  }
10986
10992
  const buffer = Buffer.from(await response.arrayBuffer());
10987
- const tmpDir = mkdtempSync5(join9(tmpdir7(), "vm0-clone-"));
10988
- const tarPath = join9(tmpDir, "archive.tar.gz");
10993
+ const tmpDir = mkdtempSync5(join10(tmpdir7(), "vm0-clone-"));
10994
+ const tarPath = join10(tmpDir, "archive.tar.gz");
10989
10995
  await writeFile6(tarPath, buffer);
10990
10996
  await tar6.extract({ file: tarPath, cwd: tmpDir, gzip: true });
10991
10997
  const files = await readdir(tmpDir);
@@ -10995,9 +11001,9 @@ async function downloadInstructions(agentName, instructionsPath, destination) {
10995
11001
  await rm4(tmpDir, { recursive: true, force: true });
10996
11002
  return false;
10997
11003
  }
10998
- const destPath = join9(destination, instructionsPath);
11004
+ const destPath = join10(destination, instructionsPath);
10999
11005
  await mkdir7(dirname3(destPath), { recursive: true });
11000
- await copyFile(join9(tmpDir, mdFile), destPath);
11006
+ await copyFile(join10(tmpDir, mdFile), destPath);
11001
11007
  await rm4(tmpDir, { recursive: true, force: true });
11002
11008
  return true;
11003
11009
  }
@@ -11023,7 +11029,7 @@ var cloneCommand3 = new Command35().name("clone").description("Clone agent compo
11023
11029
  const cleanedContent = cleanComposeContent(content);
11024
11030
  const yamlContent = yamlStringify(cleanedContent);
11025
11031
  await mkdir7(targetDir, { recursive: true });
11026
- const yamlPath = join9(targetDir, "vm0.yaml");
11032
+ const yamlPath = join10(targetDir, "vm0.yaml");
11027
11033
  await writeFile6(yamlPath, yamlContent, "utf8");
11028
11034
  console.log(chalk40.green("\u2713 Created vm0.yaml"));
11029
11035
  const agentKey = Object.keys(content.agents)[0];
@@ -11149,8 +11155,8 @@ import { Command as Command38 } from "commander";
11149
11155
  import chalk43 from "chalk";
11150
11156
 
11151
11157
  // src/lib/domain/source-derivation.ts
11152
- import * as fs9 from "fs/promises";
11153
- import * as path14 from "path";
11158
+ import * as fs10 from "fs/promises";
11159
+ import * as path15 from "path";
11154
11160
  import * as os8 from "os";
11155
11161
  async function fetchSkillFrontmatter(skillUrl, tempDir) {
11156
11162
  try {
@@ -11190,8 +11196,8 @@ async function deriveAgentVariableSources(agent, options) {
11190
11196
  credentials: Array.from(credentialSources.values())
11191
11197
  };
11192
11198
  }
11193
- const tempDir = await fs9.mkdtemp(
11194
- path14.join(os8.tmpdir(), "vm0-source-derivation-")
11199
+ const tempDir = await fs10.mkdtemp(
11200
+ path15.join(os8.tmpdir(), "vm0-source-derivation-")
11195
11201
  );
11196
11202
  try {
11197
11203
  const skillResults = await Promise.all(
@@ -11224,7 +11230,7 @@ async function deriveAgentVariableSources(agent, options) {
11224
11230
  }
11225
11231
  }
11226
11232
  } finally {
11227
- await fs9.rm(tempDir, { recursive: true, force: true });
11233
+ await fs10.rm(tempDir, { recursive: true, force: true });
11228
11234
  }
11229
11235
  return {
11230
11236
  secrets: Array.from(secretSources.values()),
@@ -11701,7 +11707,7 @@ var agentCommand = new Command44().name("agent").description("Manage agent compo
11701
11707
  // src/commands/init/index.ts
11702
11708
  import { Command as Command45 } from "commander";
11703
11709
  import chalk49 from "chalk";
11704
- import path15 from "path";
11710
+ import path16 from "path";
11705
11711
  import { existsSync as existsSync11 } from "fs";
11706
11712
  import { writeFile as writeFile7 } from "fs/promises";
11707
11713
  var VM0_YAML_FILE = "vm0.yaml";
@@ -11758,7 +11764,7 @@ var initCommand3 = new Command45().name("init").description("Initialize a new VM
11758
11764
  console.error(chalk49.dim(" Usage: vm0 init --name <agent-name>"));
11759
11765
  process.exit(1);
11760
11766
  } else {
11761
- const dirName = path15.basename(process.cwd());
11767
+ const dirName = path16.basename(process.cwd());
11762
11768
  const defaultName = validateAgentName(dirName) ? dirName : void 0;
11763
11769
  const name = await promptText(
11764
11770
  "Enter agent name",
@@ -13773,9 +13779,10 @@ import { initClient as initClient13 } from "@ts-rest/core";
13773
13779
 
13774
13780
  // src/commands/connector/lib/computer/start-services.ts
13775
13781
  import { spawn as spawn3 } from "child_process";
13782
+ import { access as access2, constants } from "fs/promises";
13776
13783
  import { createServer } from "net";
13777
13784
  import { homedir as homedir4 } from "os";
13778
- import { join as join11 } from "path";
13785
+ import { join as join12 } from "path";
13779
13786
  import chalk67 from "chalk";
13780
13787
 
13781
13788
  // src/commands/connector/lib/computer/ngrok.ts
@@ -13797,6 +13804,18 @@ async function stopNgrokTunnels() {
13797
13804
  }
13798
13805
 
13799
13806
  // src/commands/connector/lib/computer/start-services.ts
13807
+ var CHROME_CANDIDATES = [
13808
+ // macOS absolute paths
13809
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
13810
+ "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
13811
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
13812
+ // Linux / PATH-based
13813
+ "google-chrome",
13814
+ "google-chrome-stable",
13815
+ "chromium-browser",
13816
+ "chromium",
13817
+ "chrome"
13818
+ ];
13800
13819
  async function getRandomPort() {
13801
13820
  return new Promise((resolve, reject) => {
13802
13821
  const server = createServer();
@@ -13807,37 +13826,51 @@ async function getRandomPort() {
13807
13826
  server.on("error", reject);
13808
13827
  });
13809
13828
  }
13810
- async function findCommand(...candidates) {
13811
- for (const binary of candidates) {
13812
- const found = await new Promise((resolve) => {
13813
- const child = spawn3("which", [binary]);
13814
- child.on("close", (code) => resolve(code === 0));
13815
- });
13816
- if (found) return binary;
13829
+ async function findBinary(...candidates) {
13830
+ for (const candidate of candidates) {
13831
+ if (candidate.startsWith("/")) {
13832
+ try {
13833
+ await access2(candidate, constants.X_OK);
13834
+ return candidate;
13835
+ } catch {
13836
+ }
13837
+ } else {
13838
+ const found = await new Promise((resolve) => {
13839
+ const child = spawn3("which", [candidate]);
13840
+ child.on("close", (code) => resolve(code === 0));
13841
+ });
13842
+ if (found) return candidate;
13843
+ }
13817
13844
  }
13818
13845
  return null;
13819
13846
  }
13847
+ async function checkComputerDependencies() {
13848
+ const wsgidavBinary = await findBinary("wsgidav");
13849
+ if (!wsgidavBinary) {
13850
+ throw new Error(
13851
+ "wsgidav not found\n\nInstall with: pip install wsgidav[cheroot]"
13852
+ );
13853
+ }
13854
+ const chromeBinary = await findBinary(...CHROME_CANDIDATES);
13855
+ if (!chromeBinary) {
13856
+ throw new Error("Chrome not found\n\nInstall Google Chrome or Chromium");
13857
+ }
13858
+ }
13820
13859
  async function startComputerServices(credentials) {
13821
13860
  console.log(chalk67.cyan("Starting computer connector services..."));
13822
- const wsgidavBinary = await findCommand("wsgidav");
13861
+ const wsgidavBinary = await findBinary("wsgidav");
13823
13862
  if (!wsgidavBinary) {
13824
13863
  throw new Error(
13825
13864
  "wsgidav not found\n\nInstall with: pip install wsgidav[cheroot]"
13826
13865
  );
13827
13866
  }
13828
- const chromeBinary = await findCommand(
13829
- "google-chrome",
13830
- "google-chrome-stable",
13831
- "chromium",
13832
- "chromium-browser",
13833
- "chrome"
13834
- );
13867
+ const chromeBinary = await findBinary(...CHROME_CANDIDATES);
13835
13868
  if (!chromeBinary) {
13836
13869
  throw new Error("Chrome not found\n\nInstall Google Chrome or Chromium");
13837
13870
  }
13838
13871
  const webdavPort = await getRandomPort();
13839
13872
  const cdpPort = await getRandomPort();
13840
- const downloadsPath = join11(homedir4(), "Downloads");
13873
+ const downloadsPath = join12(homedir4(), "Downloads");
13841
13874
  const wsgidav = spawn3(
13842
13875
  wsgidavBinary,
13843
13876
  [
@@ -13947,6 +13980,7 @@ var connectCommand = new Command67().name("connect").description("Connect a thir
13947
13980
  const apiUrl = await getApiUrl();
13948
13981
  const headers = await getHeaders2();
13949
13982
  if (connectorType === "computer") {
13983
+ await checkComputerDependencies();
13950
13984
  console.log(chalk68.cyan("Setting up computer connector..."));
13951
13985
  const computerClient = initClient13(computerConnectorContract, {
13952
13986
  baseUrl: apiUrl,
@@ -15164,7 +15198,7 @@ var preferenceCommand = new Command77().name("preference").description("View or
15164
15198
 
15165
15199
  // src/index.ts
15166
15200
  var program = new Command78();
15167
- program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.38.0");
15201
+ program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.38.2");
15168
15202
  program.addCommand(authCommand);
15169
15203
  program.addCommand(infoCommand);
15170
15204
  program.addCommand(composeCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "9.38.0",
3
+ "version": "9.38.2",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",