@vm0/cli 3.4.0 → 3.6.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 +358 -95
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -736,10 +736,10 @@ function mergeDefs(...defs) {
|
|
|
736
736
|
function cloneDef(schema) {
|
|
737
737
|
return mergeDefs(schema._zod.def);
|
|
738
738
|
}
|
|
739
|
-
function getElementAtPath(obj,
|
|
740
|
-
if (!
|
|
739
|
+
function getElementAtPath(obj, path10) {
|
|
740
|
+
if (!path10)
|
|
741
741
|
return obj;
|
|
742
|
-
return
|
|
742
|
+
return path10.reduce((acc, key) => acc?.[key], obj);
|
|
743
743
|
}
|
|
744
744
|
function promiseAllObject(promisesObj) {
|
|
745
745
|
const keys = Object.keys(promisesObj);
|
|
@@ -1098,11 +1098,11 @@ function aborted(x, startIndex = 0) {
|
|
|
1098
1098
|
}
|
|
1099
1099
|
return false;
|
|
1100
1100
|
}
|
|
1101
|
-
function prefixIssues(
|
|
1101
|
+
function prefixIssues(path10, issues) {
|
|
1102
1102
|
return issues.map((iss) => {
|
|
1103
1103
|
var _a;
|
|
1104
1104
|
(_a = iss).path ?? (_a.path = []);
|
|
1105
|
-
iss.path.unshift(
|
|
1105
|
+
iss.path.unshift(path10);
|
|
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,
|
|
1273
|
+
const processError = (error44, path10 = []) => {
|
|
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 = [...
|
|
1283
|
+
const fullpath = [...path10, ...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
|
|
1316
|
-
for (const seg of
|
|
1315
|
+
const path10 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
1316
|
+
for (const seg of path10) {
|
|
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
|
|
12151
|
-
import
|
|
12150
|
+
import { Command as Command16 } from "commander";
|
|
12151
|
+
import chalk15 from "chalk";
|
|
12152
12152
|
|
|
12153
12153
|
// src/lib/auth.ts
|
|
12154
12154
|
import chalk from "chalk";
|
|
@@ -12352,6 +12352,19 @@ var ApiClient = class {
|
|
|
12352
12352
|
}
|
|
12353
12353
|
return await response.json();
|
|
12354
12354
|
}
|
|
12355
|
+
async getComposeById(id) {
|
|
12356
|
+
const baseUrl = await this.getBaseUrl();
|
|
12357
|
+
const headers = await this.getHeaders();
|
|
12358
|
+
const response = await fetch(`${baseUrl}/api/agent/composes/${id}`, {
|
|
12359
|
+
method: "GET",
|
|
12360
|
+
headers
|
|
12361
|
+
});
|
|
12362
|
+
if (!response.ok) {
|
|
12363
|
+
const error43 = await response.json();
|
|
12364
|
+
throw new Error(error43.error?.message || `Compose not found: ${id}`);
|
|
12365
|
+
}
|
|
12366
|
+
return await response.json();
|
|
12367
|
+
}
|
|
12355
12368
|
/**
|
|
12356
12369
|
* Resolve a version specifier to a full version ID
|
|
12357
12370
|
* Supports: "latest", full hash (64 chars), or hash prefix (8+ chars)
|
|
@@ -12389,6 +12402,7 @@ var ApiClient = class {
|
|
|
12389
12402
|
/**
|
|
12390
12403
|
* Create a run with unified request format
|
|
12391
12404
|
* Supports new runs, checkpoint resume, and session continue
|
|
12405
|
+
* Note: Environment variables are expanded server-side from templateVars
|
|
12392
12406
|
*/
|
|
12393
12407
|
async createRun(body) {
|
|
12394
12408
|
const baseUrl = await this.getBaseUrl();
|
|
@@ -12439,7 +12453,7 @@ var ApiClient = class {
|
|
|
12439
12453
|
/**
|
|
12440
12454
|
* Generic GET request
|
|
12441
12455
|
*/
|
|
12442
|
-
async get(
|
|
12456
|
+
async get(path10) {
|
|
12443
12457
|
const baseUrl = await this.getBaseUrl();
|
|
12444
12458
|
const token = await getToken();
|
|
12445
12459
|
if (!token) {
|
|
@@ -12452,7 +12466,7 @@ var ApiClient = class {
|
|
|
12452
12466
|
if (bypassSecret) {
|
|
12453
12467
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
12454
12468
|
}
|
|
12455
|
-
return fetch(`${baseUrl}${
|
|
12469
|
+
return fetch(`${baseUrl}${path10}`, {
|
|
12456
12470
|
method: "GET",
|
|
12457
12471
|
headers
|
|
12458
12472
|
});
|
|
@@ -12460,7 +12474,7 @@ var ApiClient = class {
|
|
|
12460
12474
|
/**
|
|
12461
12475
|
* Generic POST request
|
|
12462
12476
|
*/
|
|
12463
|
-
async post(
|
|
12477
|
+
async post(path10, options) {
|
|
12464
12478
|
const baseUrl = await this.getBaseUrl();
|
|
12465
12479
|
const token = await getToken();
|
|
12466
12480
|
if (!token) {
|
|
@@ -12473,12 +12487,33 @@ var ApiClient = class {
|
|
|
12473
12487
|
if (bypassSecret) {
|
|
12474
12488
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
12475
12489
|
}
|
|
12476
|
-
return fetch(`${baseUrl}${
|
|
12490
|
+
return fetch(`${baseUrl}${path10}`, {
|
|
12477
12491
|
method: "POST",
|
|
12478
12492
|
headers,
|
|
12479
12493
|
body: options?.body
|
|
12480
12494
|
});
|
|
12481
12495
|
}
|
|
12496
|
+
/**
|
|
12497
|
+
* Generic DELETE request
|
|
12498
|
+
*/
|
|
12499
|
+
async delete(path10) {
|
|
12500
|
+
const baseUrl = await this.getBaseUrl();
|
|
12501
|
+
const token = await getToken();
|
|
12502
|
+
if (!token) {
|
|
12503
|
+
throw new Error("Not authenticated. Run: vm0 auth login");
|
|
12504
|
+
}
|
|
12505
|
+
const headers = {
|
|
12506
|
+
Authorization: `Bearer ${token}`
|
|
12507
|
+
};
|
|
12508
|
+
const bypassSecret = process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
|
|
12509
|
+
if (bypassSecret) {
|
|
12510
|
+
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
12511
|
+
}
|
|
12512
|
+
return fetch(`${baseUrl}${path10}`, {
|
|
12513
|
+
method: "DELETE",
|
|
12514
|
+
headers
|
|
12515
|
+
});
|
|
12516
|
+
}
|
|
12482
12517
|
};
|
|
12483
12518
|
var apiClient = new ApiClient();
|
|
12484
12519
|
|
|
@@ -12560,6 +12595,23 @@ function validateAgentCompose(config2) {
|
|
|
12560
12595
|
error: "Missing or invalid agent.provider (must be a string)"
|
|
12561
12596
|
};
|
|
12562
12597
|
}
|
|
12598
|
+
if (agent.environment !== void 0) {
|
|
12599
|
+
if (agent.environment === null || typeof agent.environment !== "object" || Array.isArray(agent.environment)) {
|
|
12600
|
+
return {
|
|
12601
|
+
valid: false,
|
|
12602
|
+
error: "agent.environment must be an object with string keys and values"
|
|
12603
|
+
};
|
|
12604
|
+
}
|
|
12605
|
+
const env = agent.environment;
|
|
12606
|
+
for (const [key, value] of Object.entries(env)) {
|
|
12607
|
+
if (typeof value !== "string") {
|
|
12608
|
+
return {
|
|
12609
|
+
valid: false,
|
|
12610
|
+
error: `agent.environment.${key} must be a string`
|
|
12611
|
+
};
|
|
12612
|
+
}
|
|
12613
|
+
}
|
|
12614
|
+
}
|
|
12563
12615
|
const agentVolumes = agent.volumes;
|
|
12564
12616
|
if (agentVolumes && Array.isArray(agentVolumes) && agentVolumes.length > 0) {
|
|
12565
12617
|
const volumesSection = cfg.volumes;
|
|
@@ -12600,62 +12652,6 @@ function validateAgentCompose(config2) {
|
|
|
12600
12652
|
return { valid: true };
|
|
12601
12653
|
}
|
|
12602
12654
|
|
|
12603
|
-
// src/lib/env-expander.ts
|
|
12604
|
-
function expandEnvVars(value) {
|
|
12605
|
-
return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
|
|
12606
|
-
return process.env[varName] ?? "";
|
|
12607
|
-
});
|
|
12608
|
-
}
|
|
12609
|
-
function extractEnvVarReferences(obj) {
|
|
12610
|
-
const varNames = /* @__PURE__ */ new Set();
|
|
12611
|
-
function scan(value) {
|
|
12612
|
-
if (typeof value === "string") {
|
|
12613
|
-
const matches = value.matchAll(/\$\{([^}]+)\}/g);
|
|
12614
|
-
for (const match of matches) {
|
|
12615
|
-
const varName = match[1];
|
|
12616
|
-
if (varName) {
|
|
12617
|
-
varNames.add(varName);
|
|
12618
|
-
}
|
|
12619
|
-
}
|
|
12620
|
-
} else if (Array.isArray(value)) {
|
|
12621
|
-
for (const item of value) {
|
|
12622
|
-
scan(item);
|
|
12623
|
-
}
|
|
12624
|
-
} else if (value !== null && typeof value === "object") {
|
|
12625
|
-
for (const val of Object.values(value)) {
|
|
12626
|
-
scan(val);
|
|
12627
|
-
}
|
|
12628
|
-
}
|
|
12629
|
-
}
|
|
12630
|
-
scan(obj);
|
|
12631
|
-
return Array.from(varNames);
|
|
12632
|
-
}
|
|
12633
|
-
function validateEnvVars(varNames) {
|
|
12634
|
-
const missing = [];
|
|
12635
|
-
for (const varName of varNames) {
|
|
12636
|
-
if (process.env[varName] === void 0) {
|
|
12637
|
-
missing.push(varName);
|
|
12638
|
-
}
|
|
12639
|
-
}
|
|
12640
|
-
return missing;
|
|
12641
|
-
}
|
|
12642
|
-
function expandEnvVarsInObject(obj) {
|
|
12643
|
-
if (typeof obj === "string") {
|
|
12644
|
-
return expandEnvVars(obj);
|
|
12645
|
-
}
|
|
12646
|
-
if (Array.isArray(obj)) {
|
|
12647
|
-
return obj.map((item) => expandEnvVarsInObject(item));
|
|
12648
|
-
}
|
|
12649
|
-
if (obj !== null && typeof obj === "object") {
|
|
12650
|
-
const result = {};
|
|
12651
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
12652
|
-
result[key] = expandEnvVarsInObject(value);
|
|
12653
|
-
}
|
|
12654
|
-
return result;
|
|
12655
|
-
}
|
|
12656
|
-
return obj;
|
|
12657
|
-
}
|
|
12658
|
-
|
|
12659
12655
|
// src/commands/build.ts
|
|
12660
12656
|
var buildCommand = new Command().name("build").description("Create or update agent compose").argument("<config-file>", "Path to config YAML file").action(async (configFile) => {
|
|
12661
12657
|
try {
|
|
@@ -12674,24 +12670,6 @@ var buildCommand = new Command().name("build").description("Create or update age
|
|
|
12674
12670
|
}
|
|
12675
12671
|
process.exit(1);
|
|
12676
12672
|
}
|
|
12677
|
-
const referencedVars = extractEnvVarReferences(config2);
|
|
12678
|
-
const missingVars = validateEnvVars(referencedVars);
|
|
12679
|
-
if (missingVars.length > 0) {
|
|
12680
|
-
console.error(chalk2.red("\u2717 Missing required environment variables:"));
|
|
12681
|
-
for (const varName of missingVars) {
|
|
12682
|
-
console.error(chalk2.red(` - ${varName}`));
|
|
12683
|
-
}
|
|
12684
|
-
console.error();
|
|
12685
|
-
console.error(
|
|
12686
|
-
chalk2.gray("Please set these variables before running 'vm0 build'.")
|
|
12687
|
-
);
|
|
12688
|
-
console.error(chalk2.gray("Example:"));
|
|
12689
|
-
for (const varName of missingVars) {
|
|
12690
|
-
console.error(chalk2.gray(` export ${varName}=your-value`));
|
|
12691
|
-
}
|
|
12692
|
-
process.exit(1);
|
|
12693
|
-
}
|
|
12694
|
-
config2 = expandEnvVarsInObject(config2);
|
|
12695
12673
|
const validation = validateAgentCompose(config2);
|
|
12696
12674
|
if (!validation.valid) {
|
|
12697
12675
|
console.error(chalk2.red(`\u2717 ${validation.error}`));
|
|
@@ -13246,7 +13224,7 @@ var runCmd = new Command2().name("run").description("Execute an agent").argument
|
|
|
13246
13224
|
if (isUUID(name)) {
|
|
13247
13225
|
composeId = name;
|
|
13248
13226
|
if (verbose) {
|
|
13249
|
-
console.log(chalk4.gray(` Using compose ID: ${
|
|
13227
|
+
console.log(chalk4.gray(` Using compose ID: ${identifier}`));
|
|
13250
13228
|
}
|
|
13251
13229
|
} else {
|
|
13252
13230
|
if (verbose) {
|
|
@@ -14204,15 +14182,298 @@ var pullCommand2 = new Command9().name("pull").description("Pull cloud artifact
|
|
|
14204
14182
|
// src/commands/artifact/index.ts
|
|
14205
14183
|
var artifactCommand = new Command10().name("artifact").description("Manage cloud artifacts (work products)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2);
|
|
14206
14184
|
|
|
14185
|
+
// src/commands/secret/index.ts
|
|
14186
|
+
import { Command as Command14 } from "commander";
|
|
14187
|
+
|
|
14188
|
+
// src/commands/secret/set.ts
|
|
14189
|
+
import { Command as Command11 } from "commander";
|
|
14190
|
+
import chalk11 from "chalk";
|
|
14191
|
+
var setCommand = new Command11().name("set").description("Create or update a secret").argument(
|
|
14192
|
+
"<name>",
|
|
14193
|
+
"Secret name (must start with letter, alphanumeric and underscores only)"
|
|
14194
|
+
).argument("<value>", "Secret value").action(async (name, value) => {
|
|
14195
|
+
try {
|
|
14196
|
+
const nameRegex = /^[a-zA-Z][a-zA-Z0-9_]*$/;
|
|
14197
|
+
if (!nameRegex.test(name)) {
|
|
14198
|
+
console.error(chalk11.red("\u2717 Invalid secret name"));
|
|
14199
|
+
console.error(
|
|
14200
|
+
chalk11.gray(
|
|
14201
|
+
" Must start with a letter and contain only letters, numbers, and underscores"
|
|
14202
|
+
)
|
|
14203
|
+
);
|
|
14204
|
+
process.exit(1);
|
|
14205
|
+
}
|
|
14206
|
+
if (name.length > 255) {
|
|
14207
|
+
console.error(chalk11.red("\u2717 Secret name too long (max 255 characters)"));
|
|
14208
|
+
process.exit(1);
|
|
14209
|
+
}
|
|
14210
|
+
const response = await apiClient.post("/api/secrets", {
|
|
14211
|
+
body: JSON.stringify({ name, value })
|
|
14212
|
+
});
|
|
14213
|
+
if (!response.ok) {
|
|
14214
|
+
const error43 = await response.json();
|
|
14215
|
+
throw new Error(error43.error?.message || "Failed to set secret");
|
|
14216
|
+
}
|
|
14217
|
+
const result = await response.json();
|
|
14218
|
+
if (result.action === "created") {
|
|
14219
|
+
console.log(chalk11.green(`\u2713 Secret created: ${name}`));
|
|
14220
|
+
} else {
|
|
14221
|
+
console.log(chalk11.green(`\u2713 Secret updated: ${name}`));
|
|
14222
|
+
}
|
|
14223
|
+
} catch (error43) {
|
|
14224
|
+
console.error(chalk11.red("\u2717 Failed to set secret"));
|
|
14225
|
+
if (error43 instanceof Error) {
|
|
14226
|
+
console.error(chalk11.gray(` ${error43.message}`));
|
|
14227
|
+
}
|
|
14228
|
+
process.exit(1);
|
|
14229
|
+
}
|
|
14230
|
+
});
|
|
14231
|
+
|
|
14232
|
+
// src/commands/secret/list.ts
|
|
14233
|
+
import { Command as Command12 } from "commander";
|
|
14234
|
+
import chalk12 from "chalk";
|
|
14235
|
+
var listCommand = new Command12().name("list").alias("ls").description("List all secrets (names only)").action(async () => {
|
|
14236
|
+
try {
|
|
14237
|
+
const response = await apiClient.get("/api/secrets");
|
|
14238
|
+
if (!response.ok) {
|
|
14239
|
+
const error43 = await response.json();
|
|
14240
|
+
throw new Error(error43.error?.message || "Failed to list secrets");
|
|
14241
|
+
}
|
|
14242
|
+
const result = await response.json();
|
|
14243
|
+
if (result.secrets.length === 0) {
|
|
14244
|
+
console.log(chalk12.gray("No secrets found"));
|
|
14245
|
+
console.log(
|
|
14246
|
+
chalk12.gray(" Create one with: vm0 secret set <name> <value>")
|
|
14247
|
+
);
|
|
14248
|
+
return;
|
|
14249
|
+
}
|
|
14250
|
+
console.log(chalk12.cyan("Secrets:"));
|
|
14251
|
+
for (const secret of result.secrets) {
|
|
14252
|
+
const updatedAt = new Date(secret.updatedAt).toLocaleDateString();
|
|
14253
|
+
console.log(
|
|
14254
|
+
` ${chalk12.white(secret.name)} ${chalk12.gray(`(updated: ${updatedAt})`)}`
|
|
14255
|
+
);
|
|
14256
|
+
}
|
|
14257
|
+
console.log(chalk12.gray(`
|
|
14258
|
+
Total: ${result.secrets.length} secret(s)`));
|
|
14259
|
+
} catch (error43) {
|
|
14260
|
+
console.error(chalk12.red("\u2717 Failed to list secrets"));
|
|
14261
|
+
if (error43 instanceof Error) {
|
|
14262
|
+
console.error(chalk12.gray(` ${error43.message}`));
|
|
14263
|
+
}
|
|
14264
|
+
process.exit(1);
|
|
14265
|
+
}
|
|
14266
|
+
});
|
|
14267
|
+
|
|
14268
|
+
// src/commands/secret/delete.ts
|
|
14269
|
+
import { Command as Command13 } from "commander";
|
|
14270
|
+
import chalk13 from "chalk";
|
|
14271
|
+
var deleteCommand = new Command13().name("delete").alias("rm").description("Delete a secret").argument("<name>", "Secret name to delete").action(async (name) => {
|
|
14272
|
+
try {
|
|
14273
|
+
const response = await apiClient.delete(
|
|
14274
|
+
`/api/secrets?name=${encodeURIComponent(name)}`
|
|
14275
|
+
);
|
|
14276
|
+
if (!response.ok) {
|
|
14277
|
+
const error43 = await response.json();
|
|
14278
|
+
throw new Error(error43.error?.message || `Secret not found: ${name}`);
|
|
14279
|
+
}
|
|
14280
|
+
const result = await response.json();
|
|
14281
|
+
if (result.deleted) {
|
|
14282
|
+
console.log(chalk13.green(`\u2713 Secret deleted: ${name}`));
|
|
14283
|
+
}
|
|
14284
|
+
} catch (error43) {
|
|
14285
|
+
console.error(chalk13.red("\u2717 Failed to delete secret"));
|
|
14286
|
+
if (error43 instanceof Error) {
|
|
14287
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
14288
|
+
}
|
|
14289
|
+
process.exit(1);
|
|
14290
|
+
}
|
|
14291
|
+
});
|
|
14292
|
+
|
|
14293
|
+
// src/commands/secret/index.ts
|
|
14294
|
+
var secretCommand = new Command14().name("secret").description("Manage secrets for agent compose configurations").addCommand(setCommand).addCommand(listCommand).addCommand(deleteCommand);
|
|
14295
|
+
|
|
14296
|
+
// src/commands/cook.ts
|
|
14297
|
+
import { Command as Command15 } from "commander";
|
|
14298
|
+
import chalk14 from "chalk";
|
|
14299
|
+
import { readFile as readFile4, mkdir as mkdir3 } from "fs/promises";
|
|
14300
|
+
import { existsSync as existsSync4 } from "fs";
|
|
14301
|
+
import path9 from "path";
|
|
14302
|
+
import { spawn } from "child_process";
|
|
14303
|
+
import { parse as parseYaml3 } from "yaml";
|
|
14304
|
+
var CONFIG_FILE3 = "vm0.yaml";
|
|
14305
|
+
var ARTIFACT_DIR = "artifact";
|
|
14306
|
+
function execVm0Command(args, options = {}) {
|
|
14307
|
+
return new Promise((resolve, reject) => {
|
|
14308
|
+
const proc = spawn("vm0", args, {
|
|
14309
|
+
cwd: options.cwd,
|
|
14310
|
+
stdio: options.silent ? "pipe" : ["inherit", "inherit", "inherit"],
|
|
14311
|
+
shell: process.platform === "win32"
|
|
14312
|
+
});
|
|
14313
|
+
let stdout = "";
|
|
14314
|
+
let stderr = "";
|
|
14315
|
+
if (options.silent) {
|
|
14316
|
+
proc.stdout?.on("data", (data) => {
|
|
14317
|
+
stdout += data.toString();
|
|
14318
|
+
});
|
|
14319
|
+
proc.stderr?.on("data", (data) => {
|
|
14320
|
+
stderr += data.toString();
|
|
14321
|
+
});
|
|
14322
|
+
}
|
|
14323
|
+
proc.on("close", (code) => {
|
|
14324
|
+
if (code === 0) {
|
|
14325
|
+
resolve(stdout);
|
|
14326
|
+
} else {
|
|
14327
|
+
reject(new Error(stderr || `Command failed with exit code ${code}`));
|
|
14328
|
+
}
|
|
14329
|
+
});
|
|
14330
|
+
proc.on("error", (err) => {
|
|
14331
|
+
reject(err);
|
|
14332
|
+
});
|
|
14333
|
+
});
|
|
14334
|
+
}
|
|
14335
|
+
var cookCommand = new Command15().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
14336
|
+
const cwd = process.cwd();
|
|
14337
|
+
console.log(chalk14.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
14338
|
+
if (!existsSync4(CONFIG_FILE3)) {
|
|
14339
|
+
console.error(chalk14.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
14340
|
+
process.exit(1);
|
|
14341
|
+
}
|
|
14342
|
+
let config2;
|
|
14343
|
+
try {
|
|
14344
|
+
const content = await readFile4(CONFIG_FILE3, "utf8");
|
|
14345
|
+
config2 = parseYaml3(content);
|
|
14346
|
+
} catch (error43) {
|
|
14347
|
+
console.error(chalk14.red("\u2717 Invalid YAML format"));
|
|
14348
|
+
if (error43 instanceof Error) {
|
|
14349
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
14350
|
+
}
|
|
14351
|
+
process.exit(1);
|
|
14352
|
+
}
|
|
14353
|
+
const validation = validateAgentCompose(config2);
|
|
14354
|
+
if (!validation.valid) {
|
|
14355
|
+
console.error(chalk14.red(`\u2717 ${validation.error}`));
|
|
14356
|
+
process.exit(1);
|
|
14357
|
+
}
|
|
14358
|
+
const agentNames = Object.keys(config2.agents);
|
|
14359
|
+
const agentName = agentNames[0];
|
|
14360
|
+
const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
|
|
14361
|
+
console.log(
|
|
14362
|
+
chalk14.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
14363
|
+
);
|
|
14364
|
+
if (config2.volumes && Object.keys(config2.volumes).length > 0) {
|
|
14365
|
+
console.log();
|
|
14366
|
+
console.log(chalk14.blue("Processing volumes..."));
|
|
14367
|
+
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
14368
|
+
const volumeDir = path9.join(cwd, volumeConfig.name);
|
|
14369
|
+
console.log(chalk14.gray(` ${volumeConfig.name}/`));
|
|
14370
|
+
if (!existsSync4(volumeDir)) {
|
|
14371
|
+
console.error(
|
|
14372
|
+
chalk14.red(
|
|
14373
|
+
` \u2717 Directory not found. Create the directory and add files first.`
|
|
14374
|
+
)
|
|
14375
|
+
);
|
|
14376
|
+
process.exit(1);
|
|
14377
|
+
}
|
|
14378
|
+
try {
|
|
14379
|
+
const existingConfig = await readStorageConfig(volumeDir);
|
|
14380
|
+
if (!existingConfig) {
|
|
14381
|
+
await execVm0Command(["volume", "init"], {
|
|
14382
|
+
cwd: volumeDir,
|
|
14383
|
+
silent: true
|
|
14384
|
+
});
|
|
14385
|
+
console.log(chalk14.green(` \u2713 Initialized`));
|
|
14386
|
+
}
|
|
14387
|
+
await execVm0Command(["volume", "push"], {
|
|
14388
|
+
cwd: volumeDir,
|
|
14389
|
+
silent: true
|
|
14390
|
+
});
|
|
14391
|
+
console.log(chalk14.green(` \u2713 Pushed`));
|
|
14392
|
+
} catch (error43) {
|
|
14393
|
+
console.error(chalk14.red(` \u2717 Failed`));
|
|
14394
|
+
if (error43 instanceof Error) {
|
|
14395
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
14396
|
+
}
|
|
14397
|
+
process.exit(1);
|
|
14398
|
+
}
|
|
14399
|
+
}
|
|
14400
|
+
}
|
|
14401
|
+
console.log();
|
|
14402
|
+
console.log(chalk14.blue("Processing artifact..."));
|
|
14403
|
+
const artifactDir = path9.join(cwd, ARTIFACT_DIR);
|
|
14404
|
+
console.log(chalk14.gray(` ${ARTIFACT_DIR}/`));
|
|
14405
|
+
try {
|
|
14406
|
+
if (!existsSync4(artifactDir)) {
|
|
14407
|
+
await mkdir3(artifactDir, { recursive: true });
|
|
14408
|
+
console.log(chalk14.green(` \u2713 Created directory`));
|
|
14409
|
+
}
|
|
14410
|
+
const existingConfig = await readStorageConfig(artifactDir);
|
|
14411
|
+
if (!existingConfig) {
|
|
14412
|
+
await execVm0Command(["artifact", "init"], {
|
|
14413
|
+
cwd: artifactDir,
|
|
14414
|
+
silent: true
|
|
14415
|
+
});
|
|
14416
|
+
console.log(chalk14.green(` \u2713 Initialized`));
|
|
14417
|
+
}
|
|
14418
|
+
await execVm0Command(["artifact", "push"], {
|
|
14419
|
+
cwd: artifactDir,
|
|
14420
|
+
silent: true
|
|
14421
|
+
});
|
|
14422
|
+
console.log(chalk14.green(` \u2713 Pushed`));
|
|
14423
|
+
} catch (error43) {
|
|
14424
|
+
console.error(chalk14.red(` \u2717 Failed`));
|
|
14425
|
+
if (error43 instanceof Error) {
|
|
14426
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
14427
|
+
}
|
|
14428
|
+
process.exit(1);
|
|
14429
|
+
}
|
|
14430
|
+
console.log();
|
|
14431
|
+
console.log(chalk14.blue("Building compose..."));
|
|
14432
|
+
try {
|
|
14433
|
+
await execVm0Command(["build", CONFIG_FILE3], {
|
|
14434
|
+
cwd,
|
|
14435
|
+
silent: true
|
|
14436
|
+
});
|
|
14437
|
+
console.log(chalk14.green(`\u2713 Compose built: ${agentName}`));
|
|
14438
|
+
} catch (error43) {
|
|
14439
|
+
console.error(chalk14.red(`\u2717 Build failed`));
|
|
14440
|
+
if (error43 instanceof Error) {
|
|
14441
|
+
console.error(chalk14.gray(` ${error43.message}`));
|
|
14442
|
+
}
|
|
14443
|
+
process.exit(1);
|
|
14444
|
+
}
|
|
14445
|
+
if (prompt) {
|
|
14446
|
+
console.log();
|
|
14447
|
+
console.log(chalk14.blue(`Running agent: ${agentName}`));
|
|
14448
|
+
console.log();
|
|
14449
|
+
try {
|
|
14450
|
+
await execVm0Command(
|
|
14451
|
+
["run", agentName, "--artifact-name", ARTIFACT_DIR, prompt],
|
|
14452
|
+
{ cwd, silent: false }
|
|
14453
|
+
);
|
|
14454
|
+
} catch {
|
|
14455
|
+
process.exit(1);
|
|
14456
|
+
}
|
|
14457
|
+
} else {
|
|
14458
|
+
console.log();
|
|
14459
|
+
console.log(" Run your agent:");
|
|
14460
|
+
console.log(
|
|
14461
|
+
chalk14.cyan(
|
|
14462
|
+
` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
|
|
14463
|
+
)
|
|
14464
|
+
);
|
|
14465
|
+
}
|
|
14466
|
+
});
|
|
14467
|
+
|
|
14207
14468
|
// src/index.ts
|
|
14208
|
-
var program = new
|
|
14209
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("3.
|
|
14469
|
+
var program = new Command16();
|
|
14470
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("3.6.0");
|
|
14210
14471
|
program.command("hello").description("Say hello from the App").action(() => {
|
|
14211
|
-
console.log(
|
|
14212
|
-
console.log(
|
|
14472
|
+
console.log(chalk15.blue("Welcome to the VM0 CLI!"));
|
|
14473
|
+
console.log(chalk15.green(`Core says: ${FOO}`));
|
|
14213
14474
|
});
|
|
14214
14475
|
program.command("info").description("Display environment information").action(async () => {
|
|
14215
|
-
console.log(
|
|
14476
|
+
console.log(chalk15.cyan("System Information:"));
|
|
14216
14477
|
console.log(`Node Version: ${process.version}`);
|
|
14217
14478
|
console.log(`Platform: ${process.platform}`);
|
|
14218
14479
|
console.log(`Architecture: ${process.arch}`);
|
|
@@ -14233,6 +14494,8 @@ program.addCommand(buildCommand);
|
|
|
14233
14494
|
program.addCommand(runCommand);
|
|
14234
14495
|
program.addCommand(volumeCommand);
|
|
14235
14496
|
program.addCommand(artifactCommand);
|
|
14497
|
+
program.addCommand(secretCommand);
|
|
14498
|
+
program.addCommand(cookCommand);
|
|
14236
14499
|
if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
|
|
14237
14500
|
program.parse();
|
|
14238
14501
|
}
|