@vm0/cli 4.1.0 → 4.2.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 +80 -75
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2421,88 +2421,93 @@ import chalk15 from "chalk";
2421
2421
  import { readFile as readFile5 } from "fs/promises";
2422
2422
  import { existsSync as existsSync5 } from "fs";
2423
2423
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2424
- var buildCommand = new Command16().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").action(async (options) => {
2425
- const { file, name } = options;
2426
- if (!existsSync5(file)) {
2427
- console.error(chalk15.red(`\u2717 Dockerfile not found: ${file}`));
2428
- process.exit(1);
2429
- }
2430
- const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
2431
- if (!nameRegex.test(name)) {
2432
- console.error(
2433
- chalk15.red(
2434
- "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
2435
- )
2436
- );
2437
- process.exit(1);
2438
- }
2439
- if (name.startsWith("vm0-")) {
2440
- console.error(
2441
- chalk15.red(
2442
- '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
2443
- )
2444
- );
2445
- process.exit(1);
2446
- }
2447
- try {
2448
- const dockerfile = await readFile5(file, "utf8");
2449
- console.log(chalk15.blue(`Building image: ${name}`));
2450
- console.log(chalk15.gray(` Dockerfile: ${file}`));
2451
- console.log();
2452
- const buildInfo = await apiClient.createImage({
2453
- dockerfile,
2454
- alias: name
2455
- });
2456
- const { imageId, buildId } = buildInfo;
2457
- console.log(chalk15.gray(` Build ID: ${buildId}`));
2458
- console.log();
2459
- let logsOffset = 0;
2460
- let status = "building";
2461
- while (status === "building") {
2462
- const statusResponse = await apiClient.get(
2463
- `/api/images/${imageId}/builds/${buildId}?logsOffset=${logsOffset}`
2424
+ var buildCommand = new Command16().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(
2425
+ async (options) => {
2426
+ const { file, name, deleteExisting } = options;
2427
+ if (!existsSync5(file)) {
2428
+ console.error(chalk15.red(`\u2717 Dockerfile not found: ${file}`));
2429
+ process.exit(1);
2430
+ }
2431
+ const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
2432
+ if (!nameRegex.test(name)) {
2433
+ console.error(
2434
+ chalk15.red(
2435
+ "\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
2436
+ )
2464
2437
  );
2465
- if (!statusResponse.ok) {
2466
- const error = await statusResponse.json();
2467
- throw new Error(
2468
- error.error?.message || "Failed to get build status"
2469
- );
2470
- }
2471
- const statusData = await statusResponse.json();
2472
- for (const log of statusData.logs) {
2473
- console.log(chalk15.gray(` ${log}`));
2474
- }
2475
- logsOffset = statusData.logsOffset;
2476
- status = statusData.status;
2477
- if (status === "building") {
2478
- await sleep(2e3);
2479
- }
2438
+ process.exit(1);
2480
2439
  }
2481
- console.log();
2482
- if (status === "ready") {
2483
- console.log(chalk15.green(`\u2713 Image built: ${name}`));
2484
- console.log();
2485
- console.log("Use in vm0.yaml:");
2486
- console.log(chalk15.cyan(` agents:`));
2487
- console.log(chalk15.cyan(` your-agent:`));
2488
- console.log(chalk15.cyan(` image: "${name}"`));
2489
- } else {
2490
- console.error(chalk15.red(`\u2717 Build failed`));
2440
+ if (name.startsWith("vm0-")) {
2441
+ console.error(
2442
+ chalk15.red(
2443
+ '\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
2444
+ )
2445
+ );
2491
2446
  process.exit(1);
2492
2447
  }
2493
- } catch (error) {
2494
- if (error instanceof Error) {
2495
- if (error.message.includes("Not authenticated")) {
2496
- console.error(chalk15.red("\u2717 Not authenticated. Run: vm0 auth login"));
2448
+ try {
2449
+ const dockerfile = await readFile5(file, "utf8");
2450
+ console.log(chalk15.blue(`Building image: ${name}`));
2451
+ console.log(chalk15.gray(` Dockerfile: ${file}`));
2452
+ console.log();
2453
+ const buildInfo = await apiClient.createImage({
2454
+ dockerfile,
2455
+ alias: name,
2456
+ deleteExisting
2457
+ });
2458
+ const { imageId, buildId } = buildInfo;
2459
+ console.log(chalk15.gray(` Build ID: ${buildId}`));
2460
+ console.log();
2461
+ let logsOffset = 0;
2462
+ let status = "building";
2463
+ while (status === "building") {
2464
+ const statusResponse = await apiClient.get(
2465
+ `/api/images/${imageId}/builds/${buildId}?logsOffset=${logsOffset}`
2466
+ );
2467
+ if (!statusResponse.ok) {
2468
+ const error = await statusResponse.json();
2469
+ throw new Error(
2470
+ error.error?.message || "Failed to get build status"
2471
+ );
2472
+ }
2473
+ const statusData = await statusResponse.json();
2474
+ for (const log of statusData.logs) {
2475
+ console.log(chalk15.gray(` ${log}`));
2476
+ }
2477
+ logsOffset = statusData.logsOffset;
2478
+ status = statusData.status;
2479
+ if (status === "building") {
2480
+ await sleep(2e3);
2481
+ }
2482
+ }
2483
+ console.log();
2484
+ if (status === "ready") {
2485
+ console.log(chalk15.green(`\u2713 Image built: ${name}`));
2486
+ console.log();
2487
+ console.log("Use in vm0.yaml:");
2488
+ console.log(chalk15.cyan(` agents:`));
2489
+ console.log(chalk15.cyan(` your-agent:`));
2490
+ console.log(chalk15.cyan(` image: "${name}"`));
2497
2491
  } else {
2498
- console.error(chalk15.red(`\u2717 ${error.message}`));
2492
+ console.error(chalk15.red(`\u2717 Build failed`));
2493
+ process.exit(1);
2499
2494
  }
2500
- } else {
2501
- console.error(chalk15.red("\u2717 An unexpected error occurred"));
2495
+ } catch (error) {
2496
+ if (error instanceof Error) {
2497
+ if (error.message.includes("Not authenticated")) {
2498
+ console.error(
2499
+ chalk15.red("\u2717 Not authenticated. Run: vm0 auth login")
2500
+ );
2501
+ } else {
2502
+ console.error(chalk15.red(`\u2717 ${error.message}`));
2503
+ }
2504
+ } else {
2505
+ console.error(chalk15.red("\u2717 An unexpected error occurred"));
2506
+ }
2507
+ process.exit(1);
2502
2508
  }
2503
- process.exit(1);
2504
2509
  }
2505
- });
2510
+ );
2506
2511
 
2507
2512
  // src/commands/image/list.ts
2508
2513
  import { Command as Command17 } from "commander";
@@ -2626,7 +2631,7 @@ var imageCommand = new Command19().name("image").description("Manage custom imag
2626
2631
 
2627
2632
  // src/index.ts
2628
2633
  var program = new Command20();
2629
- program.name("vm0").description("VM0 CLI - A modern build tool").version("4.1.0");
2634
+ program.name("vm0").description("VM0 CLI - A modern build tool").version("4.2.0");
2630
2635
  program.command("info").description("Display environment information").action(async () => {
2631
2636
  console.log(chalk18.cyan("System Information:"));
2632
2637
  console.log(`Node Version: ${process.version}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vm0/cli",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "CLI application",
5
5
  "repository": {
6
6
  "type": "git",