@vm0/cli 4.17.0 → 4.19.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.
- package/index.js +64 -15
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -13255,9 +13255,9 @@ var createImageRequestSchema = external_exports.object({
|
|
|
13255
13255
|
/^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/,
|
|
13256
13256
|
"alias must be 3-64 characters, alphanumeric and hyphens, start/end with alphanumeric"
|
|
13257
13257
|
).refine(
|
|
13258
|
-
(val) => !val.startsWith("vm0-"),
|
|
13258
|
+
(val) => !val.toLowerCase().startsWith("vm0-"),
|
|
13259
13259
|
'alias cannot start with "vm0-" (reserved for system templates)'
|
|
13260
|
-
),
|
|
13260
|
+
).transform((s) => s.toLowerCase()),
|
|
13261
13261
|
deleteExisting: external_exports.boolean().optional()
|
|
13262
13262
|
});
|
|
13263
13263
|
var createImageResponseSchema = external_exports.object({
|
|
@@ -13487,10 +13487,10 @@ function getLegacySystemTemplateWarning(legacyFormat) {
|
|
|
13487
13487
|
return void 0;
|
|
13488
13488
|
}
|
|
13489
13489
|
if (legacyFormat === "vm0-claude-code") {
|
|
13490
|
-
return `Warning: "${legacyFormat}" format is deprecated. Use "
|
|
13490
|
+
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/claude-code" instead.`;
|
|
13491
13491
|
}
|
|
13492
13492
|
if (legacyFormat === "vm0-claude-code-dev") {
|
|
13493
|
-
return `Warning: "${legacyFormat}" format is deprecated. Use "
|
|
13493
|
+
return `Warning: "${legacyFormat}" format is deprecated. Use "vm0/claude-code:dev" instead.`;
|
|
13494
13494
|
}
|
|
13495
13495
|
if (legacyFormat.startsWith("vm0-github-cli")) {
|
|
13496
13496
|
return `Warning: "${legacyFormat}" is deprecated and will be removed. No replacement available.`;
|
|
@@ -16294,7 +16294,7 @@ async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
|
16294
16294
|
}
|
|
16295
16295
|
}
|
|
16296
16296
|
var cookCommand = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
16297
|
-
const shouldExit = await checkAndUpgrade("4.
|
|
16297
|
+
const shouldExit = await checkAndUpgrade("4.19.0", prompt);
|
|
16298
16298
|
if (shouldExit) {
|
|
16299
16299
|
process.exit(0);
|
|
16300
16300
|
}
|
|
@@ -16481,6 +16481,38 @@ import { Command as Command14 } from "commander";
|
|
|
16481
16481
|
import chalk16 from "chalk";
|
|
16482
16482
|
import { readFile as readFile6 } from "fs/promises";
|
|
16483
16483
|
import { existsSync as existsSync7 } from "fs";
|
|
16484
|
+
|
|
16485
|
+
// src/lib/dockerfile-validator.ts
|
|
16486
|
+
var ALLOWED_INSTRUCTIONS = /* @__PURE__ */ new Set(["FROM", "RUN"]);
|
|
16487
|
+
function validateDockerfile(content) {
|
|
16488
|
+
const errors = [];
|
|
16489
|
+
const lines = content.split("\n");
|
|
16490
|
+
let inContinuation = false;
|
|
16491
|
+
for (let i = 0; i < lines.length; i++) {
|
|
16492
|
+
const line = lines[i];
|
|
16493
|
+
const trimmed = line.trim();
|
|
16494
|
+
if (!inContinuation && !trimmed) continue;
|
|
16495
|
+
if (!inContinuation && trimmed.startsWith("#")) continue;
|
|
16496
|
+
if (inContinuation) {
|
|
16497
|
+
inContinuation = trimmed.endsWith("\\");
|
|
16498
|
+
continue;
|
|
16499
|
+
}
|
|
16500
|
+
const match = trimmed.match(/^([A-Za-z]+)\s/);
|
|
16501
|
+
if (match) {
|
|
16502
|
+
const instruction = match[1].toUpperCase();
|
|
16503
|
+
if (!ALLOWED_INSTRUCTIONS.has(instruction)) {
|
|
16504
|
+
errors.push(`Unsupported instruction: ${instruction} (line ${i + 1})`);
|
|
16505
|
+
}
|
|
16506
|
+
}
|
|
16507
|
+
inContinuation = trimmed.endsWith("\\");
|
|
16508
|
+
}
|
|
16509
|
+
return {
|
|
16510
|
+
valid: errors.length === 0,
|
|
16511
|
+
errors
|
|
16512
|
+
};
|
|
16513
|
+
}
|
|
16514
|
+
|
|
16515
|
+
// src/commands/image/build.ts
|
|
16484
16516
|
var sleep2 = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
16485
16517
|
var buildCommand = new Command14().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(
|
|
16486
16518
|
async (options) => {
|
|
@@ -16509,7 +16541,26 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16509
16541
|
try {
|
|
16510
16542
|
const scope = await apiClient.getScope();
|
|
16511
16543
|
const dockerfile = await readFile6(file2, "utf8");
|
|
16512
|
-
|
|
16544
|
+
const validation = validateDockerfile(dockerfile);
|
|
16545
|
+
if (!validation.valid) {
|
|
16546
|
+
console.error(chalk16.red("\u2717 Dockerfile validation failed\n"));
|
|
16547
|
+
for (const error43 of validation.errors) {
|
|
16548
|
+
console.error(chalk16.red(` ${error43}`));
|
|
16549
|
+
}
|
|
16550
|
+
console.error();
|
|
16551
|
+
console.error(
|
|
16552
|
+
chalk16.yellow(
|
|
16553
|
+
" vm0 image build only supports FROM and RUN instructions."
|
|
16554
|
+
)
|
|
16555
|
+
);
|
|
16556
|
+
console.error(
|
|
16557
|
+
chalk16.yellow(
|
|
16558
|
+
" The purpose is to pre-install environment dependencies."
|
|
16559
|
+
)
|
|
16560
|
+
);
|
|
16561
|
+
process.exit(1);
|
|
16562
|
+
}
|
|
16563
|
+
console.log(chalk16.blue(`Building image: ${scope.slug}/${name}`));
|
|
16513
16564
|
console.log();
|
|
16514
16565
|
const buildInfo = await apiClient.createImage({
|
|
16515
16566
|
dockerfile,
|
|
@@ -16545,9 +16596,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16545
16596
|
if (status === "ready") {
|
|
16546
16597
|
const shortVersion = formatVersionIdForDisplay(versionId);
|
|
16547
16598
|
console.log(
|
|
16548
|
-
chalk16.green(
|
|
16549
|
-
`\u2713 Image built: @${scope.slug}/${name}:${shortVersion}`
|
|
16550
|
-
)
|
|
16599
|
+
chalk16.green(`\u2713 Image built: ${scope.slug}/${name}:${shortVersion}`)
|
|
16551
16600
|
);
|
|
16552
16601
|
} else {
|
|
16553
16602
|
console.error(chalk16.red(`\u2717 Build failed`));
|
|
@@ -17074,7 +17123,7 @@ var statusCommand3 = new Command20().name("status").description("View current sc
|
|
|
17074
17123
|
try {
|
|
17075
17124
|
const scope = await apiClient.getScope();
|
|
17076
17125
|
console.log(chalk21.cyan("Scope Information:"));
|
|
17077
|
-
console.log(` Slug: ${chalk21.green(
|
|
17126
|
+
console.log(` Slug: ${chalk21.green(scope.slug)}`);
|
|
17078
17127
|
console.log(` Type: ${scope.type}`);
|
|
17079
17128
|
if (scope.displayName) {
|
|
17080
17129
|
console.log(` Display Name: ${scope.displayName}`);
|
|
@@ -17119,7 +17168,7 @@ var setCommand = new Command21().name("set").description("Set your scope slug").
|
|
|
17119
17168
|
if (existingScope) {
|
|
17120
17169
|
if (!options.force) {
|
|
17121
17170
|
console.error(
|
|
17122
|
-
chalk22.yellow(`You already have a scope:
|
|
17171
|
+
chalk22.yellow(`You already have a scope: ${existingScope.slug}`)
|
|
17123
17172
|
);
|
|
17124
17173
|
console.error();
|
|
17125
17174
|
console.error("To change your scope, use --force:");
|
|
@@ -17133,17 +17182,17 @@ var setCommand = new Command21().name("set").description("Set your scope slug").
|
|
|
17133
17182
|
process.exit(1);
|
|
17134
17183
|
}
|
|
17135
17184
|
scope = await apiClient.updateScope({ slug, force: true });
|
|
17136
|
-
console.log(chalk22.green(`\u2713 Scope updated to
|
|
17185
|
+
console.log(chalk22.green(`\u2713 Scope updated to ${scope.slug}`));
|
|
17137
17186
|
} else {
|
|
17138
17187
|
scope = await apiClient.createScope({
|
|
17139
17188
|
slug,
|
|
17140
17189
|
displayName: options.displayName
|
|
17141
17190
|
});
|
|
17142
|
-
console.log(chalk22.green(`\u2713 Scope created:
|
|
17191
|
+
console.log(chalk22.green(`\u2713 Scope created: ${scope.slug}`));
|
|
17143
17192
|
}
|
|
17144
17193
|
console.log();
|
|
17145
17194
|
console.log("Your images will now be namespaced as:");
|
|
17146
|
-
console.log(chalk22.cyan(`
|
|
17195
|
+
console.log(chalk22.cyan(` ${scope.slug}/<image-name>`));
|
|
17147
17196
|
} catch (error43) {
|
|
17148
17197
|
if (error43 instanceof Error) {
|
|
17149
17198
|
if (error43.message.includes("Not authenticated")) {
|
|
@@ -17180,7 +17229,7 @@ var scopeCommand = new Command22().name("scope").description("Manage your scope
|
|
|
17180
17229
|
|
|
17181
17230
|
// src/index.ts
|
|
17182
17231
|
var program = new Command23();
|
|
17183
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
17232
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.19.0");
|
|
17184
17233
|
program.command("info").description("Display environment information").action(async () => {
|
|
17185
17234
|
console.log(chalk23.cyan("System Information:"));
|
|
17186
17235
|
console.log(`Node Version: ${process.version}`);
|