@vm0/cli 4.7.1 → 4.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 +421 -117
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -167,8 +167,9 @@ async function checkAuthStatus() {
167
167
  // src/commands/compose.ts
168
168
  import { Command } from "commander";
169
169
  import chalk2 from "chalk";
170
- import { readFile as readFile2 } from "fs/promises";
170
+ import { readFile as readFile3 } from "fs/promises";
171
171
  import { existsSync as existsSync2 } from "fs";
172
+ import { dirname as dirname2 } from "path";
172
173
  import { parse as parseYaml } from "yaml";
173
174
 
174
175
  // src/lib/api-client.ts
@@ -430,7 +431,7 @@ var ApiClient = class {
430
431
  /**
431
432
  * Generic GET request
432
433
  */
433
- async get(path11) {
434
+ async get(path13) {
434
435
  const baseUrl = await this.getBaseUrl();
435
436
  const token = await getToken();
436
437
  if (!token) {
@@ -443,7 +444,7 @@ var ApiClient = class {
443
444
  if (bypassSecret) {
444
445
  headers["x-vercel-protection-bypass"] = bypassSecret;
445
446
  }
446
- return fetch(`${baseUrl}${path11}`, {
447
+ return fetch(`${baseUrl}${path13}`, {
447
448
  method: "GET",
448
449
  headers
449
450
  });
@@ -451,7 +452,7 @@ var ApiClient = class {
451
452
  /**
452
453
  * Generic POST request
453
454
  */
454
- async post(path11, options) {
455
+ async post(path13, options) {
455
456
  const baseUrl = await this.getBaseUrl();
456
457
  const token = await getToken();
457
458
  if (!token) {
@@ -467,7 +468,7 @@ var ApiClient = class {
467
468
  if (bypassSecret) {
468
469
  headers["x-vercel-protection-bypass"] = bypassSecret;
469
470
  }
470
- return fetch(`${baseUrl}${path11}`, {
471
+ return fetch(`${baseUrl}${path13}`, {
471
472
  method: "POST",
472
473
  headers,
473
474
  body: options?.body
@@ -476,7 +477,7 @@ var ApiClient = class {
476
477
  /**
477
478
  * Generic DELETE request
478
479
  */
479
- async delete(path11) {
480
+ async delete(path13) {
480
481
  const baseUrl = await this.getBaseUrl();
481
482
  const token = await getToken();
482
483
  if (!token) {
@@ -489,7 +490,7 @@ var ApiClient = class {
489
490
  if (bypassSecret) {
490
491
  headers["x-vercel-protection-bypass"] = bypassSecret;
491
492
  }
492
- return fetch(`${baseUrl}${path11}`, {
493
+ return fetch(`${baseUrl}${path13}`, {
493
494
  method: "DELETE",
494
495
  headers
495
496
  });
@@ -497,11 +498,28 @@ var ApiClient = class {
497
498
  };
498
499
  var apiClient = new ApiClient();
499
500
 
501
+ // src/lib/provider-config.ts
502
+ var PROVIDER_DEFAULTS = {
503
+ "claude-code": {
504
+ workingDir: "/home/user/workspace"
505
+ }
506
+ };
507
+ function getProviderDefaults(provider) {
508
+ return PROVIDER_DEFAULTS[provider];
509
+ }
510
+ function isProviderSupported(provider) {
511
+ return provider in PROVIDER_DEFAULTS;
512
+ }
513
+
500
514
  // src/lib/yaml-validator.ts
501
515
  function validateAgentName(name) {
502
516
  const nameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{1,62}[a-zA-Z0-9])?$/;
503
517
  return nameRegex.test(name);
504
518
  }
519
+ function validateGitHubTreeUrl(url2) {
520
+ const githubTreeRegex = /^https:\/\/github\.com\/[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+\/tree\/[^/]+\/.+$/;
521
+ return githubTreeRegex.test(url2);
522
+ }
505
523
  function validateVolumeConfig(volumeKey, volumeConfig) {
506
524
  if (!volumeConfig || typeof volumeConfig !== "object") {
507
525
  return `Volume "${volumeKey}" must be an object`;
@@ -557,24 +575,67 @@ function validateAgentCompose(config2) {
557
575
  if (!agent || typeof agent !== "object") {
558
576
  return { valid: false, error: "Agent definition must be an object" };
559
577
  }
560
- if (!agent.working_dir || typeof agent.working_dir !== "string") {
578
+ if (!agent.provider || typeof agent.provider !== "string") {
561
579
  return {
562
580
  valid: false,
563
- error: "Missing or invalid agent.working_dir (must be a string)"
581
+ error: "Missing or invalid agent.provider (must be a string)"
564
582
  };
565
583
  }
584
+ const providerIsSupported = isProviderSupported(agent.provider);
566
585
  if (!agent.image || typeof agent.image !== "string") {
567
586
  return {
568
587
  valid: false,
569
588
  error: "Missing or invalid agent.image (must be a string)"
570
589
  };
571
590
  }
572
- if (!agent.provider || typeof agent.provider !== "string") {
591
+ if (agent.working_dir !== void 0 && typeof agent.working_dir !== "string") {
573
592
  return {
574
593
  valid: false,
575
- error: "Missing or invalid agent.provider (must be a string)"
594
+ error: "agent.working_dir must be a string if provided"
595
+ };
596
+ }
597
+ if (!agent.working_dir && !providerIsSupported) {
598
+ return {
599
+ valid: false,
600
+ error: "Missing agent.working_dir (required when provider is not auto-configured)"
576
601
  };
577
602
  }
603
+ if (agent.beta_system_prompt !== void 0) {
604
+ if (typeof agent.beta_system_prompt !== "string") {
605
+ return {
606
+ valid: false,
607
+ error: "agent.beta_system_prompt must be a string (path to AGENTS.md file)"
608
+ };
609
+ }
610
+ if (agent.beta_system_prompt.length === 0) {
611
+ return {
612
+ valid: false,
613
+ error: "agent.beta_system_prompt cannot be empty"
614
+ };
615
+ }
616
+ }
617
+ if (agent.beta_system_skills !== void 0) {
618
+ if (!Array.isArray(agent.beta_system_skills)) {
619
+ return {
620
+ valid: false,
621
+ error: "agent.beta_system_skills must be an array of GitHub tree URLs"
622
+ };
623
+ }
624
+ for (const skillUrl of agent.beta_system_skills) {
625
+ if (typeof skillUrl !== "string") {
626
+ return {
627
+ valid: false,
628
+ error: "Each beta_system_skill must be a string URL"
629
+ };
630
+ }
631
+ if (!validateGitHubTreeUrl(skillUrl)) {
632
+ return {
633
+ valid: false,
634
+ error: `Invalid beta_system_skill URL: ${skillUrl}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
635
+ };
636
+ }
637
+ }
638
+ }
578
639
  if (agent.environment !== void 0) {
579
640
  if (agent.environment === null || typeof agent.environment !== "object" || Array.isArray(agent.environment)) {
580
641
  return {
@@ -632,6 +693,175 @@ function validateAgentCompose(config2) {
632
693
  return { valid: true };
633
694
  }
634
695
 
696
+ // src/lib/system-storage.ts
697
+ import * as fs2 from "fs/promises";
698
+ import * as path2 from "path";
699
+ import * as os2 from "os";
700
+ import * as tar from "tar";
701
+
702
+ // src/lib/github-skills.ts
703
+ import * as fs from "fs/promises";
704
+ import * as path from "path";
705
+ import * as os from "os";
706
+ import { exec } from "child_process";
707
+ import { promisify } from "util";
708
+ var execAsync = promisify(exec);
709
+ function parseGitHubTreeUrl(url2) {
710
+ const fullPathMatch = url2.match(/^https:\/\/github\.com\/(.+)$/);
711
+ if (!fullPathMatch) {
712
+ throw new Error(
713
+ `Invalid GitHub URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
714
+ );
715
+ }
716
+ const fullPath = fullPathMatch[1];
717
+ const regex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
718
+ const match = url2.match(regex);
719
+ if (!match) {
720
+ throw new Error(
721
+ `Invalid GitHub tree URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
722
+ );
723
+ }
724
+ const [, owner, repo, branch, pathPart] = match;
725
+ const pathSegments = pathPart.split("/");
726
+ const skillName = pathSegments[pathSegments.length - 1];
727
+ return {
728
+ owner,
729
+ repo,
730
+ branch,
731
+ path: pathPart,
732
+ skillName,
733
+ fullPath
734
+ };
735
+ }
736
+ function getSkillStorageName(parsed) {
737
+ return `system-skill@${parsed.fullPath}`;
738
+ }
739
+ function getSystemPromptStorageName(composeName) {
740
+ return `system-prompt@${composeName}`;
741
+ }
742
+ async function downloadGitHubSkill(parsed, destDir) {
743
+ const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
744
+ const skillDir = path.join(destDir, parsed.skillName);
745
+ const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "vm0-skill-"));
746
+ try {
747
+ await execAsync(`git init`, { cwd: tempDir });
748
+ await execAsync(`git remote add origin "${repoUrl}"`, { cwd: tempDir });
749
+ await execAsync(`git config core.sparseCheckout true`, { cwd: tempDir });
750
+ const sparseFile = path.join(tempDir, ".git", "info", "sparse-checkout");
751
+ await fs.writeFile(sparseFile, parsed.path + "\n");
752
+ await execAsync(`git fetch --depth 1 origin "${parsed.branch}"`, {
753
+ cwd: tempDir
754
+ });
755
+ await execAsync(`git checkout "${parsed.branch}"`, { cwd: tempDir });
756
+ const fetchedPath = path.join(tempDir, parsed.path);
757
+ await fs.mkdir(path.dirname(skillDir), { recursive: true });
758
+ await fs.rename(fetchedPath, skillDir);
759
+ return skillDir;
760
+ } finally {
761
+ await fs.rm(tempDir, { recursive: true, force: true });
762
+ }
763
+ }
764
+ async function validateSkillDirectory(skillDir) {
765
+ const skillMdPath = path.join(skillDir, "SKILL.md");
766
+ try {
767
+ await fs.access(skillMdPath);
768
+ } catch {
769
+ throw new Error(
770
+ `Skill directory missing required SKILL.md file: ${skillDir}`
771
+ );
772
+ }
773
+ }
774
+
775
+ // src/lib/system-storage.ts
776
+ async function uploadSystemPrompt(agentName, promptFilePath, basePath) {
777
+ const storageName = getSystemPromptStorageName(agentName);
778
+ const absolutePath = path2.isAbsolute(promptFilePath) ? promptFilePath : path2.join(basePath, promptFilePath);
779
+ const content = await fs2.readFile(absolutePath, "utf8");
780
+ const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), "vm0-prompt-"));
781
+ const promptDir = path2.join(tmpDir, "prompt");
782
+ await fs2.mkdir(promptDir);
783
+ await fs2.writeFile(path2.join(promptDir, "CLAUDE.md"), content);
784
+ try {
785
+ const tarPath = path2.join(tmpDir, "prompt.tar.gz");
786
+ await tar.create(
787
+ {
788
+ gzip: true,
789
+ file: tarPath,
790
+ cwd: promptDir
791
+ },
792
+ ["."]
793
+ );
794
+ const tarBuffer = await fs2.readFile(tarPath);
795
+ const formData = new FormData();
796
+ formData.append("name", storageName);
797
+ formData.append("type", "volume");
798
+ formData.append(
799
+ "file",
800
+ new Blob([new Uint8Array(tarBuffer)], { type: "application/gzip" }),
801
+ "volume.tar.gz"
802
+ );
803
+ const response = await apiClient.post("/api/storages", {
804
+ body: formData
805
+ });
806
+ if (!response.ok) {
807
+ const errorBody = await response.json();
808
+ const errorMessage = typeof errorBody.error === "string" ? errorBody.error : errorBody.error?.message || "Upload failed";
809
+ throw new Error(errorMessage);
810
+ }
811
+ const result = await response.json();
812
+ return {
813
+ name: storageName,
814
+ versionId: result.versionId,
815
+ action: result.deduplicated ? "deduplicated" : "created"
816
+ };
817
+ } finally {
818
+ await fs2.rm(tmpDir, { recursive: true, force: true });
819
+ }
820
+ }
821
+ async function uploadSystemSkill(skillUrl) {
822
+ const parsed = parseGitHubTreeUrl(skillUrl);
823
+ const storageName = getSkillStorageName(parsed);
824
+ const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), "vm0-skill-"));
825
+ try {
826
+ const skillDir = await downloadGitHubSkill(parsed, tmpDir);
827
+ await validateSkillDirectory(skillDir);
828
+ const tarPath = path2.join(tmpDir, "skill.tar.gz");
829
+ await tar.create(
830
+ {
831
+ gzip: true,
832
+ file: tarPath,
833
+ cwd: skillDir
834
+ },
835
+ ["."]
836
+ );
837
+ const tarBuffer = await fs2.readFile(tarPath);
838
+ const formData = new FormData();
839
+ formData.append("name", storageName);
840
+ formData.append("type", "volume");
841
+ formData.append(
842
+ "file",
843
+ new Blob([new Uint8Array(tarBuffer)], { type: "application/gzip" }),
844
+ "volume.tar.gz"
845
+ );
846
+ const response = await apiClient.post("/api/storages", {
847
+ body: formData
848
+ });
849
+ if (!response.ok) {
850
+ const errorBody = await response.json();
851
+ const errorMessage = typeof errorBody.error === "string" ? errorBody.error : errorBody.error?.message || "Upload failed";
852
+ throw new Error(errorMessage);
853
+ }
854
+ const result = await response.json();
855
+ return {
856
+ name: storageName,
857
+ versionId: result.versionId,
858
+ action: result.deduplicated ? "deduplicated" : "created"
859
+ };
860
+ } finally {
861
+ await fs2.rm(tmpDir, { recursive: true, force: true });
862
+ }
863
+ }
864
+
635
865
  // src/commands/compose.ts
636
866
  var composeCommand = new Command().name("compose").description("Create or update agent compose").argument("<config-file>", "Path to config YAML file").action(async (configFile) => {
637
867
  try {
@@ -639,7 +869,7 @@ var composeCommand = new Command().name("compose").description("Create or update
639
869
  console.error(chalk2.red(`\u2717 Config file not found: ${configFile}`));
640
870
  process.exit(1);
641
871
  }
642
- const content = await readFile2(configFile, "utf8");
872
+ const content = await readFile3(configFile, "utf8");
643
873
  let config2;
644
874
  try {
645
875
  config2 = parseYaml(content);
@@ -655,6 +885,69 @@ var composeCommand = new Command().name("compose").description("Create or update
655
885
  console.error(chalk2.red(`\u2717 ${validation.error}`));
656
886
  process.exit(1);
657
887
  }
888
+ const cfg = config2;
889
+ const agents = cfg.agents;
890
+ const agentName = Object.keys(agents)[0];
891
+ const agent = agents[agentName];
892
+ const basePath = dirname2(configFile);
893
+ if (agent.provider) {
894
+ const defaults = getProviderDefaults(agent.provider);
895
+ if (defaults) {
896
+ if (!agent.working_dir) {
897
+ agent.working_dir = defaults.workingDir;
898
+ console.log(
899
+ chalk2.gray(
900
+ ` Auto-configured working_dir: ${defaults.workingDir}`
901
+ )
902
+ );
903
+ }
904
+ }
905
+ }
906
+ if (agent.beta_system_prompt) {
907
+ const promptPath = agent.beta_system_prompt;
908
+ console.log(chalk2.blue(`Uploading system prompt: ${promptPath}`));
909
+ try {
910
+ const result = await uploadSystemPrompt(
911
+ agentName,
912
+ promptPath,
913
+ basePath
914
+ );
915
+ console.log(
916
+ chalk2.green(
917
+ `\u2713 System prompt ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
918
+ )
919
+ );
920
+ } catch (error43) {
921
+ console.error(chalk2.red(`\u2717 Failed to upload system prompt`));
922
+ if (error43 instanceof Error) {
923
+ console.error(chalk2.gray(` ${error43.message}`));
924
+ }
925
+ process.exit(1);
926
+ }
927
+ }
928
+ if (agent.beta_system_skills && Array.isArray(agent.beta_system_skills)) {
929
+ const skillUrls = agent.beta_system_skills;
930
+ console.log(
931
+ chalk2.blue(`Uploading ${skillUrls.length} system skill(s)...`)
932
+ );
933
+ for (const skillUrl of skillUrls) {
934
+ try {
935
+ console.log(chalk2.gray(` Downloading: ${skillUrl}`));
936
+ const result = await uploadSystemSkill(skillUrl);
937
+ console.log(
938
+ chalk2.green(
939
+ ` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
940
+ )
941
+ );
942
+ } catch (error43) {
943
+ console.error(chalk2.red(`\u2717 Failed to upload skill: ${skillUrl}`));
944
+ if (error43 instanceof Error) {
945
+ console.error(chalk2.gray(` ${error43.message}`));
946
+ }
947
+ process.exit(1);
948
+ }
949
+ }
950
+ }
658
951
  console.log(chalk2.blue("Uploading compose..."));
659
952
  const response = await apiClient.createOrUpdateCompose({
660
953
  content: config2
@@ -695,8 +988,8 @@ var composeCommand = new Command().name("compose").description("Create or update
695
988
  // src/commands/run.ts
696
989
  import { Command as Command2 } from "commander";
697
990
  import chalk4 from "chalk";
698
- import * as fs from "fs";
699
- import * as path from "path";
991
+ import * as fs3 from "fs";
992
+ import * as path3 from "path";
700
993
  import { config as dotenvConfig } from "dotenv";
701
994
 
702
995
  // src/lib/event-parser.ts
@@ -1777,10 +2070,10 @@ function mergeDefs(...defs) {
1777
2070
  function cloneDef(schema) {
1778
2071
  return mergeDefs(schema._zod.def);
1779
2072
  }
1780
- function getElementAtPath(obj, path11) {
1781
- if (!path11)
2073
+ function getElementAtPath(obj, path13) {
2074
+ if (!path13)
1782
2075
  return obj;
1783
- return path11.reduce((acc, key) => acc?.[key], obj);
2076
+ return path13.reduce((acc, key) => acc?.[key], obj);
1784
2077
  }
1785
2078
  function promiseAllObject(promisesObj) {
1786
2079
  const keys = Object.keys(promisesObj);
@@ -2139,11 +2432,11 @@ function aborted(x, startIndex = 0) {
2139
2432
  }
2140
2433
  return false;
2141
2434
  }
2142
- function prefixIssues(path11, issues) {
2435
+ function prefixIssues(path13, issues) {
2143
2436
  return issues.map((iss) => {
2144
2437
  var _a;
2145
2438
  (_a = iss).path ?? (_a.path = []);
2146
- iss.path.unshift(path11);
2439
+ iss.path.unshift(path13);
2147
2440
  return iss;
2148
2441
  });
2149
2442
  }
@@ -2311,7 +2604,7 @@ function treeifyError(error43, _mapper) {
2311
2604
  return issue2.message;
2312
2605
  };
2313
2606
  const result = { errors: [] };
2314
- const processError = (error44, path11 = []) => {
2607
+ const processError = (error44, path13 = []) => {
2315
2608
  var _a, _b;
2316
2609
  for (const issue2 of error44.issues) {
2317
2610
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -2321,7 +2614,7 @@ function treeifyError(error43, _mapper) {
2321
2614
  } else if (issue2.code === "invalid_element") {
2322
2615
  processError({ issues: issue2.issues }, issue2.path);
2323
2616
  } else {
2324
- const fullpath = [...path11, ...issue2.path];
2617
+ const fullpath = [...path13, ...issue2.path];
2325
2618
  if (fullpath.length === 0) {
2326
2619
  result.errors.push(mapper(issue2));
2327
2620
  continue;
@@ -2353,8 +2646,8 @@ function treeifyError(error43, _mapper) {
2353
2646
  }
2354
2647
  function toDotPath(_path) {
2355
2648
  const segs = [];
2356
- const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2357
- for (const seg of path11) {
2649
+ const path13 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2650
+ for (const seg of path13) {
2358
2651
  if (typeof seg === "number")
2359
2652
  segs.push(`[${seg}]`);
2360
2653
  else if (typeof seg === "symbol")
@@ -13154,7 +13447,8 @@ var agentDefinitionSchema = external_exports.object({
13154
13447
  image: external_exports.string().min(1, "Image is required"),
13155
13448
  provider: external_exports.string().min(1, "Provider is required"),
13156
13449
  volumes: external_exports.array(external_exports.string()).optional(),
13157
- working_dir: external_exports.string().min(1, "Working directory is required"),
13450
+ working_dir: external_exports.string().optional(),
13451
+ // Optional when provider supports auto-config
13158
13452
  environment: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13159
13453
  /**
13160
13454
  * Enable network security mode for secrets.
@@ -13162,7 +13456,17 @@ var agentDefinitionSchema = external_exports.object({
13162
13456
  * is routed through mitmproxy -> VM0 Proxy for decryption.
13163
13457
  * Default: false (plaintext secrets in env vars)
13164
13458
  */
13165
- beta_network_security: external_exports.boolean().optional().default(false)
13459
+ beta_network_security: external_exports.boolean().optional().default(false),
13460
+ /**
13461
+ * Path to system prompt file (e.g., AGENTS.md).
13462
+ * Auto-uploaded as volume and mounted at /home/user/.config/claude/CLAUDE.md
13463
+ */
13464
+ beta_system_prompt: external_exports.string().optional(),
13465
+ /**
13466
+ * Array of GitHub tree URLs for system skills.
13467
+ * Each skill is auto-downloaded and mounted at /home/user/.config/claude/skills/{skillName}/
13468
+ */
13469
+ beta_system_skills: external_exports.array(external_exports.string()).optional()
13166
13470
  });
13167
13471
  var agentComposeContentSchema = external_exports.object({
13168
13472
  version: external_exports.string().min(1, "Version is required"),
@@ -14214,9 +14518,9 @@ function loadValues(cliValues, configNames) {
14214
14518
  const result = { ...cliValues };
14215
14519
  const missingNames = configNames.filter((name) => !(name in result));
14216
14520
  if (missingNames.length > 0) {
14217
- const envFilePath = path.resolve(process.cwd(), ".env");
14521
+ const envFilePath = path3.resolve(process.cwd(), ".env");
14218
14522
  let dotenvValues = {};
14219
- if (fs.existsSync(envFilePath)) {
14523
+ if (fs3.existsSync(envFilePath)) {
14220
14524
  const dotenvResult = dotenvConfig({ path: envFilePath });
14221
14525
  if (dotenvResult.parsed) {
14222
14526
  dotenvValues = Object.fromEntries(
@@ -14696,13 +15000,13 @@ import { Command as Command6 } from "commander";
14696
15000
  // src/commands/volume/init.ts
14697
15001
  import { Command as Command3 } from "commander";
14698
15002
  import chalk5 from "chalk";
14699
- import path3 from "path";
15003
+ import path5 from "path";
14700
15004
 
14701
15005
  // src/lib/storage-utils.ts
14702
- import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
15006
+ import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
14703
15007
  import { existsSync as existsSync4 } from "fs";
14704
15008
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
14705
- import path2 from "path";
15009
+ import path4 from "path";
14706
15010
  var CONFIG_DIR2 = ".vm0";
14707
15011
  var CONFIG_FILE2 = "storage.yaml";
14708
15012
  function isValidStorageName(name) {
@@ -14713,8 +15017,8 @@ function isValidStorageName(name) {
14713
15017
  return pattern.test(name) && !name.includes("--");
14714
15018
  }
14715
15019
  async function readStorageConfig(basePath = process.cwd()) {
14716
- const configPath = path2.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
14717
- const legacyConfigPath = path2.join(basePath, CONFIG_DIR2, "volume.yaml");
15020
+ const configPath = path4.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
15021
+ const legacyConfigPath = path4.join(basePath, CONFIG_DIR2, "volume.yaml");
14718
15022
  let actualPath = null;
14719
15023
  if (existsSync4(configPath)) {
14720
15024
  actualPath = configPath;
@@ -14724,7 +15028,7 @@ async function readStorageConfig(basePath = process.cwd()) {
14724
15028
  if (!actualPath) {
14725
15029
  return null;
14726
15030
  }
14727
- const content = await readFile3(actualPath, "utf8");
15031
+ const content = await readFile4(actualPath, "utf8");
14728
15032
  const config2 = parseYaml2(content);
14729
15033
  if (!config2.type) {
14730
15034
  config2.type = "volume";
@@ -14732,31 +15036,31 @@ async function readStorageConfig(basePath = process.cwd()) {
14732
15036
  return config2;
14733
15037
  }
14734
15038
  async function writeStorageConfig(storageName, basePath = process.cwd(), type = "volume") {
14735
- const configDir = path2.join(basePath, CONFIG_DIR2);
14736
- const configPath = path2.join(configDir, CONFIG_FILE2);
15039
+ const configDir = path4.join(basePath, CONFIG_DIR2);
15040
+ const configPath = path4.join(configDir, CONFIG_FILE2);
14737
15041
  if (!existsSync4(configDir)) {
14738
- await mkdir2(configDir, { recursive: true });
15042
+ await mkdir4(configDir, { recursive: true });
14739
15043
  }
14740
15044
  const config2 = {
14741
15045
  name: storageName,
14742
15046
  type
14743
15047
  };
14744
15048
  const yamlContent = stringifyYaml(config2);
14745
- await writeFile2(configPath, yamlContent, "utf8");
15049
+ await writeFile4(configPath, yamlContent, "utf8");
14746
15050
  }
14747
15051
 
14748
15052
  // src/commands/volume/init.ts
14749
15053
  var initCommand = new Command3().name("init").description("Initialize a volume in the current directory").action(async () => {
14750
15054
  try {
14751
15055
  const cwd = process.cwd();
14752
- const dirName = path3.basename(cwd);
15056
+ const dirName = path5.basename(cwd);
14753
15057
  const existingConfig = await readStorageConfig(cwd);
14754
15058
  if (existingConfig) {
14755
15059
  console.log(
14756
15060
  chalk5.yellow(`Volume already initialized: ${existingConfig.name}`)
14757
15061
  );
14758
15062
  console.log(
14759
- chalk5.gray(`Config file: ${path3.join(cwd, ".vm0", "storage.yaml")}`)
15063
+ chalk5.gray(`Config file: ${path5.join(cwd, ".vm0", "storage.yaml")}`)
14760
15064
  );
14761
15065
  return;
14762
15066
  }
@@ -14777,7 +15081,7 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
14777
15081
  console.log(chalk5.green(`\u2713 Initialized volume: ${volumeName}`));
14778
15082
  console.log(
14779
15083
  chalk5.gray(
14780
- `\u2713 Config saved to ${path3.join(cwd, ".vm0", "storage.yaml")}`
15084
+ `\u2713 Config saved to ${path5.join(cwd, ".vm0", "storage.yaml")}`
14781
15085
  )
14782
15086
  );
14783
15087
  } catch (error43) {
@@ -14792,15 +15096,15 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
14792
15096
  // src/commands/volume/push.ts
14793
15097
  import { Command as Command4 } from "commander";
14794
15098
  import chalk6 from "chalk";
14795
- import path5 from "path";
14796
- import * as fs3 from "fs";
14797
- import * as os from "os";
14798
- import * as tar2 from "tar";
15099
+ import path7 from "path";
15100
+ import * as fs5 from "fs";
15101
+ import * as os3 from "os";
15102
+ import * as tar3 from "tar";
14799
15103
 
14800
15104
  // src/lib/file-utils.ts
14801
- import * as fs2 from "fs";
14802
- import * as path4 from "path";
14803
- import * as tar from "tar";
15105
+ import * as fs4 from "fs";
15106
+ import * as path6 from "path";
15107
+ import * as tar2 from "tar";
14804
15108
  function excludeVm0Filter(filePath) {
14805
15109
  const shouldExclude = filePath === ".vm0" || filePath.startsWith(".vm0/") || filePath.startsWith("./.vm0");
14806
15110
  return !shouldExclude;
@@ -14808,7 +15112,7 @@ function excludeVm0Filter(filePath) {
14808
15112
  function listTarFiles(tarPath) {
14809
15113
  return new Promise((resolve2, reject) => {
14810
15114
  const files = [];
14811
- tar.list({
15115
+ tar2.list({
14812
15116
  file: tarPath,
14813
15117
  onReadEntry: (entry) => {
14814
15118
  if (entry.type === "File") {
@@ -14821,14 +15125,14 @@ function listTarFiles(tarPath) {
14821
15125
  async function listLocalFiles(dir, excludeDirs = [".vm0"]) {
14822
15126
  const files = [];
14823
15127
  async function walkDir(currentDir, relativePath = "") {
14824
- const entries = await fs2.promises.readdir(currentDir, {
15128
+ const entries = await fs4.promises.readdir(currentDir, {
14825
15129
  withFileTypes: true
14826
15130
  });
14827
15131
  for (const entry of entries) {
14828
- const entryRelativePath = relativePath ? path4.join(relativePath, entry.name) : entry.name;
15132
+ const entryRelativePath = relativePath ? path6.join(relativePath, entry.name) : entry.name;
14829
15133
  if (entry.isDirectory()) {
14830
15134
  if (!excludeDirs.includes(entry.name)) {
14831
- await walkDir(path4.join(currentDir, entry.name), entryRelativePath);
15135
+ await walkDir(path6.join(currentDir, entry.name), entryRelativePath);
14832
15136
  }
14833
15137
  } else {
14834
15138
  files.push(entryRelativePath);
@@ -14844,8 +15148,8 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
14844
15148
  for (const localFile of localFiles) {
14845
15149
  const normalizedPath = localFile.replace(/\\/g, "/");
14846
15150
  if (!remoteFiles.has(normalizedPath)) {
14847
- const fullPath = path4.join(dir, localFile);
14848
- await fs2.promises.unlink(fullPath);
15151
+ const fullPath = path6.join(dir, localFile);
15152
+ await fs4.promises.unlink(fullPath);
14849
15153
  removedCount++;
14850
15154
  }
14851
15155
  }
@@ -14853,17 +15157,17 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
14853
15157
  return removedCount;
14854
15158
  }
14855
15159
  async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
14856
- const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
15160
+ const entries = await fs4.promises.readdir(dir, { withFileTypes: true });
14857
15161
  let isEmpty = true;
14858
15162
  for (const entry of entries) {
14859
- const fullPath = path4.join(dir, entry.name);
15163
+ const fullPath = path6.join(dir, entry.name);
14860
15164
  if (entry.isDirectory()) {
14861
15165
  if (excludeDirs.includes(entry.name)) {
14862
15166
  isEmpty = false;
14863
15167
  } else {
14864
15168
  const subDirEmpty = await removeEmptyDirs(fullPath, excludeDirs);
14865
15169
  if (subDirEmpty) {
14866
- await fs2.promises.rmdir(fullPath);
15170
+ await fs4.promises.rmdir(fullPath);
14867
15171
  } else {
14868
15172
  isEmpty = false;
14869
15173
  }
@@ -14878,10 +15182,10 @@ async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
14878
15182
  // src/commands/volume/push.ts
14879
15183
  async function getAllFiles(dirPath, baseDir = dirPath) {
14880
15184
  const files = [];
14881
- const entries = await fs3.promises.readdir(dirPath, { withFileTypes: true });
15185
+ const entries = await fs5.promises.readdir(dirPath, { withFileTypes: true });
14882
15186
  for (const entry of entries) {
14883
- const fullPath = path5.join(dirPath, entry.name);
14884
- const relativePath = path5.relative(baseDir, fullPath);
15187
+ const fullPath = path7.join(dirPath, entry.name);
15188
+ const relativePath = path7.relative(baseDir, fullPath);
14885
15189
  if (relativePath.startsWith(".vm0")) {
14886
15190
  continue;
14887
15191
  }
@@ -14918,7 +15222,7 @@ var pushCommand = new Command4().name("push").description("Push local files to c
14918
15222
  const files = await getAllFiles(cwd);
14919
15223
  let totalSize = 0;
14920
15224
  for (const file2 of files) {
14921
- const stats = await fs3.promises.stat(file2);
15225
+ const stats = await fs5.promises.stat(file2);
14922
15226
  totalSize += stats.size;
14923
15227
  }
14924
15228
  if (files.length === 0) {
@@ -14929,11 +15233,11 @@ var pushCommand = new Command4().name("push").description("Push local files to c
14929
15233
  );
14930
15234
  }
14931
15235
  console.log(chalk6.gray("Compressing files..."));
14932
- const tmpDir = fs3.mkdtempSync(path5.join(os.tmpdir(), "vm0-"));
14933
- const tarPath = path5.join(tmpDir, "volume.tar.gz");
14934
- const relativePaths = files.map((file2) => path5.relative(cwd, file2));
15236
+ const tmpDir = fs5.mkdtempSync(path7.join(os3.tmpdir(), "vm0-"));
15237
+ const tarPath = path7.join(tmpDir, "volume.tar.gz");
15238
+ const relativePaths = files.map((file2) => path7.relative(cwd, file2));
14935
15239
  if (relativePaths.length > 0) {
14936
- await tar2.create(
15240
+ await tar3.create(
14937
15241
  {
14938
15242
  gzip: true,
14939
15243
  file: tarPath,
@@ -14942,7 +15246,7 @@ var pushCommand = new Command4().name("push").description("Push local files to c
14942
15246
  relativePaths
14943
15247
  );
14944
15248
  } else {
14945
- await tar2.create(
15249
+ await tar3.create(
14946
15250
  {
14947
15251
  gzip: true,
14948
15252
  file: tarPath,
@@ -14952,9 +15256,9 @@ var pushCommand = new Command4().name("push").description("Push local files to c
14952
15256
  ["."]
14953
15257
  );
14954
15258
  }
14955
- const tarBuffer = await fs3.promises.readFile(tarPath);
14956
- await fs3.promises.unlink(tarPath);
14957
- await fs3.promises.rmdir(tmpDir);
15259
+ const tarBuffer = await fs5.promises.readFile(tarPath);
15260
+ await fs5.promises.unlink(tarPath);
15261
+ await fs5.promises.rmdir(tmpDir);
14958
15262
  console.log(
14959
15263
  chalk6.green(`\u2713 Compressed to ${formatBytes(tarBuffer.length)}`)
14960
15264
  );
@@ -15000,10 +15304,10 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15000
15304
  // src/commands/volume/pull.ts
15001
15305
  import { Command as Command5 } from "commander";
15002
15306
  import chalk7 from "chalk";
15003
- import path6 from "path";
15004
- import * as fs4 from "fs";
15005
- import * as os2 from "os";
15006
- import * as tar3 from "tar";
15307
+ import path8 from "path";
15308
+ import * as fs6 from "fs";
15309
+ import * as os4 from "os";
15310
+ import * as tar4 from "tar";
15007
15311
  function formatBytes2(bytes) {
15008
15312
  if (bytes === 0) return "0 B";
15009
15313
  const k = 1024;
@@ -15053,9 +15357,9 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15053
15357
  const arrayBuffer = await response.arrayBuffer();
15054
15358
  const tarBuffer = Buffer.from(arrayBuffer);
15055
15359
  console.log(chalk7.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
15056
- const tmpDir = fs4.mkdtempSync(path6.join(os2.tmpdir(), "vm0-"));
15057
- const tarPath = path6.join(tmpDir, "volume.tar.gz");
15058
- await fs4.promises.writeFile(tarPath, tarBuffer);
15360
+ const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
15361
+ const tarPath = path8.join(tmpDir, "volume.tar.gz");
15362
+ await fs6.promises.writeFile(tarPath, tarBuffer);
15059
15363
  console.log(chalk7.gray("Syncing local files..."));
15060
15364
  const remoteFiles = await listTarFiles(tarPath);
15061
15365
  const remoteFilesSet = new Set(
@@ -15068,13 +15372,13 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15068
15372
  );
15069
15373
  }
15070
15374
  console.log(chalk7.gray("Extracting files..."));
15071
- await tar3.extract({
15375
+ await tar4.extract({
15072
15376
  file: tarPath,
15073
15377
  cwd,
15074
15378
  gzip: true
15075
15379
  });
15076
- await fs4.promises.unlink(tarPath);
15077
- await fs4.promises.rmdir(tmpDir);
15380
+ await fs6.promises.unlink(tarPath);
15381
+ await fs6.promises.rmdir(tmpDir);
15078
15382
  console.log(chalk7.green(`\u2713 Extracted ${remoteFiles.length} files`));
15079
15383
  } catch (error43) {
15080
15384
  console.error(chalk7.red("\u2717 Pull failed"));
@@ -15094,11 +15398,11 @@ import { Command as Command10 } from "commander";
15094
15398
  // src/commands/artifact/init.ts
15095
15399
  import { Command as Command7 } from "commander";
15096
15400
  import chalk8 from "chalk";
15097
- import path7 from "path";
15401
+ import path9 from "path";
15098
15402
  var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
15099
15403
  try {
15100
15404
  const cwd = process.cwd();
15101
- const dirName = path7.basename(cwd);
15405
+ const dirName = path9.basename(cwd);
15102
15406
  const existingConfig = await readStorageConfig(cwd);
15103
15407
  if (existingConfig) {
15104
15408
  if (existingConfig.type === "artifact") {
@@ -15120,7 +15424,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15120
15424
  );
15121
15425
  }
15122
15426
  console.log(
15123
- chalk8.gray(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
15427
+ chalk8.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15124
15428
  );
15125
15429
  return;
15126
15430
  }
@@ -15141,7 +15445,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15141
15445
  console.log(chalk8.green(`\u2713 Initialized artifact: ${artifactName}`));
15142
15446
  console.log(
15143
15447
  chalk8.gray(
15144
- `\u2713 Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
15448
+ `\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
15145
15449
  )
15146
15450
  );
15147
15451
  } catch (error43) {
@@ -15156,16 +15460,16 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15156
15460
  // src/commands/artifact/push.ts
15157
15461
  import { Command as Command8 } from "commander";
15158
15462
  import chalk9 from "chalk";
15159
- import path8 from "path";
15160
- import * as fs5 from "fs";
15161
- import * as os3 from "os";
15162
- import * as tar4 from "tar";
15463
+ import path10 from "path";
15464
+ import * as fs7 from "fs";
15465
+ import * as os5 from "os";
15466
+ import * as tar5 from "tar";
15163
15467
  async function getAllFiles2(dirPath, baseDir = dirPath) {
15164
15468
  const files = [];
15165
- const entries = await fs5.promises.readdir(dirPath, { withFileTypes: true });
15469
+ const entries = await fs7.promises.readdir(dirPath, { withFileTypes: true });
15166
15470
  for (const entry of entries) {
15167
- const fullPath = path8.join(dirPath, entry.name);
15168
- const relativePath = path8.relative(baseDir, fullPath);
15471
+ const fullPath = path10.join(dirPath, entry.name);
15472
+ const relativePath = path10.relative(baseDir, fullPath);
15169
15473
  if (relativePath.startsWith(".vm0")) {
15170
15474
  continue;
15171
15475
  }
@@ -15211,7 +15515,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15211
15515
  const files = await getAllFiles2(cwd);
15212
15516
  let totalSize = 0;
15213
15517
  for (const file2 of files) {
15214
- const stats = await fs5.promises.stat(file2);
15518
+ const stats = await fs7.promises.stat(file2);
15215
15519
  totalSize += stats.size;
15216
15520
  }
15217
15521
  if (files.length === 0) {
@@ -15222,11 +15526,11 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15222
15526
  );
15223
15527
  }
15224
15528
  console.log(chalk9.gray("Compressing files..."));
15225
- const tmpDir = fs5.mkdtempSync(path8.join(os3.tmpdir(), "vm0-"));
15226
- const tarPath = path8.join(tmpDir, "artifact.tar.gz");
15227
- const relativePaths = files.map((file2) => path8.relative(cwd, file2));
15529
+ const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
15530
+ const tarPath = path10.join(tmpDir, "artifact.tar.gz");
15531
+ const relativePaths = files.map((file2) => path10.relative(cwd, file2));
15228
15532
  if (relativePaths.length > 0) {
15229
- await tar4.create(
15533
+ await tar5.create(
15230
15534
  {
15231
15535
  gzip: true,
15232
15536
  file: tarPath,
@@ -15235,7 +15539,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15235
15539
  relativePaths
15236
15540
  );
15237
15541
  } else {
15238
- await tar4.create(
15542
+ await tar5.create(
15239
15543
  {
15240
15544
  gzip: true,
15241
15545
  file: tarPath,
@@ -15245,9 +15549,9 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15245
15549
  ["."]
15246
15550
  );
15247
15551
  }
15248
- const tarBuffer = await fs5.promises.readFile(tarPath);
15249
- await fs5.promises.unlink(tarPath);
15250
- await fs5.promises.rmdir(tmpDir);
15552
+ const tarBuffer = await fs7.promises.readFile(tarPath);
15553
+ await fs7.promises.unlink(tarPath);
15554
+ await fs7.promises.rmdir(tmpDir);
15251
15555
  console.log(
15252
15556
  chalk9.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
15253
15557
  );
@@ -15292,10 +15596,10 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15292
15596
  // src/commands/artifact/pull.ts
15293
15597
  import { Command as Command9 } from "commander";
15294
15598
  import chalk10 from "chalk";
15295
- import path9 from "path";
15296
- import * as fs6 from "fs";
15297
- import * as os4 from "os";
15298
- import * as tar5 from "tar";
15599
+ import path11 from "path";
15600
+ import * as fs8 from "fs";
15601
+ import * as os6 from "os";
15602
+ import * as tar6 from "tar";
15299
15603
  function formatBytes4(bytes) {
15300
15604
  if (bytes === 0) return "0 B";
15301
15605
  const k = 1024;
@@ -15356,9 +15660,9 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15356
15660
  const arrayBuffer = await response.arrayBuffer();
15357
15661
  const tarBuffer = Buffer.from(arrayBuffer);
15358
15662
  console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
15359
- const tmpDir = fs6.mkdtempSync(path9.join(os4.tmpdir(), "vm0-"));
15360
- const tarPath = path9.join(tmpDir, "artifact.tar.gz");
15361
- await fs6.promises.writeFile(tarPath, tarBuffer);
15663
+ const tmpDir = fs8.mkdtempSync(path11.join(os6.tmpdir(), "vm0-"));
15664
+ const tarPath = path11.join(tmpDir, "artifact.tar.gz");
15665
+ await fs8.promises.writeFile(tarPath, tarBuffer);
15362
15666
  console.log(chalk10.gray("Syncing local files..."));
15363
15667
  const remoteFiles = await listTarFiles(tarPath);
15364
15668
  const remoteFilesSet = new Set(
@@ -15371,13 +15675,13 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15371
15675
  );
15372
15676
  }
15373
15677
  console.log(chalk10.gray("Extracting files..."));
15374
- await tar5.extract({
15678
+ await tar6.extract({
15375
15679
  file: tarPath,
15376
15680
  cwd,
15377
15681
  gzip: true
15378
15682
  });
15379
- await fs6.promises.unlink(tarPath);
15380
- await fs6.promises.rmdir(tmpDir);
15683
+ await fs8.promises.unlink(tarPath);
15684
+ await fs8.promises.rmdir(tmpDir);
15381
15685
  console.log(chalk10.green(`\u2713 Extracted ${remoteFiles.length} files`));
15382
15686
  } catch (error43) {
15383
15687
  console.error(chalk10.red("\u2717 Pull failed"));
@@ -15394,9 +15698,9 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
15394
15698
  // src/commands/cook.ts
15395
15699
  import { Command as Command11 } from "commander";
15396
15700
  import chalk11 from "chalk";
15397
- import { readFile as readFile4, mkdir as mkdir3 } from "fs/promises";
15701
+ import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
15398
15702
  import { existsSync as existsSync5 } from "fs";
15399
- import path10 from "path";
15703
+ import path12 from "path";
15400
15704
  import { spawn } from "child_process";
15401
15705
  import { parse as parseYaml3 } from "yaml";
15402
15706
  var CONFIG_FILE3 = "vm0.yaml";
@@ -15485,7 +15789,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15485
15789
  }
15486
15790
  let config2;
15487
15791
  try {
15488
- const content = await readFile4(CONFIG_FILE3, "utf8");
15792
+ const content = await readFile5(CONFIG_FILE3, "utf8");
15489
15793
  config2 = parseYaml3(content);
15490
15794
  } catch (error43) {
15491
15795
  console.error(chalk11.red("\u2717 Invalid YAML format"));
@@ -15509,7 +15813,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15509
15813
  console.log();
15510
15814
  console.log(chalk11.blue("Processing volumes..."));
15511
15815
  for (const volumeConfig of Object.values(config2.volumes)) {
15512
- const volumeDir = path10.join(cwd, volumeConfig.name);
15816
+ const volumeDir = path12.join(cwd, volumeConfig.name);
15513
15817
  console.log(chalk11.gray(` ${volumeConfig.name}/`));
15514
15818
  if (!existsSync5(volumeDir)) {
15515
15819
  console.error(
@@ -15544,11 +15848,11 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15544
15848
  }
15545
15849
  console.log();
15546
15850
  console.log(chalk11.blue("Processing artifact..."));
15547
- const artifactDir = path10.join(cwd, ARTIFACT_DIR);
15851
+ const artifactDir = path12.join(cwd, ARTIFACT_DIR);
15548
15852
  console.log(chalk11.gray(` ${ARTIFACT_DIR}/`));
15549
15853
  try {
15550
15854
  if (!existsSync5(artifactDir)) {
15551
- await mkdir3(artifactDir, { recursive: true });
15855
+ await mkdir5(artifactDir, { recursive: true });
15552
15856
  console.log(chalk11.green(` \u2713 Created directory`));
15553
15857
  }
15554
15858
  const existingConfig = await readStorageConfig(artifactDir);
@@ -15640,7 +15944,7 @@ import { Command as Command15 } from "commander";
15640
15944
  // src/commands/image/build.ts
15641
15945
  import { Command as Command12 } from "commander";
15642
15946
  import chalk12 from "chalk";
15643
- import { readFile as readFile5 } from "fs/promises";
15947
+ import { readFile as readFile6 } from "fs/promises";
15644
15948
  import { existsSync as existsSync6 } from "fs";
15645
15949
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
15646
15950
  var buildCommand = new Command12().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").option("--delete-existing", "Delete existing image before building").action(
@@ -15668,7 +15972,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15668
15972
  process.exit(1);
15669
15973
  }
15670
15974
  try {
15671
- const dockerfile = await readFile5(file2, "utf8");
15975
+ const dockerfile = await readFile6(file2, "utf8");
15672
15976
  console.log(chalk12.blue(`Building image: ${name}`));
15673
15977
  console.log(chalk12.gray(` Dockerfile: ${file2}`));
15674
15978
  console.log();
@@ -16092,7 +16396,7 @@ function handleError(error43, runId) {
16092
16396
 
16093
16397
  // src/index.ts
16094
16398
  var program = new Command17();
16095
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.7.1");
16399
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.8.0");
16096
16400
  program.command("info").description("Display environment information").action(async () => {
16097
16401
  console.log(chalk16.cyan("System Information:"));
16098
16402
  console.log(`Node Version: ${process.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.7.1",
3
+ "version": "4.8.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",