@vm0/cli 1.4.0 → 1.5.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 +313 -41
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -736,15 +736,15 @@ function mergeDefs(...defs) {
736
736
  function cloneDef(schema) {
737
737
  return mergeDefs(schema._zod.def);
738
738
  }
739
- function getElementAtPath(obj, path5) {
740
- if (!path5)
739
+ function getElementAtPath(obj, path8) {
740
+ if (!path8)
741
741
  return obj;
742
- return path5.reduce((acc, key) => acc?.[key], obj);
742
+ return path8.reduce((acc, key) => acc?.[key], obj);
743
743
  }
744
744
  function promiseAllObject(promisesObj) {
745
745
  const keys = Object.keys(promisesObj);
746
- const promises3 = keys.map((key) => promisesObj[key]);
747
- return Promise.all(promises3).then((results) => {
746
+ const promises5 = keys.map((key) => promisesObj[key]);
747
+ return Promise.all(promises5).then((results) => {
748
748
  const resolvedObj = {};
749
749
  for (let i = 0; i < keys.length; i++) {
750
750
  resolvedObj[keys[i]] = results[i];
@@ -1098,11 +1098,11 @@ function aborted(x, startIndex = 0) {
1098
1098
  }
1099
1099
  return false;
1100
1100
  }
1101
- function prefixIssues(path5, issues) {
1101
+ function prefixIssues(path8, issues) {
1102
1102
  return issues.map((iss) => {
1103
1103
  var _a;
1104
1104
  (_a = iss).path ?? (_a.path = []);
1105
- iss.path.unshift(path5);
1105
+ iss.path.unshift(path8);
1106
1106
  return iss;
1107
1107
  });
1108
1108
  }
@@ -1270,7 +1270,7 @@ function treeifyError(error43, _mapper) {
1270
1270
  return issue2.message;
1271
1271
  };
1272
1272
  const result = { errors: [] };
1273
- const processError = (error44, path5 = []) => {
1273
+ const processError = (error44, path8 = []) => {
1274
1274
  var _a, _b;
1275
1275
  for (const issue2 of error44.issues) {
1276
1276
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -1280,7 +1280,7 @@ function treeifyError(error43, _mapper) {
1280
1280
  } else if (issue2.code === "invalid_element") {
1281
1281
  processError({ issues: issue2.issues }, issue2.path);
1282
1282
  } else {
1283
- const fullpath = [...path5, ...issue2.path];
1283
+ const fullpath = [...path8, ...issue2.path];
1284
1284
  if (fullpath.length === 0) {
1285
1285
  result.errors.push(mapper(issue2));
1286
1286
  continue;
@@ -1312,8 +1312,8 @@ function treeifyError(error43, _mapper) {
1312
1312
  }
1313
1313
  function toDotPath(_path) {
1314
1314
  const segs = [];
1315
- const path5 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1316
- for (const seg of path5) {
1315
+ const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1316
+ for (const seg of path8) {
1317
1317
  if (typeof seg === "number")
1318
1318
  segs.push(`[${seg}]`);
1319
1319
  else if (typeof seg === "symbol")
@@ -12147,8 +12147,8 @@ var helloContract = c.router({
12147
12147
  var FOO = "hello";
12148
12148
 
12149
12149
  // src/index.ts
12150
- import { Command as Command7 } from "commander";
12151
- import chalk8 from "chalk";
12150
+ import { Command as Command11 } from "commander";
12151
+ import chalk11 from "chalk";
12152
12152
 
12153
12153
  // src/lib/auth.ts
12154
12154
  import chalk from "chalk";
@@ -12416,7 +12416,7 @@ var ApiClient = class {
12416
12416
  /**
12417
12417
  * Generic GET request
12418
12418
  */
12419
- async get(path5) {
12419
+ async get(path8) {
12420
12420
  const baseUrl = await this.getBaseUrl();
12421
12421
  const token = await getToken();
12422
12422
  if (!token) {
@@ -12429,7 +12429,7 @@ var ApiClient = class {
12429
12429
  if (bypassSecret) {
12430
12430
  headers["x-vercel-protection-bypass"] = bypassSecret;
12431
12431
  }
12432
- return fetch(`${baseUrl}${path5}`, {
12432
+ return fetch(`${baseUrl}${path8}`, {
12433
12433
  method: "GET",
12434
12434
  headers
12435
12435
  });
@@ -12437,7 +12437,7 @@ var ApiClient = class {
12437
12437
  /**
12438
12438
  * Generic POST request
12439
12439
  */
12440
- async post(path5, options) {
12440
+ async post(path8, options) {
12441
12441
  const baseUrl = await this.getBaseUrl();
12442
12442
  const token = await getToken();
12443
12443
  if (!token) {
@@ -12450,7 +12450,7 @@ var ApiClient = class {
12450
12450
  if (bypassSecret) {
12451
12451
  headers["x-vercel-protection-bypass"] = bypassSecret;
12452
12452
  }
12453
- return fetch(`${baseUrl}${path5}`, {
12453
+ return fetch(`${baseUrl}${path8}`, {
12454
12454
  method: "POST",
12455
12455
  headers,
12456
12456
  body: options?.body
@@ -12964,6 +12964,9 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
12964
12964
  "Environment variables (repeatable)",
12965
12965
  collectEnvVars,
12966
12966
  {}
12967
+ ).option(
12968
+ "-a, --artifact <key>",
12969
+ "Artifact key to mount (for VM0 driver artifacts)"
12967
12970
  ).action(
12968
12971
  async (identifier, prompt, options) => {
12969
12972
  try {
@@ -12996,13 +12999,17 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
12996
12999
  chalk4.gray(` Variables: ${JSON.stringify(options.env)}`)
12997
13000
  );
12998
13001
  }
13002
+ if (options.artifact) {
13003
+ console.log(chalk4.gray(` Artifact: ${options.artifact}`));
13004
+ }
12999
13005
  console.log();
13000
13006
  console.log(chalk4.blue("Executing in sandbox..."));
13001
13007
  console.log();
13002
13008
  const response = await apiClient.createRun({
13003
13009
  agentConfigId: configId,
13004
13010
  prompt,
13005
- dynamicVars: Object.keys(options.env).length > 0 ? options.env : void 0
13011
+ dynamicVars: Object.keys(options.env).length > 0 ? options.env : void 0,
13012
+ artifactKey: options.artifact
13006
13013
  });
13007
13014
  await pollEvents(response.runId);
13008
13015
  } catch (error43) {
@@ -13073,37 +13080,48 @@ import { Command as Command3 } from "commander";
13073
13080
  import chalk5 from "chalk";
13074
13081
  import path2 from "path";
13075
13082
 
13076
- // src/lib/volume-utils.ts
13083
+ // src/lib/storage-utils.ts
13077
13084
  import { readFile as readFile3, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
13078
13085
  import { existsSync as existsSync3 } from "fs";
13079
13086
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
13080
13087
  import path from "path";
13081
13088
  var CONFIG_DIR2 = ".vm0";
13082
- var CONFIG_FILE2 = "volume.yaml";
13083
- function isValidVolumeName(name) {
13089
+ var CONFIG_FILE2 = "storage.yaml";
13090
+ function isValidStorageName(name) {
13084
13091
  if (name.length < 3 || name.length > 64) {
13085
13092
  return false;
13086
13093
  }
13087
13094
  const pattern = /^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$/;
13088
13095
  return pattern.test(name) && !name.includes("--");
13089
13096
  }
13090
- async function readVolumeConfig(basePath = process.cwd()) {
13097
+ async function readStorageConfig(basePath = process.cwd()) {
13091
13098
  const configPath = path.join(basePath, CONFIG_DIR2, CONFIG_FILE2);
13092
- if (!existsSync3(configPath)) {
13099
+ const legacyConfigPath = path.join(basePath, CONFIG_DIR2, "volume.yaml");
13100
+ let actualPath = null;
13101
+ if (existsSync3(configPath)) {
13102
+ actualPath = configPath;
13103
+ } else if (existsSync3(legacyConfigPath)) {
13104
+ actualPath = legacyConfigPath;
13105
+ }
13106
+ if (!actualPath) {
13093
13107
  return null;
13094
13108
  }
13095
- const content = await readFile3(configPath, "utf8");
13109
+ const content = await readFile3(actualPath, "utf8");
13096
13110
  const config2 = parseYaml2(content);
13111
+ if (!config2.type) {
13112
+ config2.type = "volume";
13113
+ }
13097
13114
  return config2;
13098
13115
  }
13099
- async function writeVolumeConfig(volumeName, basePath = process.cwd()) {
13116
+ async function writeStorageConfig(storageName, basePath = process.cwd(), type = "volume") {
13100
13117
  const configDir = path.join(basePath, CONFIG_DIR2);
13101
13118
  const configPath = path.join(configDir, CONFIG_FILE2);
13102
13119
  if (!existsSync3(configDir)) {
13103
13120
  await mkdir2(configDir, { recursive: true });
13104
13121
  }
13105
13122
  const config2 = {
13106
- name: volumeName
13123
+ name: storageName,
13124
+ type
13107
13125
  };
13108
13126
  const yamlContent = stringifyYaml(config2);
13109
13127
  await writeFile2(configPath, yamlContent, "utf8");
@@ -13114,18 +13132,18 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
13114
13132
  try {
13115
13133
  const cwd = process.cwd();
13116
13134
  const dirName = path2.basename(cwd);
13117
- const existingConfig = await readVolumeConfig(cwd);
13135
+ const existingConfig = await readStorageConfig(cwd);
13118
13136
  if (existingConfig) {
13119
13137
  console.log(
13120
13138
  chalk5.yellow(`Volume already initialized: ${existingConfig.name}`)
13121
13139
  );
13122
13140
  console.log(
13123
- chalk5.gray(`Config file: ${path2.join(cwd, ".vm0", "volume.yaml")}`)
13141
+ chalk5.gray(`Config file: ${path2.join(cwd, ".vm0", "storage.yaml")}`)
13124
13142
  );
13125
13143
  return;
13126
13144
  }
13127
13145
  const volumeName = dirName;
13128
- if (!isValidVolumeName(volumeName)) {
13146
+ if (!isValidStorageName(volumeName)) {
13129
13147
  console.error(chalk5.red(`\u2717 Invalid volume name: "${dirName}"`));
13130
13148
  console.error(
13131
13149
  chalk5.gray(
@@ -13137,11 +13155,11 @@ var initCommand = new Command3().name("init").description("Initialize a volume i
13137
13155
  );
13138
13156
  process.exit(1);
13139
13157
  }
13140
- await writeVolumeConfig(volumeName, cwd);
13158
+ await writeStorageConfig(volumeName, cwd);
13141
13159
  console.log(chalk5.green(`\u2713 Initialized volume: ${volumeName}`));
13142
13160
  console.log(
13143
13161
  chalk5.gray(
13144
- `\u2713 Config saved to ${path2.join(cwd, ".vm0", "volume.yaml")}`
13162
+ `\u2713 Config saved to ${path2.join(cwd, ".vm0", "storage.yaml")}`
13145
13163
  )
13146
13164
  );
13147
13165
  } catch (error43) {
@@ -13187,7 +13205,7 @@ function formatBytes(bytes) {
13187
13205
  var pushCommand = new Command4().name("push").description("Push local files to cloud volume").action(async () => {
13188
13206
  try {
13189
13207
  const cwd = process.cwd();
13190
- const config2 = await readVolumeConfig(cwd);
13208
+ const config2 = await readStorageConfig(cwd);
13191
13209
  if (!config2) {
13192
13210
  console.error(chalk6.red("\u2717 No volume initialized in this directory"));
13193
13211
  console.error(chalk6.gray(" Run: vm0 volume init"));
@@ -13220,13 +13238,14 @@ var pushCommand = new Command4().name("push").description("Push local files to c
13220
13238
  );
13221
13239
  console.log(chalk6.gray("Uploading..."));
13222
13240
  const formData = new FormData();
13223
- formData.append("volumeName", config2.name);
13241
+ formData.append("name", config2.name);
13242
+ formData.append("type", "volume");
13224
13243
  formData.append(
13225
13244
  "file",
13226
13245
  new Blob([zipBuffer], { type: "application/zip" }),
13227
13246
  "volume.zip"
13228
13247
  );
13229
- const response = await apiClient.post("/api/volumes", {
13248
+ const response = await apiClient.post("/api/storages", {
13230
13249
  body: formData
13231
13250
  });
13232
13251
  if (!response.ok) {
@@ -13263,7 +13282,7 @@ function formatBytes2(bytes) {
13263
13282
  var pullCommand = new Command5().name("pull").description("Pull cloud files to local directory").action(async () => {
13264
13283
  try {
13265
13284
  const cwd = process.cwd();
13266
- const config2 = await readVolumeConfig(cwd);
13285
+ const config2 = await readStorageConfig(cwd);
13267
13286
  if (!config2) {
13268
13287
  console.error(chalk7.red("\u2717 No volume initialized in this directory"));
13269
13288
  console.error(chalk7.gray(" Run: vm0 volume init"));
@@ -13272,14 +13291,14 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
13272
13291
  console.log(chalk7.cyan(`Pulling volume: ${config2.name}`));
13273
13292
  console.log(chalk7.gray("Downloading..."));
13274
13293
  const response = await apiClient.get(
13275
- `/api/volumes?name=${encodeURIComponent(config2.name)}`
13294
+ `/api/storages?name=${encodeURIComponent(config2.name)}`
13276
13295
  );
13277
13296
  if (!response.ok) {
13278
13297
  if (response.status === 404) {
13279
13298
  console.error(chalk7.red(`\u2717 Volume "${config2.name}" not found`));
13280
13299
  console.error(
13281
13300
  chalk7.gray(
13282
- " Make sure the volume name is correct in .vm0/volume.yaml"
13301
+ " Make sure the volume name is correct in .vm0/storage.yaml"
13283
13302
  )
13284
13303
  );
13285
13304
  console.error(
@@ -13321,15 +13340,267 @@ var pullCommand = new Command5().name("pull").description("Pull cloud files to l
13321
13340
  // src/commands/volume/index.ts
13322
13341
  var volumeCommand = new Command6().name("volume").description("Manage cloud volumes").addCommand(initCommand).addCommand(pushCommand).addCommand(pullCommand);
13323
13342
 
13343
+ // src/commands/artifact/index.ts
13344
+ import { Command as Command10 } from "commander";
13345
+
13346
+ // src/commands/artifact/init.ts
13347
+ import { Command as Command7 } from "commander";
13348
+ import chalk8 from "chalk";
13349
+ import path5 from "path";
13350
+ var initCommand2 = new Command7().name("init").description("Initialize an artifact in the current directory").action(async () => {
13351
+ try {
13352
+ const cwd = process.cwd();
13353
+ const dirName = path5.basename(cwd);
13354
+ const existingConfig = await readStorageConfig(cwd);
13355
+ if (existingConfig) {
13356
+ if (existingConfig.type === "artifact") {
13357
+ console.log(
13358
+ chalk8.yellow(
13359
+ `Artifact already initialized: ${existingConfig.name}`
13360
+ )
13361
+ );
13362
+ } else {
13363
+ console.log(
13364
+ chalk8.yellow(
13365
+ `Directory already initialized as volume: ${existingConfig.name}`
13366
+ )
13367
+ );
13368
+ console.log(
13369
+ chalk8.gray(
13370
+ " To change type, delete .vm0/storage.yaml and reinitialize"
13371
+ )
13372
+ );
13373
+ }
13374
+ console.log(
13375
+ chalk8.gray(`Config file: ${path5.join(cwd, ".vm0", "storage.yaml")}`)
13376
+ );
13377
+ return;
13378
+ }
13379
+ const artifactName = dirName;
13380
+ if (!isValidStorageName(artifactName)) {
13381
+ console.error(chalk8.red(`\u2717 Invalid artifact name: "${dirName}"`));
13382
+ console.error(
13383
+ chalk8.gray(
13384
+ " Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
13385
+ )
13386
+ );
13387
+ console.error(
13388
+ chalk8.gray(" Example: my-project, user-workspace, code-artifact")
13389
+ );
13390
+ process.exit(1);
13391
+ }
13392
+ await writeStorageConfig(artifactName, cwd, "artifact");
13393
+ console.log(chalk8.green(`\u2713 Initialized artifact: ${artifactName}`));
13394
+ console.log(
13395
+ chalk8.gray(
13396
+ `\u2713 Config saved to ${path5.join(cwd, ".vm0", "storage.yaml")}`
13397
+ )
13398
+ );
13399
+ } catch (error43) {
13400
+ console.error(chalk8.red("\u2717 Failed to initialize artifact"));
13401
+ if (error43 instanceof Error) {
13402
+ console.error(chalk8.gray(` ${error43.message}`));
13403
+ }
13404
+ process.exit(1);
13405
+ }
13406
+ });
13407
+
13408
+ // src/commands/artifact/push.ts
13409
+ import { Command as Command8 } from "commander";
13410
+ import chalk9 from "chalk";
13411
+ import path6 from "path";
13412
+ import * as fs3 from "fs";
13413
+ import AdmZip3 from "adm-zip";
13414
+ async function getAllFiles2(dirPath, baseDir = dirPath) {
13415
+ const files = [];
13416
+ const entries = await fs3.promises.readdir(dirPath, { withFileTypes: true });
13417
+ for (const entry of entries) {
13418
+ const fullPath = path6.join(dirPath, entry.name);
13419
+ const relativePath = path6.relative(baseDir, fullPath);
13420
+ if (relativePath.startsWith(".vm0")) {
13421
+ continue;
13422
+ }
13423
+ if (entry.isDirectory()) {
13424
+ const subFiles = await getAllFiles2(fullPath, baseDir);
13425
+ files.push(...subFiles);
13426
+ } else {
13427
+ files.push(fullPath);
13428
+ }
13429
+ }
13430
+ return files;
13431
+ }
13432
+ function formatBytes3(bytes) {
13433
+ if (bytes === 0) return "0 B";
13434
+ const k = 1024;
13435
+ const sizes = ["B", "KB", "MB", "GB"];
13436
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
13437
+ return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
13438
+ }
13439
+ var pushCommand2 = new Command8().name("push").description("Push local files to cloud artifact").action(async () => {
13440
+ try {
13441
+ const cwd = process.cwd();
13442
+ const config2 = await readStorageConfig(cwd);
13443
+ if (!config2) {
13444
+ console.error(chalk9.red("\u2717 No artifact initialized in this directory"));
13445
+ console.error(chalk9.gray(" Run: vm0 artifact init"));
13446
+ process.exit(1);
13447
+ }
13448
+ if (config2.type !== "artifact") {
13449
+ console.error(
13450
+ chalk9.red(
13451
+ `\u2717 This directory is initialized as a volume, not an artifact`
13452
+ )
13453
+ );
13454
+ console.error(chalk9.gray(" Use: vm0 volume push"));
13455
+ process.exit(1);
13456
+ }
13457
+ console.log(chalk9.cyan(`Pushing artifact: ${config2.name}`));
13458
+ console.log(chalk9.gray("Collecting files..."));
13459
+ const files = await getAllFiles2(cwd);
13460
+ if (files.length === 0) {
13461
+ console.log(chalk9.yellow("No files to upload"));
13462
+ return;
13463
+ }
13464
+ let totalSize = 0;
13465
+ for (const file2 of files) {
13466
+ const stats = await fs3.promises.stat(file2);
13467
+ totalSize += stats.size;
13468
+ }
13469
+ console.log(
13470
+ chalk9.gray(`Found ${files.length} files (${formatBytes3(totalSize)})`)
13471
+ );
13472
+ console.log(chalk9.gray("Compressing files..."));
13473
+ const zip = new AdmZip3();
13474
+ for (const file2 of files) {
13475
+ const relativePath = path6.relative(cwd, file2);
13476
+ zip.addLocalFile(file2, path6.dirname(relativePath));
13477
+ }
13478
+ const zipBuffer = zip.toBuffer();
13479
+ console.log(
13480
+ chalk9.green(`\u2713 Compressed to ${formatBytes3(zipBuffer.length)}`)
13481
+ );
13482
+ console.log(chalk9.gray("Uploading..."));
13483
+ const formData = new FormData();
13484
+ formData.append("name", config2.name);
13485
+ formData.append("type", "artifact");
13486
+ formData.append(
13487
+ "file",
13488
+ new Blob([zipBuffer], { type: "application/zip" }),
13489
+ "artifact.zip"
13490
+ );
13491
+ const response = await apiClient.post("/api/storages", {
13492
+ body: formData
13493
+ });
13494
+ if (!response.ok) {
13495
+ const error43 = await response.json();
13496
+ throw new Error(error43.error || "Upload failed");
13497
+ }
13498
+ const result = await response.json();
13499
+ console.log(chalk9.green("\u2713 Upload complete"));
13500
+ console.log(chalk9.gray(` Version: ${result.versionId}`));
13501
+ console.log(chalk9.gray(` Files: ${result.fileCount.toLocaleString()}`));
13502
+ console.log(chalk9.gray(` Size: ${formatBytes3(result.size)}`));
13503
+ } catch (error43) {
13504
+ console.error(chalk9.red("\u2717 Push failed"));
13505
+ if (error43 instanceof Error) {
13506
+ console.error(chalk9.gray(` ${error43.message}`));
13507
+ }
13508
+ process.exit(1);
13509
+ }
13510
+ });
13511
+
13512
+ // src/commands/artifact/pull.ts
13513
+ import { Command as Command9 } from "commander";
13514
+ import chalk10 from "chalk";
13515
+ import path7 from "path";
13516
+ import * as fs4 from "fs";
13517
+ import AdmZip4 from "adm-zip";
13518
+ function formatBytes4(bytes) {
13519
+ if (bytes === 0) return "0 B";
13520
+ const k = 1024;
13521
+ const sizes = ["B", "KB", "MB", "GB"];
13522
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
13523
+ return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
13524
+ }
13525
+ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact to local directory").action(async () => {
13526
+ try {
13527
+ const cwd = process.cwd();
13528
+ const config2 = await readStorageConfig(cwd);
13529
+ if (!config2) {
13530
+ console.error(chalk10.red("\u2717 No artifact initialized in this directory"));
13531
+ console.error(chalk10.gray(" Run: vm0 artifact init"));
13532
+ process.exit(1);
13533
+ }
13534
+ if (config2.type !== "artifact") {
13535
+ console.error(
13536
+ chalk10.red(
13537
+ `\u2717 This directory is initialized as a volume, not an artifact`
13538
+ )
13539
+ );
13540
+ console.error(chalk10.gray(" Use: vm0 volume pull"));
13541
+ process.exit(1);
13542
+ }
13543
+ console.log(chalk10.cyan(`Pulling artifact: ${config2.name}`));
13544
+ console.log(chalk10.gray("Downloading..."));
13545
+ const response = await apiClient.get(
13546
+ `/api/storages?name=${encodeURIComponent(config2.name)}`
13547
+ );
13548
+ if (!response.ok) {
13549
+ if (response.status === 404) {
13550
+ console.error(chalk10.red(`\u2717 Artifact "${config2.name}" not found`));
13551
+ console.error(
13552
+ chalk10.gray(
13553
+ " Make sure the artifact name is correct in .vm0/storage.yaml"
13554
+ )
13555
+ );
13556
+ console.error(
13557
+ chalk10.gray(" Or push the artifact first with: vm0 artifact push")
13558
+ );
13559
+ } else {
13560
+ const error43 = await response.json();
13561
+ throw new Error(error43.error || "Download failed");
13562
+ }
13563
+ process.exit(1);
13564
+ }
13565
+ const arrayBuffer = await response.arrayBuffer();
13566
+ const zipBuffer = Buffer.from(arrayBuffer);
13567
+ console.log(chalk10.green(`\u2713 Downloaded ${formatBytes4(zipBuffer.length)}`));
13568
+ console.log(chalk10.gray("Extracting files..."));
13569
+ const zip = new AdmZip4(zipBuffer);
13570
+ const zipEntries = zip.getEntries();
13571
+ let extractedCount = 0;
13572
+ for (const entry of zipEntries) {
13573
+ if (!entry.isDirectory) {
13574
+ const targetPath = path7.join(cwd, entry.entryName);
13575
+ const dir = path7.dirname(targetPath);
13576
+ await fs4.promises.mkdir(dir, { recursive: true });
13577
+ const data = entry.getData();
13578
+ await fs4.promises.writeFile(targetPath, data);
13579
+ extractedCount++;
13580
+ }
13581
+ }
13582
+ console.log(chalk10.green(`\u2713 Extracted ${extractedCount} files`));
13583
+ } catch (error43) {
13584
+ console.error(chalk10.red("\u2717 Pull failed"));
13585
+ if (error43 instanceof Error) {
13586
+ console.error(chalk10.gray(` ${error43.message}`));
13587
+ }
13588
+ process.exit(1);
13589
+ }
13590
+ });
13591
+
13592
+ // src/commands/artifact/index.ts
13593
+ var artifactCommand = new Command10().name("artifact").description("Manage cloud artifacts (work products)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2);
13594
+
13324
13595
  // src/index.ts
13325
- var program = new Command7();
13596
+ var program = new Command11();
13326
13597
  program.name("vm0").description("VM0 CLI - A modern build tool").version("0.1.0");
13327
13598
  program.command("hello").description("Say hello from the App").action(() => {
13328
- console.log(chalk8.blue("Welcome to the VM0 CLI!"));
13329
- console.log(chalk8.green(`Core says: ${FOO}`));
13599
+ console.log(chalk11.blue("Welcome to the VM0 CLI!"));
13600
+ console.log(chalk11.green(`Core says: ${FOO}`));
13330
13601
  });
13331
13602
  program.command("info").description("Display environment information").action(async () => {
13332
- console.log(chalk8.cyan("System Information:"));
13603
+ console.log(chalk11.cyan("System Information:"));
13333
13604
  console.log(`Node Version: ${process.version}`);
13334
13605
  console.log(`Platform: ${process.platform}`);
13335
13606
  console.log(`Architecture: ${process.arch}`);
@@ -13349,6 +13620,7 @@ authCommand.command("status").description("Show current authentication status").
13349
13620
  program.addCommand(buildCommand);
13350
13621
  program.addCommand(runCommand);
13351
13622
  program.addCommand(volumeCommand);
13623
+ program.addCommand(artifactCommand);
13352
13624
  if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
13353
13625
  program.parse();
13354
13626
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "CLI application",
5
5
  "type": "module",
6
6
  "bin": {