@vm0/cli 4.7.0 → 4.7.1

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 +120 -432
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -167,9 +167,8 @@ 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 readFile3 } from "fs/promises";
170
+ import { readFile as readFile2 } from "fs/promises";
171
171
  import { existsSync as existsSync2 } from "fs";
172
- import { dirname as dirname2 } from "path";
173
172
  import { parse as parseYaml } from "yaml";
174
173
 
175
174
  // src/lib/api-client.ts
@@ -431,7 +430,7 @@ var ApiClient = class {
431
430
  /**
432
431
  * Generic GET request
433
432
  */
434
- async get(path13) {
433
+ async get(path11) {
435
434
  const baseUrl = await this.getBaseUrl();
436
435
  const token = await getToken();
437
436
  if (!token) {
@@ -444,7 +443,7 @@ var ApiClient = class {
444
443
  if (bypassSecret) {
445
444
  headers["x-vercel-protection-bypass"] = bypassSecret;
446
445
  }
447
- return fetch(`${baseUrl}${path13}`, {
446
+ return fetch(`${baseUrl}${path11}`, {
448
447
  method: "GET",
449
448
  headers
450
449
  });
@@ -452,7 +451,7 @@ var ApiClient = class {
452
451
  /**
453
452
  * Generic POST request
454
453
  */
455
- async post(path13, options) {
454
+ async post(path11, options) {
456
455
  const baseUrl = await this.getBaseUrl();
457
456
  const token = await getToken();
458
457
  if (!token) {
@@ -468,7 +467,7 @@ var ApiClient = class {
468
467
  if (bypassSecret) {
469
468
  headers["x-vercel-protection-bypass"] = bypassSecret;
470
469
  }
471
- return fetch(`${baseUrl}${path13}`, {
470
+ return fetch(`${baseUrl}${path11}`, {
472
471
  method: "POST",
473
472
  headers,
474
473
  body: options?.body
@@ -477,7 +476,7 @@ var ApiClient = class {
477
476
  /**
478
477
  * Generic DELETE request
479
478
  */
480
- async delete(path13) {
479
+ async delete(path11) {
481
480
  const baseUrl = await this.getBaseUrl();
482
481
  const token = await getToken();
483
482
  if (!token) {
@@ -490,7 +489,7 @@ var ApiClient = class {
490
489
  if (bypassSecret) {
491
490
  headers["x-vercel-protection-bypass"] = bypassSecret;
492
491
  }
493
- return fetch(`${baseUrl}${path13}`, {
492
+ return fetch(`${baseUrl}${path11}`, {
494
493
  method: "DELETE",
495
494
  headers
496
495
  });
@@ -498,29 +497,11 @@ var ApiClient = class {
498
497
  };
499
498
  var apiClient = new ApiClient();
500
499
 
501
- // src/lib/provider-config.ts
502
- var PROVIDER_DEFAULTS = {
503
- "claude-code": {
504
- image: "vm0-claude-code-dev",
505
- workingDir: "/home/user/workspace"
506
- }
507
- };
508
- function getProviderDefaults(provider) {
509
- return PROVIDER_DEFAULTS[provider];
510
- }
511
- function isProviderSupported(provider) {
512
- return provider in PROVIDER_DEFAULTS;
513
- }
514
-
515
500
  // src/lib/yaml-validator.ts
516
501
  function validateAgentName(name) {
517
502
  const nameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{1,62}[a-zA-Z0-9])?$/;
518
503
  return nameRegex.test(name);
519
504
  }
520
- function validateGitHubTreeUrl(url2) {
521
- const githubTreeRegex = /^https:\/\/github\.com\/[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+\/tree\/[^/]+\/.+$/;
522
- return githubTreeRegex.test(url2);
523
- }
524
505
  function validateVolumeConfig(volumeKey, volumeConfig) {
525
506
  if (!volumeConfig || typeof volumeConfig !== "object") {
526
507
  return `Volume "${volumeKey}" must be an object`;
@@ -576,73 +557,24 @@ function validateAgentCompose(config2) {
576
557
  if (!agent || typeof agent !== "object") {
577
558
  return { valid: false, error: "Agent definition must be an object" };
578
559
  }
579
- if (!agent.provider || typeof agent.provider !== "string") {
560
+ if (!agent.working_dir || typeof agent.working_dir !== "string") {
580
561
  return {
581
562
  valid: false,
582
- error: "Missing or invalid agent.provider (must be a string)"
583
- };
584
- }
585
- const providerIsSupported = isProviderSupported(agent.provider);
586
- if (agent.image !== void 0 && typeof agent.image !== "string") {
587
- return {
588
- valid: false,
589
- error: "agent.image must be a string if provided"
563
+ error: "Missing or invalid agent.working_dir (must be a string)"
590
564
  };
591
565
  }
592
- if (!agent.image && !providerIsSupported) {
566
+ if (!agent.image || typeof agent.image !== "string") {
593
567
  return {
594
568
  valid: false,
595
- error: "Missing agent.image (required when provider is not auto-configured)"
569
+ error: "Missing or invalid agent.image (must be a string)"
596
570
  };
597
571
  }
598
- if (agent.working_dir !== void 0 && typeof agent.working_dir !== "string") {
599
- return {
600
- valid: false,
601
- error: "agent.working_dir must be a string if provided"
602
- };
603
- }
604
- if (!agent.working_dir && !providerIsSupported) {
572
+ if (!agent.provider || typeof agent.provider !== "string") {
605
573
  return {
606
574
  valid: false,
607
- error: "Missing agent.working_dir (required when provider is not auto-configured)"
575
+ error: "Missing or invalid agent.provider (must be a string)"
608
576
  };
609
577
  }
610
- if (agent.system_prompt !== void 0) {
611
- if (typeof agent.system_prompt !== "string") {
612
- return {
613
- valid: false,
614
- error: "agent.system_prompt must be a string (path to AGENTS.md file)"
615
- };
616
- }
617
- if (agent.system_prompt.length === 0) {
618
- return {
619
- valid: false,
620
- error: "agent.system_prompt cannot be empty"
621
- };
622
- }
623
- }
624
- if (agent.system_skills !== void 0) {
625
- if (!Array.isArray(agent.system_skills)) {
626
- return {
627
- valid: false,
628
- error: "agent.system_skills must be an array of GitHub tree URLs"
629
- };
630
- }
631
- for (const skillUrl of agent.system_skills) {
632
- if (typeof skillUrl !== "string") {
633
- return {
634
- valid: false,
635
- error: "Each system_skill must be a string URL"
636
- };
637
- }
638
- if (!validateGitHubTreeUrl(skillUrl)) {
639
- return {
640
- valid: false,
641
- error: `Invalid system_skill URL: ${skillUrl}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
642
- };
643
- }
644
- }
645
- }
646
578
  if (agent.environment !== void 0) {
647
579
  if (agent.environment === null || typeof agent.environment !== "object" || Array.isArray(agent.environment)) {
648
580
  return {
@@ -700,175 +632,6 @@ function validateAgentCompose(config2) {
700
632
  return { valid: true };
701
633
  }
702
634
 
703
- // src/lib/system-storage.ts
704
- import * as fs2 from "fs/promises";
705
- import * as path2 from "path";
706
- import * as os2 from "os";
707
- import * as tar from "tar";
708
-
709
- // src/lib/github-skills.ts
710
- import * as fs from "fs/promises";
711
- import * as path from "path";
712
- import * as os from "os";
713
- import { exec } from "child_process";
714
- import { promisify } from "util";
715
- var execAsync = promisify(exec);
716
- function parseGitHubTreeUrl(url2) {
717
- const fullPathMatch = url2.match(/^https:\/\/github\.com\/(.+)$/);
718
- if (!fullPathMatch) {
719
- throw new Error(
720
- `Invalid GitHub URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
721
- );
722
- }
723
- const fullPath = fullPathMatch[1];
724
- const regex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/tree\/([^/]+)\/(.+)$/;
725
- const match = url2.match(regex);
726
- if (!match) {
727
- throw new Error(
728
- `Invalid GitHub tree URL: ${url2}. Expected format: https://github.com/{owner}/{repo}/tree/{branch}/{path}`
729
- );
730
- }
731
- const [, owner, repo, branch, pathPart] = match;
732
- const pathSegments = pathPart.split("/");
733
- const skillName = pathSegments[pathSegments.length - 1];
734
- return {
735
- owner,
736
- repo,
737
- branch,
738
- path: pathPart,
739
- skillName,
740
- fullPath
741
- };
742
- }
743
- function getSkillStorageName(parsed) {
744
- return `system-skill@${parsed.fullPath}`;
745
- }
746
- function getSystemPromptStorageName(composeName) {
747
- return `system-prompt@${composeName}`;
748
- }
749
- async function downloadGitHubSkill(parsed, destDir) {
750
- const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
751
- const skillDir = path.join(destDir, parsed.skillName);
752
- const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "vm0-skill-"));
753
- try {
754
- await execAsync(`git init`, { cwd: tempDir });
755
- await execAsync(`git remote add origin "${repoUrl}"`, { cwd: tempDir });
756
- await execAsync(`git config core.sparseCheckout true`, { cwd: tempDir });
757
- const sparseFile = path.join(tempDir, ".git", "info", "sparse-checkout");
758
- await fs.writeFile(sparseFile, parsed.path + "\n");
759
- await execAsync(`git fetch --depth 1 origin "${parsed.branch}"`, {
760
- cwd: tempDir
761
- });
762
- await execAsync(`git checkout "${parsed.branch}"`, { cwd: tempDir });
763
- const fetchedPath = path.join(tempDir, parsed.path);
764
- await fs.mkdir(path.dirname(skillDir), { recursive: true });
765
- await fs.rename(fetchedPath, skillDir);
766
- return skillDir;
767
- } finally {
768
- await fs.rm(tempDir, { recursive: true, force: true });
769
- }
770
- }
771
- async function validateSkillDirectory(skillDir) {
772
- const skillMdPath = path.join(skillDir, "SKILL.md");
773
- try {
774
- await fs.access(skillMdPath);
775
- } catch {
776
- throw new Error(
777
- `Skill directory missing required SKILL.md file: ${skillDir}`
778
- );
779
- }
780
- }
781
-
782
- // src/lib/system-storage.ts
783
- async function uploadSystemPrompt(agentName, promptFilePath, basePath) {
784
- const storageName = getSystemPromptStorageName(agentName);
785
- const absolutePath = path2.isAbsolute(promptFilePath) ? promptFilePath : path2.join(basePath, promptFilePath);
786
- const content = await fs2.readFile(absolutePath, "utf8");
787
- const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), "vm0-prompt-"));
788
- const promptDir = path2.join(tmpDir, "prompt");
789
- await fs2.mkdir(promptDir);
790
- await fs2.writeFile(path2.join(promptDir, "CLAUDE.md"), content);
791
- try {
792
- const tarPath = path2.join(tmpDir, "prompt.tar.gz");
793
- await tar.create(
794
- {
795
- gzip: true,
796
- file: tarPath,
797
- cwd: promptDir
798
- },
799
- ["."]
800
- );
801
- const tarBuffer = await fs2.readFile(tarPath);
802
- const formData = new FormData();
803
- formData.append("name", storageName);
804
- formData.append("type", "volume");
805
- formData.append(
806
- "file",
807
- new Blob([tarBuffer], { type: "application/gzip" }),
808
- "volume.tar.gz"
809
- );
810
- const response = await apiClient.post("/api/storages", {
811
- body: formData
812
- });
813
- if (!response.ok) {
814
- const errorBody = await response.json();
815
- const errorMessage = typeof errorBody.error === "string" ? errorBody.error : errorBody.error?.message || "Upload failed";
816
- throw new Error(errorMessage);
817
- }
818
- const result = await response.json();
819
- return {
820
- name: storageName,
821
- versionId: result.versionId,
822
- action: result.deduplicated ? "deduplicated" : "created"
823
- };
824
- } finally {
825
- await fs2.rm(tmpDir, { recursive: true, force: true });
826
- }
827
- }
828
- async function uploadSystemSkill(skillUrl) {
829
- const parsed = parseGitHubTreeUrl(skillUrl);
830
- const storageName = getSkillStorageName(parsed);
831
- const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), "vm0-skill-"));
832
- try {
833
- const skillDir = await downloadGitHubSkill(parsed, tmpDir);
834
- await validateSkillDirectory(skillDir);
835
- const tarPath = path2.join(tmpDir, "skill.tar.gz");
836
- await tar.create(
837
- {
838
- gzip: true,
839
- file: tarPath,
840
- cwd: skillDir
841
- },
842
- ["."]
843
- );
844
- const tarBuffer = await fs2.readFile(tarPath);
845
- const formData = new FormData();
846
- formData.append("name", storageName);
847
- formData.append("type", "volume");
848
- formData.append(
849
- "file",
850
- new Blob([tarBuffer], { type: "application/gzip" }),
851
- "volume.tar.gz"
852
- );
853
- const response = await apiClient.post("/api/storages", {
854
- body: formData
855
- });
856
- if (!response.ok) {
857
- const errorBody = await response.json();
858
- const errorMessage = typeof errorBody.error === "string" ? errorBody.error : errorBody.error?.message || "Upload failed";
859
- throw new Error(errorMessage);
860
- }
861
- const result = await response.json();
862
- return {
863
- name: storageName,
864
- versionId: result.versionId,
865
- action: result.deduplicated ? "deduplicated" : "created"
866
- };
867
- } finally {
868
- await fs2.rm(tmpDir, { recursive: true, force: true });
869
- }
870
- }
871
-
872
635
  // src/commands/compose.ts
873
636
  var composeCommand = new Command().name("compose").description("Create or update agent compose").argument("<config-file>", "Path to config YAML file").action(async (configFile) => {
874
637
  try {
@@ -876,7 +639,7 @@ var composeCommand = new Command().name("compose").description("Create or update
876
639
  console.error(chalk2.red(`\u2717 Config file not found: ${configFile}`));
877
640
  process.exit(1);
878
641
  }
879
- const content = await readFile3(configFile, "utf8");
642
+ const content = await readFile2(configFile, "utf8");
880
643
  let config2;
881
644
  try {
882
645
  config2 = parseYaml(content);
@@ -892,75 +655,6 @@ var composeCommand = new Command().name("compose").description("Create or update
892
655
  console.error(chalk2.red(`\u2717 ${validation.error}`));
893
656
  process.exit(1);
894
657
  }
895
- const cfg = config2;
896
- const agents = cfg.agents;
897
- const agentName = Object.keys(agents)[0];
898
- const agent = agents[agentName];
899
- const basePath = dirname2(configFile);
900
- if (agent.provider) {
901
- const defaults = getProviderDefaults(agent.provider);
902
- if (defaults) {
903
- if (!agent.image) {
904
- agent.image = defaults.image;
905
- console.log(
906
- chalk2.gray(` Auto-configured image: ${defaults.image}`)
907
- );
908
- }
909
- if (!agent.working_dir) {
910
- agent.working_dir = defaults.workingDir;
911
- console.log(
912
- chalk2.gray(
913
- ` Auto-configured working_dir: ${defaults.workingDir}`
914
- )
915
- );
916
- }
917
- }
918
- }
919
- if (agent.system_prompt) {
920
- const promptPath = agent.system_prompt;
921
- console.log(chalk2.blue(`Uploading system prompt: ${promptPath}`));
922
- try {
923
- const result = await uploadSystemPrompt(
924
- agentName,
925
- promptPath,
926
- basePath
927
- );
928
- console.log(
929
- chalk2.green(
930
- `\u2713 System prompt ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
931
- )
932
- );
933
- } catch (error43) {
934
- console.error(chalk2.red(`\u2717 Failed to upload system prompt`));
935
- if (error43 instanceof Error) {
936
- console.error(chalk2.gray(` ${error43.message}`));
937
- }
938
- process.exit(1);
939
- }
940
- }
941
- if (agent.system_skills && Array.isArray(agent.system_skills)) {
942
- const skillUrls = agent.system_skills;
943
- console.log(
944
- chalk2.blue(`Uploading ${skillUrls.length} system skill(s)...`)
945
- );
946
- for (const skillUrl of skillUrls) {
947
- try {
948
- console.log(chalk2.gray(` Downloading: ${skillUrl}`));
949
- const result = await uploadSystemSkill(skillUrl);
950
- console.log(
951
- chalk2.green(
952
- ` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
953
- )
954
- );
955
- } catch (error43) {
956
- console.error(chalk2.red(`\u2717 Failed to upload skill: ${skillUrl}`));
957
- if (error43 instanceof Error) {
958
- console.error(chalk2.gray(` ${error43.message}`));
959
- }
960
- process.exit(1);
961
- }
962
- }
963
- }
964
658
  console.log(chalk2.blue("Uploading compose..."));
965
659
  const response = await apiClient.createOrUpdateCompose({
966
660
  content: config2
@@ -1001,8 +695,8 @@ var composeCommand = new Command().name("compose").description("Create or update
1001
695
  // src/commands/run.ts
1002
696
  import { Command as Command2 } from "commander";
1003
697
  import chalk4 from "chalk";
1004
- import * as fs3 from "fs";
1005
- import * as path3 from "path";
698
+ import * as fs from "fs";
699
+ import * as path from "path";
1006
700
  import { config as dotenvConfig } from "dotenv";
1007
701
 
1008
702
  // src/lib/event-parser.ts
@@ -2083,10 +1777,10 @@ function mergeDefs(...defs) {
2083
1777
  function cloneDef(schema) {
2084
1778
  return mergeDefs(schema._zod.def);
2085
1779
  }
2086
- function getElementAtPath(obj, path13) {
2087
- if (!path13)
1780
+ function getElementAtPath(obj, path11) {
1781
+ if (!path11)
2088
1782
  return obj;
2089
- return path13.reduce((acc, key) => acc?.[key], obj);
1783
+ return path11.reduce((acc, key) => acc?.[key], obj);
2090
1784
  }
2091
1785
  function promiseAllObject(promisesObj) {
2092
1786
  const keys = Object.keys(promisesObj);
@@ -2445,11 +2139,11 @@ function aborted(x, startIndex = 0) {
2445
2139
  }
2446
2140
  return false;
2447
2141
  }
2448
- function prefixIssues(path13, issues) {
2142
+ function prefixIssues(path11, issues) {
2449
2143
  return issues.map((iss) => {
2450
2144
  var _a;
2451
2145
  (_a = iss).path ?? (_a.path = []);
2452
- iss.path.unshift(path13);
2146
+ iss.path.unshift(path11);
2453
2147
  return iss;
2454
2148
  });
2455
2149
  }
@@ -2617,7 +2311,7 @@ function treeifyError(error43, _mapper) {
2617
2311
  return issue2.message;
2618
2312
  };
2619
2313
  const result = { errors: [] };
2620
- const processError = (error44, path13 = []) => {
2314
+ const processError = (error44, path11 = []) => {
2621
2315
  var _a, _b;
2622
2316
  for (const issue2 of error44.issues) {
2623
2317
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -2627,7 +2321,7 @@ function treeifyError(error43, _mapper) {
2627
2321
  } else if (issue2.code === "invalid_element") {
2628
2322
  processError({ issues: issue2.issues }, issue2.path);
2629
2323
  } else {
2630
- const fullpath = [...path13, ...issue2.path];
2324
+ const fullpath = [...path11, ...issue2.path];
2631
2325
  if (fullpath.length === 0) {
2632
2326
  result.errors.push(mapper(issue2));
2633
2327
  continue;
@@ -2659,8 +2353,8 @@ function treeifyError(error43, _mapper) {
2659
2353
  }
2660
2354
  function toDotPath(_path) {
2661
2355
  const segs = [];
2662
- const path13 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2663
- for (const seg of path13) {
2356
+ const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2357
+ for (const seg of path11) {
2664
2358
  if (typeof seg === "number")
2665
2359
  segs.push(`[${seg}]`);
2666
2360
  else if (typeof seg === "symbol")
@@ -13457,12 +13151,10 @@ var volumeConfigSchema = external_exports.object({
13457
13151
  });
13458
13152
  var agentDefinitionSchema = external_exports.object({
13459
13153
  description: external_exports.string().optional(),
13460
- image: external_exports.string().optional(),
13461
- // Optional when provider is specified (auto-resolved)
13154
+ image: external_exports.string().min(1, "Image is required"),
13462
13155
  provider: external_exports.string().min(1, "Provider is required"),
13463
13156
  volumes: external_exports.array(external_exports.string()).optional(),
13464
- working_dir: external_exports.string().optional(),
13465
- // Optional when provider is specified (defaults to /home/user/workspace)
13157
+ working_dir: external_exports.string().min(1, "Working directory is required"),
13466
13158
  environment: external_exports.record(external_exports.string(), external_exports.string()).optional(),
13467
13159
  /**
13468
13160
  * Enable network security mode for secrets.
@@ -13470,11 +13162,7 @@ var agentDefinitionSchema = external_exports.object({
13470
13162
  * is routed through mitmproxy -> VM0 Proxy for decryption.
13471
13163
  * Default: false (plaintext secrets in env vars)
13472
13164
  */
13473
- beta_network_security: external_exports.boolean().optional().default(false),
13474
- system_prompt: external_exports.string().optional(),
13475
- // Path to AGENTS.md file
13476
- system_skills: external_exports.array(external_exports.string()).optional()
13477
- // GitHub tree URLs for skills
13165
+ beta_network_security: external_exports.boolean().optional().default(false)
13478
13166
  });
13479
13167
  var agentComposeContentSchema = external_exports.object({
13480
13168
  version: external_exports.string().min(1, "Version is required"),
@@ -14526,9 +14214,9 @@ function loadValues(cliValues, configNames) {
14526
14214
  const result = { ...cliValues };
14527
14215
  const missingNames = configNames.filter((name) => !(name in result));
14528
14216
  if (missingNames.length > 0) {
14529
- const envFilePath = path3.resolve(process.cwd(), ".env");
14217
+ const envFilePath = path.resolve(process.cwd(), ".env");
14530
14218
  let dotenvValues = {};
14531
- if (fs3.existsSync(envFilePath)) {
14219
+ if (fs.existsSync(envFilePath)) {
14532
14220
  const dotenvResult = dotenvConfig({ path: envFilePath });
14533
14221
  if (dotenvResult.parsed) {
14534
14222
  dotenvValues = Object.fromEntries(
@@ -15008,13 +14696,13 @@ import { Command as Command6 } from "commander";
15008
14696
  // src/commands/volume/init.ts
15009
14697
  import { Command as Command3 } from "commander";
15010
14698
  import chalk5 from "chalk";
15011
- import path5 from "path";
14699
+ import path3 from "path";
15012
14700
 
15013
14701
  // src/lib/storage-utils.ts
15014
- import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir4 } from "fs/promises";
14702
+ import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
15015
14703
  import { existsSync as existsSync4 } from "fs";
15016
14704
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
15017
- import path4 from "path";
14705
+ import path2 from "path";
15018
14706
  var CONFIG_DIR2 = ".vm0";
15019
14707
  var CONFIG_FILE2 = "storage.yaml";
15020
14708
  function isValidStorageName(name) {
@@ -15025,8 +14713,8 @@ function isValidStorageName(name) {
15025
14713
  return pattern.test(name) && !name.includes("--");
15026
14714
  }
15027
14715
  async function readStorageConfig(basePath = process.cwd()) {
15028
- const configPath = path4.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
15029
- const legacyConfigPath = path4.join(basePath, CONFIG_DIR2, "volume.yaml");
14716
+ const configPath = path2.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
14717
+ const legacyConfigPath = path2.join(basePath, CONFIG_DIR2, "volume.yaml");
15030
14718
  let actualPath = null;
15031
14719
  if (existsSync4(configPath)) {
15032
14720
  actualPath = configPath;
@@ -15036,7 +14724,7 @@ async function readStorageConfig(basePath = process.cwd()) {
15036
14724
  if (!actualPath) {
15037
14725
  return null;
15038
14726
  }
15039
- const content = await readFile4(actualPath, "utf8");
14727
+ const content = await readFile3(actualPath, "utf8");
15040
14728
  const config2 = parseYaml2(content);
15041
14729
  if (!config2.type) {
15042
14730
  config2.type = "volume";
@@ -15044,31 +14732,31 @@ async function readStorageConfig(basePath = process.cwd()) {
15044
14732
  return config2;
15045
14733
  }
15046
14734
  async function writeStorageConfig(storageName, basePath = process.cwd(), type = "volume") {
15047
- const configDir = path4.join(basePath, CONFIG_DIR2);
15048
- const configPath = path4.join(configDir, CONFIG_FILE2);
14735
+ const configDir = path2.join(basePath, CONFIG_DIR2);
14736
+ const configPath = path2.join(configDir, CONFIG_FILE2);
15049
14737
  if (!existsSync4(configDir)) {
15050
- await mkdir4(configDir, { recursive: true });
14738
+ await mkdir2(configDir, { recursive: true });
15051
14739
  }
15052
14740
  const config2 = {
15053
14741
  name: storageName,
15054
14742
  type
15055
14743
  };
15056
14744
  const yamlContent = stringifyYaml(config2);
15057
- await writeFile4(configPath, yamlContent, "utf8");
14745
+ await writeFile2(configPath, yamlContent, "utf8");
15058
14746
  }
15059
14747
 
15060
14748
  // src/commands/volume/init.ts
15061
14749
  var initCommand = new Command3().name("init").description("Initialize a volume in the current directory").action(async () => {
15062
14750
  try {
15063
14751
  const cwd = process.cwd();
15064
- const dirName = path5.basename(cwd);
14752
+ const dirName = path3.basename(cwd);
15065
14753
  const existingConfig = await readStorageConfig(cwd);
15066
14754
  if (existingConfig) {
15067
14755
  console.log(
15068
14756
  chalk5.yellow(`Volume already initialized: ${existingConfig.name}`)
15069
14757
  );
15070
14758
  console.log(
15071
- chalk5.gray(`Config file: ${path5.join(cwd, ".vm0", "storage.yaml")}`)
14759
+ chalk5.gray(`Config file: ${path3.join(cwd, ".vm0", "storage.yaml")}`)
15072
14760
  );
15073
14761
  return;
15074
14762
  }
@@ -15089,7 +14777,7 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
15089
14777
  console.log(chalk5.green(`\u2713 Initialized volume: ${volumeName}`));
15090
14778
  console.log(
15091
14779
  chalk5.gray(
15092
- `\u2713 Config saved to ${path5.join(cwd, ".vm0", "storage.yaml")}`
14780
+ `\u2713 Config saved to ${path3.join(cwd, ".vm0", "storage.yaml")}`
15093
14781
  )
15094
14782
  );
15095
14783
  } catch (error43) {
@@ -15104,15 +14792,15 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
15104
14792
  // src/commands/volume/push.ts
15105
14793
  import { Command as Command4 } from "commander";
15106
14794
  import chalk6 from "chalk";
15107
- import path7 from "path";
15108
- import * as fs5 from "fs";
15109
- import * as os3 from "os";
15110
- import * as tar3 from "tar";
14795
+ import path5 from "path";
14796
+ import * as fs3 from "fs";
14797
+ import * as os from "os";
14798
+ import * as tar2 from "tar";
15111
14799
 
15112
14800
  // src/lib/file-utils.ts
15113
- import * as fs4 from "fs";
15114
- import * as path6 from "path";
15115
- import * as tar2 from "tar";
14801
+ import * as fs2 from "fs";
14802
+ import * as path4 from "path";
14803
+ import * as tar from "tar";
15116
14804
  function excludeVm0Filter(filePath) {
15117
14805
  const shouldExclude = filePath === ".vm0" || filePath.startsWith(".vm0/") || filePath.startsWith("./.vm0");
15118
14806
  return !shouldExclude;
@@ -15120,7 +14808,7 @@ function excludeVm0Filter(filePath) {
15120
14808
  function listTarFiles(tarPath) {
15121
14809
  return new Promise((resolve2, reject) => {
15122
14810
  const files = [];
15123
- tar2.list({
14811
+ tar.list({
15124
14812
  file: tarPath,
15125
14813
  onReadEntry: (entry) => {
15126
14814
  if (entry.type === "File") {
@@ -15133,14 +14821,14 @@ function listTarFiles(tarPath) {
15133
14821
  async function listLocalFiles(dir, excludeDirs = [".vm0"]) {
15134
14822
  const files = [];
15135
14823
  async function walkDir(currentDir, relativePath = "") {
15136
- const entries = await fs4.promises.readdir(currentDir, {
14824
+ const entries = await fs2.promises.readdir(currentDir, {
15137
14825
  withFileTypes: true
15138
14826
  });
15139
14827
  for (const entry of entries) {
15140
- const entryRelativePath = relativePath ? path6.join(relativePath, entry.name) : entry.name;
14828
+ const entryRelativePath = relativePath ? path4.join(relativePath, entry.name) : entry.name;
15141
14829
  if (entry.isDirectory()) {
15142
14830
  if (!excludeDirs.includes(entry.name)) {
15143
- await walkDir(path6.join(currentDir, entry.name), entryRelativePath);
14831
+ await walkDir(path4.join(currentDir, entry.name), entryRelativePath);
15144
14832
  }
15145
14833
  } else {
15146
14834
  files.push(entryRelativePath);
@@ -15156,8 +14844,8 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
15156
14844
  for (const localFile of localFiles) {
15157
14845
  const normalizedPath = localFile.replace(/\\/g, "/");
15158
14846
  if (!remoteFiles.has(normalizedPath)) {
15159
- const fullPath = path6.join(dir, localFile);
15160
- await fs4.promises.unlink(fullPath);
14847
+ const fullPath = path4.join(dir, localFile);
14848
+ await fs2.promises.unlink(fullPath);
15161
14849
  removedCount++;
15162
14850
  }
15163
14851
  }
@@ -15165,17 +14853,17 @@ async function removeExtraFiles(dir, remoteFiles, excludeDirs = [".vm0"]) {
15165
14853
  return removedCount;
15166
14854
  }
15167
14855
  async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
15168
- const entries = await fs4.promises.readdir(dir, { withFileTypes: true });
14856
+ const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
15169
14857
  let isEmpty = true;
15170
14858
  for (const entry of entries) {
15171
- const fullPath = path6.join(dir, entry.name);
14859
+ const fullPath = path4.join(dir, entry.name);
15172
14860
  if (entry.isDirectory()) {
15173
14861
  if (excludeDirs.includes(entry.name)) {
15174
14862
  isEmpty = false;
15175
14863
  } else {
15176
14864
  const subDirEmpty = await removeEmptyDirs(fullPath, excludeDirs);
15177
14865
  if (subDirEmpty) {
15178
- await fs4.promises.rmdir(fullPath);
14866
+ await fs2.promises.rmdir(fullPath);
15179
14867
  } else {
15180
14868
  isEmpty = false;
15181
14869
  }
@@ -15190,10 +14878,10 @@ async function removeEmptyDirs(dir, excludeDirs = [".vm0"]) {
15190
14878
  // src/commands/volume/push.ts
15191
14879
  async function getAllFiles(dirPath, baseDir = dirPath) {
15192
14880
  const files = [];
15193
- const entries = await fs5.promises.readdir(dirPath, { withFileTypes: true });
14881
+ const entries = await fs3.promises.readdir(dirPath, { withFileTypes: true });
15194
14882
  for (const entry of entries) {
15195
- const fullPath = path7.join(dirPath, entry.name);
15196
- const relativePath = path7.relative(baseDir, fullPath);
14883
+ const fullPath = path5.join(dirPath, entry.name);
14884
+ const relativePath = path5.relative(baseDir, fullPath);
15197
14885
  if (relativePath.startsWith(".vm0")) {
15198
14886
  continue;
15199
14887
  }
@@ -15230,7 +14918,7 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15230
14918
  const files = await getAllFiles(cwd);
15231
14919
  let totalSize = 0;
15232
14920
  for (const file2 of files) {
15233
- const stats = await fs5.promises.stat(file2);
14921
+ const stats = await fs3.promises.stat(file2);
15234
14922
  totalSize += stats.size;
15235
14923
  }
15236
14924
  if (files.length === 0) {
@@ -15241,11 +14929,11 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15241
14929
  );
15242
14930
  }
15243
14931
  console.log(chalk6.gray("Compressing files..."));
15244
- const tmpDir = fs5.mkdtempSync(path7.join(os3.tmpdir(), "vm0-"));
15245
- const tarPath = path7.join(tmpDir, "volume.tar.gz");
15246
- const relativePaths = files.map((file2) => path7.relative(cwd, file2));
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));
15247
14935
  if (relativePaths.length > 0) {
15248
- await tar3.create(
14936
+ await tar2.create(
15249
14937
  {
15250
14938
  gzip: true,
15251
14939
  file: tarPath,
@@ -15254,7 +14942,7 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15254
14942
  relativePaths
15255
14943
  );
15256
14944
  } else {
15257
- await tar3.create(
14945
+ await tar2.create(
15258
14946
  {
15259
14947
  gzip: true,
15260
14948
  file: tarPath,
@@ -15264,9 +14952,9 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15264
14952
  ["."]
15265
14953
  );
15266
14954
  }
15267
- const tarBuffer = await fs5.promises.readFile(tarPath);
15268
- await fs5.promises.unlink(tarPath);
15269
- await fs5.promises.rmdir(tmpDir);
14955
+ const tarBuffer = await fs3.promises.readFile(tarPath);
14956
+ await fs3.promises.unlink(tarPath);
14957
+ await fs3.promises.rmdir(tmpDir);
15270
14958
  console.log(
15271
14959
  chalk6.green(`\u2713 Compressed to ${formatBytes(tarBuffer.length)}`)
15272
14960
  );
@@ -15312,10 +15000,10 @@ var pushCommand = new Command4().name("push").description("Push local files to c
15312
15000
  // src/commands/volume/pull.ts
15313
15001
  import { Command as Command5 } from "commander";
15314
15002
  import chalk7 from "chalk";
15315
- import path8 from "path";
15316
- import * as fs6 from "fs";
15317
- import * as os4 from "os";
15318
- import * as tar4 from "tar";
15003
+ import path6 from "path";
15004
+ import * as fs4 from "fs";
15005
+ import * as os2 from "os";
15006
+ import * as tar3 from "tar";
15319
15007
  function formatBytes2(bytes) {
15320
15008
  if (bytes === 0) return "0 B";
15321
15009
  const k = 1024;
@@ -15365,9 +15053,9 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15365
15053
  const arrayBuffer = await response.arrayBuffer();
15366
15054
  const tarBuffer = Buffer.from(arrayBuffer);
15367
15055
  console.log(chalk7.green(`\u2713 Downloaded ${formatBytes2(tarBuffer.length)}`));
15368
- const tmpDir = fs6.mkdtempSync(path8.join(os4.tmpdir(), "vm0-"));
15369
- const tarPath = path8.join(tmpDir, "volume.tar.gz");
15370
- await fs6.promises.writeFile(tarPath, tarBuffer);
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);
15371
15059
  console.log(chalk7.gray("Syncing local files..."));
15372
15060
  const remoteFiles = await listTarFiles(tarPath);
15373
15061
  const remoteFilesSet = new Set(
@@ -15380,13 +15068,13 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
15380
15068
  );
15381
15069
  }
15382
15070
  console.log(chalk7.gray("Extracting files..."));
15383
- await tar4.extract({
15071
+ await tar3.extract({
15384
15072
  file: tarPath,
15385
15073
  cwd,
15386
15074
  gzip: true
15387
15075
  });
15388
- await fs6.promises.unlink(tarPath);
15389
- await fs6.promises.rmdir(tmpDir);
15076
+ await fs4.promises.unlink(tarPath);
15077
+ await fs4.promises.rmdir(tmpDir);
15390
15078
  console.log(chalk7.green(`\u2713 Extracted ${remoteFiles.length} files`));
15391
15079
  } catch (error43) {
15392
15080
  console.error(chalk7.red("\u2717 Pull failed"));
@@ -15406,11 +15094,11 @@ import { Command as Command10 } from "commander";
15406
15094
  // src/commands/artifact/init.ts
15407
15095
  import { Command as Command7 } from "commander";
15408
15096
  import chalk8 from "chalk";
15409
- import path9 from "path";
15097
+ import path7 from "path";
15410
15098
  var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
15411
15099
  try {
15412
15100
  const cwd = process.cwd();
15413
- const dirName = path9.basename(cwd);
15101
+ const dirName = path7.basename(cwd);
15414
15102
  const existingConfig = await readStorageConfig(cwd);
15415
15103
  if (existingConfig) {
15416
15104
  if (existingConfig.type === "artifact") {
@@ -15432,7 +15120,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15432
15120
  );
15433
15121
  }
15434
15122
  console.log(
15435
- chalk8.gray(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
15123
+ chalk8.gray(`Config file: ${path7.join(cwd, ".vm0", "storage.yaml")}`)
15436
15124
  );
15437
15125
  return;
15438
15126
  }
@@ -15453,7 +15141,7 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15453
15141
  console.log(chalk8.green(`\u2713 Initialized artifact: ${artifactName}`));
15454
15142
  console.log(
15455
15143
  chalk8.gray(
15456
- `\u2713 Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
15144
+ `\u2713 Config saved to ${path7.join(cwd, ".vm0", "storage.yaml")}`
15457
15145
  )
15458
15146
  );
15459
15147
  } catch (error43) {
@@ -15468,16 +15156,16 @@ var initCommand2 = new Command7().name("init").description("Initialize an artifa
15468
15156
  // src/commands/artifact/push.ts
15469
15157
  import { Command as Command8 } from "commander";
15470
15158
  import chalk9 from "chalk";
15471
- import path10 from "path";
15472
- import * as fs7 from "fs";
15473
- import * as os5 from "os";
15474
- import * as tar5 from "tar";
15159
+ import path8 from "path";
15160
+ import * as fs5 from "fs";
15161
+ import * as os3 from "os";
15162
+ import * as tar4 from "tar";
15475
15163
  async function getAllFiles2(dirPath, baseDir = dirPath) {
15476
15164
  const files = [];
15477
- const entries = await fs7.promises.readdir(dirPath, { withFileTypes: true });
15165
+ const entries = await fs5.promises.readdir(dirPath, { withFileTypes: true });
15478
15166
  for (const entry of entries) {
15479
- const fullPath = path10.join(dirPath, entry.name);
15480
- const relativePath = path10.relative(baseDir, fullPath);
15167
+ const fullPath = path8.join(dirPath, entry.name);
15168
+ const relativePath = path8.relative(baseDir, fullPath);
15481
15169
  if (relativePath.startsWith(".vm0")) {
15482
15170
  continue;
15483
15171
  }
@@ -15523,7 +15211,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15523
15211
  const files = await getAllFiles2(cwd);
15524
15212
  let totalSize = 0;
15525
15213
  for (const file2 of files) {
15526
- const stats = await fs7.promises.stat(file2);
15214
+ const stats = await fs5.promises.stat(file2);
15527
15215
  totalSize += stats.size;
15528
15216
  }
15529
15217
  if (files.length === 0) {
@@ -15534,11 +15222,11 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15534
15222
  );
15535
15223
  }
15536
15224
  console.log(chalk9.gray("Compressing files..."));
15537
- const tmpDir = fs7.mkdtempSync(path10.join(os5.tmpdir(), "vm0-"));
15538
- const tarPath = path10.join(tmpDir, "artifact.tar.gz");
15539
- const relativePaths = files.map((file2) => path10.relative(cwd, file2));
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));
15540
15228
  if (relativePaths.length > 0) {
15541
- await tar5.create(
15229
+ await tar4.create(
15542
15230
  {
15543
15231
  gzip: true,
15544
15232
  file: tarPath,
@@ -15547,7 +15235,7 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15547
15235
  relativePaths
15548
15236
  );
15549
15237
  } else {
15550
- await tar5.create(
15238
+ await tar4.create(
15551
15239
  {
15552
15240
  gzip: true,
15553
15241
  file: tarPath,
@@ -15557,9 +15245,9 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15557
15245
  ["."]
15558
15246
  );
15559
15247
  }
15560
- const tarBuffer = await fs7.promises.readFile(tarPath);
15561
- await fs7.promises.unlink(tarPath);
15562
- await fs7.promises.rmdir(tmpDir);
15248
+ const tarBuffer = await fs5.promises.readFile(tarPath);
15249
+ await fs5.promises.unlink(tarPath);
15250
+ await fs5.promises.rmdir(tmpDir);
15563
15251
  console.log(
15564
15252
  chalk9.green(`\u2713 Compressed to ${formatBytes3(tarBuffer.length)}`)
15565
15253
  );
@@ -15604,10 +15292,10 @@ var pushCommand2 = new Command8().name("push").description("Push local files to
15604
15292
  // src/commands/artifact/pull.ts
15605
15293
  import { Command as Command9 } from "commander";
15606
15294
  import chalk10 from "chalk";
15607
- import path11 from "path";
15608
- import * as fs8 from "fs";
15609
- import * as os6 from "os";
15610
- import * as tar6 from "tar";
15295
+ import path9 from "path";
15296
+ import * as fs6 from "fs";
15297
+ import * as os4 from "os";
15298
+ import * as tar5 from "tar";
15611
15299
  function formatBytes4(bytes) {
15612
15300
  if (bytes === 0) return "0 B";
15613
15301
  const k = 1024;
@@ -15668,9 +15356,9 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15668
15356
  const arrayBuffer = await response.arrayBuffer();
15669
15357
  const tarBuffer = Buffer.from(arrayBuffer);
15670
15358
  console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(tarBuffer.length)}`));
15671
- const tmpDir = fs8.mkdtempSync(path11.join(os6.tmpdir(), "vm0-"));
15672
- const tarPath = path11.join(tmpDir, "artifact.tar.gz");
15673
- await fs8.promises.writeFile(tarPath, tarBuffer);
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);
15674
15362
  console.log(chalk10.gray("Syncing local files..."));
15675
15363
  const remoteFiles = await listTarFiles(tarPath);
15676
15364
  const remoteFilesSet = new Set(
@@ -15683,13 +15371,13 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
15683
15371
  );
15684
15372
  }
15685
15373
  console.log(chalk10.gray("Extracting files..."));
15686
- await tar6.extract({
15374
+ await tar5.extract({
15687
15375
  file: tarPath,
15688
15376
  cwd,
15689
15377
  gzip: true
15690
15378
  });
15691
- await fs8.promises.unlink(tarPath);
15692
- await fs8.promises.rmdir(tmpDir);
15379
+ await fs6.promises.unlink(tarPath);
15380
+ await fs6.promises.rmdir(tmpDir);
15693
15381
  console.log(chalk10.green(`\u2713 Extracted ${remoteFiles.length} files`));
15694
15382
  } catch (error43) {
15695
15383
  console.error(chalk10.red("\u2717 Pull failed"));
@@ -15706,9 +15394,9 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
15706
15394
  // src/commands/cook.ts
15707
15395
  import { Command as Command11 } from "commander";
15708
15396
  import chalk11 from "chalk";
15709
- import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
15397
+ import { readFile as readFile4, mkdir as mkdir3 } from "fs/promises";
15710
15398
  import { existsSync as existsSync5 } from "fs";
15711
- import path12 from "path";
15399
+ import path10 from "path";
15712
15400
  import { spawn } from "child_process";
15713
15401
  import { parse as parseYaml3 } from "yaml";
15714
15402
  var CONFIG_FILE3 = "vm0.yaml";
@@ -15797,7 +15485,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15797
15485
  }
15798
15486
  let config2;
15799
15487
  try {
15800
- const content = await readFile5(CONFIG_FILE3, "utf8");
15488
+ const content = await readFile4(CONFIG_FILE3, "utf8");
15801
15489
  config2 = parseYaml3(content);
15802
15490
  } catch (error43) {
15803
15491
  console.error(chalk11.red("\u2717 Invalid YAML format"));
@@ -15821,7 +15509,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15821
15509
  console.log();
15822
15510
  console.log(chalk11.blue("Processing volumes..."));
15823
15511
  for (const volumeConfig of Object.values(config2.volumes)) {
15824
- const volumeDir = path12.join(cwd, volumeConfig.name);
15512
+ const volumeDir = path10.join(cwd, volumeConfig.name);
15825
15513
  console.log(chalk11.gray(` ${volumeConfig.name}/`));
15826
15514
  if (!existsSync5(volumeDir)) {
15827
15515
  console.error(
@@ -15856,11 +15544,11 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
15856
15544
  }
15857
15545
  console.log();
15858
15546
  console.log(chalk11.blue("Processing artifact..."));
15859
- const artifactDir = path12.join(cwd, ARTIFACT_DIR);
15547
+ const artifactDir = path10.join(cwd, ARTIFACT_DIR);
15860
15548
  console.log(chalk11.gray(` ${ARTIFACT_DIR}/`));
15861
15549
  try {
15862
15550
  if (!existsSync5(artifactDir)) {
15863
- await mkdir5(artifactDir, { recursive: true });
15551
+ await mkdir3(artifactDir, { recursive: true });
15864
15552
  console.log(chalk11.green(` \u2713 Created directory`));
15865
15553
  }
15866
15554
  const existingConfig = await readStorageConfig(artifactDir);
@@ -15952,7 +15640,7 @@ import { Command as Command15 } from "commander";
15952
15640
  // src/commands/image/build.ts
15953
15641
  import { Command as Command12 } from "commander";
15954
15642
  import chalk12 from "chalk";
15955
- import { readFile as readFile6 } from "fs/promises";
15643
+ import { readFile as readFile5 } from "fs/promises";
15956
15644
  import { existsSync as existsSync6 } from "fs";
15957
15645
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
15958
15646
  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(
@@ -15980,7 +15668,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
15980
15668
  process.exit(1);
15981
15669
  }
15982
15670
  try {
15983
- const dockerfile = await readFile6(file2, "utf8");
15671
+ const dockerfile = await readFile5(file2, "utf8");
15984
15672
  console.log(chalk12.blue(`Building image: ${name}`));
15985
15673
  console.log(chalk12.gray(` Dockerfile: ${file2}`));
15986
15674
  console.log();
@@ -16404,7 +16092,7 @@ function handleError(error43, runId) {
16404
16092
 
16405
16093
  // src/index.ts
16406
16094
  var program = new Command17();
16407
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.7.0");
16095
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.7.1");
16408
16096
  program.command("info").description("Display environment information").action(async () => {
16409
16097
  console.log(chalk16.cyan("System Information:"));
16410
16098
  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.0",
3
+ "version": "4.7.1",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",