@vm0/cli 9.5.0 → 9.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 +270 -236
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1878,7 +1878,7 @@ var credentialsByNameContract = c10.router({
|
|
|
1878
1878
|
name: credentialNameSchema
|
|
1879
1879
|
}),
|
|
1880
1880
|
responses: {
|
|
1881
|
-
204:
|
|
1881
|
+
204: c10.noBody(),
|
|
1882
1882
|
401: apiErrorSchema,
|
|
1883
1883
|
404: apiErrorSchema,
|
|
1884
1884
|
500: apiErrorSchema
|
|
@@ -1990,7 +1990,7 @@ var modelProvidersByTypeContract = c11.router({
|
|
|
1990
1990
|
type: modelProviderTypeSchema
|
|
1991
1991
|
}),
|
|
1992
1992
|
responses: {
|
|
1993
|
-
204:
|
|
1993
|
+
204: c11.noBody(),
|
|
1994
1994
|
401: apiErrorSchema,
|
|
1995
1995
|
404: apiErrorSchema,
|
|
1996
1996
|
500: apiErrorSchema
|
|
@@ -2275,7 +2275,7 @@ var schedulesByNameContract = c13.router({
|
|
|
2275
2275
|
composeId: z16.string().uuid("Compose ID required")
|
|
2276
2276
|
}),
|
|
2277
2277
|
responses: {
|
|
2278
|
-
204:
|
|
2278
|
+
204: c13.noBody(),
|
|
2279
2279
|
401: apiErrorSchema,
|
|
2280
2280
|
404: apiErrorSchema
|
|
2281
2281
|
},
|
|
@@ -3246,10 +3246,10 @@ async function getRawHeaders() {
|
|
|
3246
3246
|
}
|
|
3247
3247
|
return headers;
|
|
3248
3248
|
}
|
|
3249
|
-
async function httpGet(
|
|
3249
|
+
async function httpGet(path16) {
|
|
3250
3250
|
const baseUrl = await getBaseUrl();
|
|
3251
3251
|
const headers = await getRawHeaders();
|
|
3252
|
-
return fetch(`${baseUrl}${
|
|
3252
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
3253
3253
|
method: "GET",
|
|
3254
3254
|
headers
|
|
3255
3255
|
});
|
|
@@ -3754,49 +3754,49 @@ var cliComposeSchema = z24.object({
|
|
|
3754
3754
|
function formatZodError(error) {
|
|
3755
3755
|
const issue = error.issues[0];
|
|
3756
3756
|
if (!issue) return "Validation failed";
|
|
3757
|
-
const
|
|
3757
|
+
const path16 = issue.path.join(".");
|
|
3758
3758
|
const message = issue.message;
|
|
3759
|
-
if (!
|
|
3759
|
+
if (!path16) return message;
|
|
3760
3760
|
if (issue.code === "invalid_type") {
|
|
3761
3761
|
const received = issue.received;
|
|
3762
3762
|
const isMissing = received === "undefined" || message.includes("received undefined") || message === "Required";
|
|
3763
|
-
if (
|
|
3763
|
+
if (path16 === "version" && isMissing) {
|
|
3764
3764
|
return "Missing config.version";
|
|
3765
3765
|
}
|
|
3766
|
-
if (
|
|
3766
|
+
if (path16 === "agents" && isMissing) {
|
|
3767
3767
|
return "Missing agents object in config";
|
|
3768
3768
|
}
|
|
3769
|
-
if (
|
|
3770
|
-
const volumeKey =
|
|
3769
|
+
if (path16.startsWith("volumes.") && path16.endsWith(".name")) {
|
|
3770
|
+
const volumeKey = path16.split(".")[1];
|
|
3771
3771
|
return `Volume "${volumeKey}" must have a 'name' field (string)`;
|
|
3772
3772
|
}
|
|
3773
|
-
if (
|
|
3774
|
-
const volumeKey =
|
|
3773
|
+
if (path16.startsWith("volumes.") && path16.endsWith(".version")) {
|
|
3774
|
+
const volumeKey = path16.split(".")[1];
|
|
3775
3775
|
return `Volume "${volumeKey}" must have a 'version' field (string)`;
|
|
3776
3776
|
}
|
|
3777
3777
|
if (issue.expected === "array") {
|
|
3778
|
-
const fieldName =
|
|
3778
|
+
const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
|
|
3779
3779
|
return `${fieldName} must be an array`;
|
|
3780
3780
|
}
|
|
3781
3781
|
if (issue.expected === "string" && received === "number") {
|
|
3782
|
-
const fieldName =
|
|
3782
|
+
const fieldName = path16.replace(/^agents\.[^.]+\./, "agent.");
|
|
3783
3783
|
const match = fieldName.match(/^(agent\.[^.]+)\.\d+$/);
|
|
3784
3784
|
if (match) {
|
|
3785
3785
|
return `Each entry in ${match[1]?.replace("agent.", "")} must be a string`;
|
|
3786
3786
|
}
|
|
3787
3787
|
}
|
|
3788
3788
|
}
|
|
3789
|
-
if (issue.code === "invalid_key" &&
|
|
3789
|
+
if (issue.code === "invalid_key" && path16.startsWith("agents.")) {
|
|
3790
3790
|
return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
|
|
3791
3791
|
}
|
|
3792
|
-
if (message === "Invalid key in record" &&
|
|
3792
|
+
if (message === "Invalid key in record" && path16.startsWith("agents.")) {
|
|
3793
3793
|
return "Invalid agent name format. Must be 3-64 characters, letters, numbers, and hyphens only. Must start and end with letter or number.";
|
|
3794
3794
|
}
|
|
3795
3795
|
if (issue.code === "custom") {
|
|
3796
3796
|
return message;
|
|
3797
3797
|
}
|
|
3798
|
-
if (
|
|
3799
|
-
const cleanPath =
|
|
3798
|
+
if (path16.startsWith("agents.")) {
|
|
3799
|
+
const cleanPath = path16.replace(/^agents\.[^.]+\./, "agent.");
|
|
3800
3800
|
if (message.startsWith("Invalid input:")) {
|
|
3801
3801
|
const match = message.match(/expected (\w+), received (\w+)/);
|
|
3802
3802
|
if (match && match[1] === "string" && match[2] === "number") {
|
|
@@ -3808,7 +3808,7 @@ function formatZodError(error) {
|
|
|
3808
3808
|
}
|
|
3809
3809
|
return `${cleanPath}: ${message}`;
|
|
3810
3810
|
}
|
|
3811
|
-
return `${
|
|
3811
|
+
return `${path16}: ${message}`;
|
|
3812
3812
|
}
|
|
3813
3813
|
function validateAgentName(name) {
|
|
3814
3814
|
return cliAgentNameSchema.safeParse(name).success;
|
|
@@ -6007,7 +6007,7 @@ var ApiClient = class {
|
|
|
6007
6007
|
/**
|
|
6008
6008
|
* Generic GET request
|
|
6009
6009
|
*/
|
|
6010
|
-
async get(
|
|
6010
|
+
async get(path16) {
|
|
6011
6011
|
const baseUrl = await this.getBaseUrl();
|
|
6012
6012
|
const token = await getToken();
|
|
6013
6013
|
if (!token) {
|
|
@@ -6020,7 +6020,7 @@ var ApiClient = class {
|
|
|
6020
6020
|
if (bypassSecret) {
|
|
6021
6021
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
6022
6022
|
}
|
|
6023
|
-
return fetch(`${baseUrl}${
|
|
6023
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
6024
6024
|
method: "GET",
|
|
6025
6025
|
headers
|
|
6026
6026
|
});
|
|
@@ -6028,7 +6028,7 @@ var ApiClient = class {
|
|
|
6028
6028
|
/**
|
|
6029
6029
|
* Generic POST request
|
|
6030
6030
|
*/
|
|
6031
|
-
async post(
|
|
6031
|
+
async post(path16, options) {
|
|
6032
6032
|
const baseUrl = await this.getBaseUrl();
|
|
6033
6033
|
const token = await getToken();
|
|
6034
6034
|
if (!token) {
|
|
@@ -6044,7 +6044,7 @@ var ApiClient = class {
|
|
|
6044
6044
|
if (bypassSecret) {
|
|
6045
6045
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
6046
6046
|
}
|
|
6047
|
-
return fetch(`${baseUrl}${
|
|
6047
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
6048
6048
|
method: "POST",
|
|
6049
6049
|
headers,
|
|
6050
6050
|
body: options?.body
|
|
@@ -6053,7 +6053,7 @@ var ApiClient = class {
|
|
|
6053
6053
|
/**
|
|
6054
6054
|
* Generic DELETE request
|
|
6055
6055
|
*/
|
|
6056
|
-
async delete(
|
|
6056
|
+
async delete(path16) {
|
|
6057
6057
|
const baseUrl = await this.getBaseUrl();
|
|
6058
6058
|
const token = await getToken();
|
|
6059
6059
|
if (!token) {
|
|
@@ -6066,7 +6066,7 @@ var ApiClient = class {
|
|
|
6066
6066
|
if (bypassSecret) {
|
|
6067
6067
|
headers["x-vercel-protection-bypass"] = bypassSecret;
|
|
6068
6068
|
}
|
|
6069
|
-
return fetch(`${baseUrl}${
|
|
6069
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
6070
6070
|
method: "DELETE",
|
|
6071
6071
|
headers
|
|
6072
6072
|
});
|
|
@@ -7871,8 +7871,10 @@ function execVm0Command(args, options = {}) {
|
|
|
7871
7871
|
}
|
|
7872
7872
|
function execVm0RunWithCapture(args, options = {}) {
|
|
7873
7873
|
return new Promise((resolve, reject) => {
|
|
7874
|
+
const env = process.stdout.isTTY ? { ...process.env, FORCE_COLOR: "1" } : process.env;
|
|
7874
7875
|
const proc = spawn2("vm0", args, {
|
|
7875
7876
|
cwd: options.cwd,
|
|
7877
|
+
env,
|
|
7876
7878
|
stdio: ["inherit", "pipe", "pipe"],
|
|
7877
7879
|
shell: process.platform === "win32"
|
|
7878
7880
|
});
|
|
@@ -8163,7 +8165,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
8163
8165
|
).option("-y, --yes", "Skip confirmation prompts").addOption(new Option4("--debug-no-mock-claude").hideHelp()).addOption(new Option4("--no-auto-update").hideHelp()).action(
|
|
8164
8166
|
async (prompt, options) => {
|
|
8165
8167
|
if (!options.noAutoUpdate) {
|
|
8166
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
8168
|
+
const shouldExit = await checkAndUpgrade("9.6.0", prompt);
|
|
8167
8169
|
if (shouldExit) {
|
|
8168
8170
|
process.exit(0);
|
|
8169
8171
|
}
|
|
@@ -9111,13 +9113,16 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9111
9113
|
console.log();
|
|
9112
9114
|
console.log("Next steps:");
|
|
9113
9115
|
console.log(
|
|
9114
|
-
` 1. Set model provider (one-time): ${chalk37.cyan("vm0 model-provider setup")}`
|
|
9116
|
+
` 1. Set up model provider (one-time): ${chalk37.cyan("vm0 model-provider setup")}`
|
|
9115
9117
|
);
|
|
9116
9118
|
console.log(
|
|
9117
9119
|
` 2. Edit ${chalk37.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
9118
9120
|
);
|
|
9119
9121
|
console.log(
|
|
9120
|
-
`
|
|
9122
|
+
` Or install Claude plugin: ${chalk37.cyan(`vm0 setup-claude && claude "/vm0-agent let's build an agent"`)}`
|
|
9123
|
+
);
|
|
9124
|
+
console.log(
|
|
9125
|
+
` 3. Run your agent: ${chalk37.cyan(`vm0 cook "let's start working"`)}`
|
|
9121
9126
|
);
|
|
9122
9127
|
});
|
|
9123
9128
|
|
|
@@ -10744,31 +10749,30 @@ import { Command as Command56 } from "commander";
|
|
|
10744
10749
|
import chalk56 from "chalk";
|
|
10745
10750
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
10746
10751
|
import { existsSync as existsSync11 } from "fs";
|
|
10747
|
-
import path16 from "path";
|
|
10748
10752
|
|
|
10749
10753
|
// src/lib/ui/welcome-box.ts
|
|
10750
10754
|
import chalk53 from "chalk";
|
|
10751
10755
|
var gradientColors = [
|
|
10752
|
-
chalk53.hex("#
|
|
10756
|
+
chalk53.hex("#FFAB5E"),
|
|
10753
10757
|
// Line 1 - lightest
|
|
10754
|
-
chalk53.hex("#
|
|
10758
|
+
chalk53.hex("#FF9642"),
|
|
10755
10759
|
// Line 2
|
|
10756
|
-
chalk53.hex("#
|
|
10760
|
+
chalk53.hex("#FF8228"),
|
|
10757
10761
|
// Line 3
|
|
10758
|
-
chalk53.hex("#
|
|
10759
|
-
// Line 4
|
|
10760
|
-
chalk53.hex("#
|
|
10762
|
+
chalk53.hex("#FF6D0A"),
|
|
10763
|
+
// Line 4
|
|
10764
|
+
chalk53.hex("#E85D00"),
|
|
10761
10765
|
// Line 5
|
|
10762
|
-
chalk53.hex("#
|
|
10766
|
+
chalk53.hex("#CC4E00")
|
|
10763
10767
|
// Line 6 - darkest
|
|
10764
10768
|
];
|
|
10765
10769
|
var vm0LogoLines = [
|
|
10766
|
-
"\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
10770
|
+
"\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
10767
10771
|
"\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557",
|
|
10768
10772
|
"\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551",
|
|
10769
10773
|
"\u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551",
|
|
10770
10774
|
" \u255A\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D",
|
|
10771
|
-
" \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D"
|
|
10775
|
+
" \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D "
|
|
10772
10776
|
];
|
|
10773
10777
|
function renderVm0Banner() {
|
|
10774
10778
|
console.log();
|
|
@@ -10781,73 +10785,79 @@ function renderVm0Banner() {
|
|
|
10781
10785
|
function renderOnboardWelcome() {
|
|
10782
10786
|
renderVm0Banner();
|
|
10783
10787
|
console.log(` ${chalk53.bold("Welcome to VM0!")}`);
|
|
10784
|
-
console.log(
|
|
10788
|
+
console.log(
|
|
10789
|
+
` ${chalk53.dim("Build agentic workflows using natural language.")}`
|
|
10790
|
+
);
|
|
10785
10791
|
console.log();
|
|
10786
10792
|
}
|
|
10787
10793
|
|
|
10788
|
-
// src/lib/ui/
|
|
10794
|
+
// src/lib/ui/step-runner.ts
|
|
10789
10795
|
import chalk54 from "chalk";
|
|
10790
|
-
function
|
|
10791
|
-
|
|
10792
|
-
|
|
10793
|
-
|
|
10794
|
-
const
|
|
10795
|
-
|
|
10796
|
-
process.stdout.write(
|
|
10797
|
-
|
|
10798
|
-
|
|
10799
|
-
|
|
10800
|
-
|
|
10801
|
-
for (let i = 0; i < detailLineCount; i++) {
|
|
10802
|
-
process.stdout.write(`
|
|
10803
|
-
\x1B[K`);
|
|
10804
|
-
}
|
|
10805
|
-
if (detailLineCount > 0) {
|
|
10806
|
-
process.stdout.write(`\x1B[${detailLineCount}A`);
|
|
10796
|
+
function createStepRunner(options = true) {
|
|
10797
|
+
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
10798
|
+
const interactive = opts.interactive ?? true;
|
|
10799
|
+
const headerFn = opts.header;
|
|
10800
|
+
const completedSteps = [];
|
|
10801
|
+
function redrawCompletedSteps(isFinal) {
|
|
10802
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
10803
|
+
if (headerFn) {
|
|
10804
|
+
console.log();
|
|
10805
|
+
headerFn();
|
|
10806
|
+
console.log();
|
|
10807
10807
|
}
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
|
|
10813
|
-
isFinalStep = false;
|
|
10814
|
-
console.log(chalk54.yellow(`\u25CB ${label}`));
|
|
10815
|
-
},
|
|
10816
|
-
detail: (message) => {
|
|
10817
|
-
console.log(chalk54.dim(`\u2502 ${message}`));
|
|
10818
|
-
detailLineCount++;
|
|
10819
|
-
},
|
|
10820
|
-
completeStep: () => {
|
|
10821
|
-
if (interactive && detailLineCount > 0) {
|
|
10822
|
-
clearDetails();
|
|
10823
|
-
} else if (interactive) {
|
|
10824
|
-
process.stdout.write(`\x1B[1A\x1B[K`);
|
|
10808
|
+
for (const [i, step] of completedSteps.entries()) {
|
|
10809
|
+
if (step.failed) {
|
|
10810
|
+
console.log(chalk54.red(`\u2717 ${step.label}`));
|
|
10811
|
+
} else {
|
|
10812
|
+
console.log(chalk54.green(`\u25CF ${step.label}`));
|
|
10825
10813
|
}
|
|
10826
|
-
|
|
10827
|
-
if (
|
|
10828
|
-
|
|
10814
|
+
const isLastStep = i === completedSteps.length - 1;
|
|
10815
|
+
if (!isLastStep || !isFinal) {
|
|
10816
|
+
console.log(chalk54.dim("\u2502"));
|
|
10829
10817
|
}
|
|
10830
|
-
|
|
10818
|
+
}
|
|
10819
|
+
}
|
|
10820
|
+
async function executeStep(label, fn, isFinal) {
|
|
10821
|
+
let stepFailed = false;
|
|
10822
|
+
console.log(chalk54.yellow(`\u25CB ${label}`));
|
|
10823
|
+
const ctx = {
|
|
10824
|
+
connector() {
|
|
10831
10825
|
console.log(chalk54.dim("\u2502"));
|
|
10826
|
+
},
|
|
10827
|
+
detail(message) {
|
|
10828
|
+
console.log(`${chalk54.dim("\u2502")} ${message}`);
|
|
10829
|
+
},
|
|
10830
|
+
async prompt(promptFn) {
|
|
10831
|
+
return await promptFn();
|
|
10832
10832
|
}
|
|
10833
|
-
|
|
10834
|
-
|
|
10835
|
-
|
|
10836
|
-
|
|
10837
|
-
|
|
10838
|
-
|
|
10839
|
-
|
|
10840
|
-
|
|
10841
|
-
|
|
10842
|
-
|
|
10843
|
-
|
|
10844
|
-
|
|
10845
|
-
|
|
10846
|
-
|
|
10847
|
-
|
|
10833
|
+
};
|
|
10834
|
+
try {
|
|
10835
|
+
await fn(ctx);
|
|
10836
|
+
} catch (error) {
|
|
10837
|
+
stepFailed = true;
|
|
10838
|
+
throw error;
|
|
10839
|
+
} finally {
|
|
10840
|
+
completedSteps.push({ label, failed: stepFailed });
|
|
10841
|
+
if (interactive) {
|
|
10842
|
+
redrawCompletedSteps(isFinal);
|
|
10843
|
+
} else {
|
|
10844
|
+
if (stepFailed) {
|
|
10845
|
+
console.log(chalk54.red(`\u2717 ${label}`));
|
|
10846
|
+
} else {
|
|
10847
|
+
console.log(chalk54.green(`\u25CF ${label}`));
|
|
10848
|
+
}
|
|
10849
|
+
if (!isFinal) {
|
|
10850
|
+
console.log(chalk54.dim("\u2502"));
|
|
10851
|
+
}
|
|
10852
|
+
}
|
|
10853
|
+
}
|
|
10854
|
+
}
|
|
10855
|
+
return {
|
|
10856
|
+
async step(label, fn) {
|
|
10857
|
+
await executeStep(label, fn, false);
|
|
10848
10858
|
},
|
|
10849
|
-
|
|
10850
|
-
|
|
10859
|
+
async finalStep(label, fn) {
|
|
10860
|
+
await executeStep(label, fn, true);
|
|
10851
10861
|
}
|
|
10852
10862
|
};
|
|
10853
10863
|
}
|
|
@@ -11084,175 +11094,199 @@ async function installVm0Plugin(scope = "user", cwd) {
|
|
|
11084
11094
|
// src/commands/onboard/index.ts
|
|
11085
11095
|
var DEFAULT_AGENT_NAME = "my-vm0-agent";
|
|
11086
11096
|
async function handleAuthentication(ctx) {
|
|
11087
|
-
ctx.
|
|
11088
|
-
|
|
11089
|
-
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
|
|
11093
|
-
|
|
11094
|
-
|
|
11095
|
-
console.error(chalk56.red("Error: Not authenticated"));
|
|
11096
|
-
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
11097
|
-
process.exit(1);
|
|
11098
|
-
}
|
|
11099
|
-
await runAuthFlow({
|
|
11100
|
-
onInitiating: () => {
|
|
11101
|
-
},
|
|
11102
|
-
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
11103
|
-
ctx.progress.detail(`Visit: ${url}`);
|
|
11104
|
-
ctx.progress.detail(`Code: ${code}`);
|
|
11105
|
-
ctx.progress.detail(`Expires in ${expiresIn} minutes`);
|
|
11106
|
-
ctx.progress.detail("Waiting for confirmation...");
|
|
11107
|
-
},
|
|
11108
|
-
onPolling: () => {
|
|
11109
|
-
},
|
|
11110
|
-
onSuccess: () => {
|
|
11111
|
-
},
|
|
11112
|
-
onError: (error) => {
|
|
11113
|
-
ctx.progress.failStep();
|
|
11114
|
-
console.error(chalk56.red(`
|
|
11115
|
-
${error.message}`));
|
|
11097
|
+
await ctx.runner.step("Authenticate to vm0.ai", async (step) => {
|
|
11098
|
+
const authenticated = await isAuthenticated();
|
|
11099
|
+
if (authenticated) {
|
|
11100
|
+
return;
|
|
11101
|
+
}
|
|
11102
|
+
if (!ctx.interactive) {
|
|
11103
|
+
console.error(chalk56.red("Error: Not authenticated"));
|
|
11104
|
+
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
11116
11105
|
process.exit(1);
|
|
11117
11106
|
}
|
|
11107
|
+
await runAuthFlow({
|
|
11108
|
+
onInitiating: () => {
|
|
11109
|
+
},
|
|
11110
|
+
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
11111
|
+
step.detail(`Copy code: ${chalk56.cyan.bold(code)}`);
|
|
11112
|
+
step.detail(`Open: ${chalk56.cyan(url)}`);
|
|
11113
|
+
step.detail(chalk56.dim(`Expires in ${expiresIn} minutes`));
|
|
11114
|
+
},
|
|
11115
|
+
onPolling: () => {
|
|
11116
|
+
},
|
|
11117
|
+
onSuccess: () => {
|
|
11118
|
+
},
|
|
11119
|
+
onError: (error) => {
|
|
11120
|
+
console.error(chalk56.red(`
|
|
11121
|
+
${error.message}`));
|
|
11122
|
+
process.exit(1);
|
|
11123
|
+
}
|
|
11124
|
+
});
|
|
11118
11125
|
});
|
|
11119
|
-
ctx.progress.completeStep();
|
|
11120
11126
|
}
|
|
11121
11127
|
async function handleModelProvider(ctx) {
|
|
11122
|
-
ctx.
|
|
11123
|
-
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
|
|
11127
|
-
|
|
11128
|
-
|
|
11129
|
-
|
|
11130
|
-
|
|
11131
|
-
|
|
11132
|
-
|
|
11133
|
-
|
|
11134
|
-
|
|
11135
|
-
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
|
|
11142
|
-
|
|
11143
|
-
|
|
11144
|
-
|
|
11145
|
-
|
|
11146
|
-
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
);
|
|
11151
|
-
if (!credential) {
|
|
11152
|
-
console.log(chalk56.dim("Cancelled"));
|
|
11153
|
-
process.exit(0);
|
|
11154
|
-
}
|
|
11155
|
-
const result = await setupModelProvider(providerType, credential);
|
|
11156
|
-
ctx.progress.detail(
|
|
11157
|
-
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}`
|
|
11158
|
-
);
|
|
11159
|
-
ctx.progress.completeStep();
|
|
11160
|
-
}
|
|
11161
|
-
async function handleAgentCreation(ctx) {
|
|
11162
|
-
ctx.progress.startStep("Create Agent");
|
|
11163
|
-
let agentName = ctx.options.name ?? DEFAULT_AGENT_NAME;
|
|
11164
|
-
if (!ctx.options.yes && !ctx.options.name && ctx.interactive) {
|
|
11165
|
-
const inputName = await promptText(
|
|
11166
|
-
"Enter agent name:",
|
|
11167
|
-
DEFAULT_AGENT_NAME,
|
|
11168
|
-
(value) => {
|
|
11169
|
-
if (!validateAgentName(value)) {
|
|
11170
|
-
return "Invalid name: 3-64 chars, alphanumeric + hyphens, start/end with letter/number";
|
|
11171
|
-
}
|
|
11172
|
-
return true;
|
|
11128
|
+
await ctx.runner.step("Set Up Model Provider", async (step) => {
|
|
11129
|
+
const providerStatus = await checkModelProviderStatus();
|
|
11130
|
+
if (providerStatus.hasProvider) {
|
|
11131
|
+
return;
|
|
11132
|
+
}
|
|
11133
|
+
if (!ctx.interactive) {
|
|
11134
|
+
console.error(chalk56.red("Error: No model provider configured"));
|
|
11135
|
+
console.error("Run 'vm0 model-provider setup' first");
|
|
11136
|
+
process.exit(1);
|
|
11137
|
+
}
|
|
11138
|
+
const choices = getProviderChoices();
|
|
11139
|
+
step.connector();
|
|
11140
|
+
const providerType = await step.prompt(
|
|
11141
|
+
() => promptSelect(
|
|
11142
|
+
"Select provider type:",
|
|
11143
|
+
choices.map((c20) => ({
|
|
11144
|
+
title: c20.label,
|
|
11145
|
+
value: c20.type
|
|
11146
|
+
}))
|
|
11147
|
+
)
|
|
11148
|
+
);
|
|
11149
|
+
if (!providerType) {
|
|
11150
|
+
process.exit(0);
|
|
11151
|
+
}
|
|
11152
|
+
const selectedChoice = choices.find((c20) => c20.type === providerType);
|
|
11153
|
+
if (selectedChoice?.helpText) {
|
|
11154
|
+
for (const line of selectedChoice.helpText.split("\n")) {
|
|
11155
|
+
step.detail(chalk56.dim(line));
|
|
11173
11156
|
}
|
|
11157
|
+
}
|
|
11158
|
+
const credential = await step.prompt(
|
|
11159
|
+
() => promptPassword(
|
|
11160
|
+
`Enter your ${selectedChoice?.credentialLabel ?? "credential"}:`
|
|
11161
|
+
)
|
|
11174
11162
|
);
|
|
11175
|
-
if (!
|
|
11163
|
+
if (!credential) {
|
|
11164
|
+
console.log(chalk56.dim("Cancelled"));
|
|
11176
11165
|
process.exit(0);
|
|
11177
11166
|
}
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
console.error(
|
|
11183
|
-
chalk56.red(
|
|
11184
|
-
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
11167
|
+
const result = await setupModelProvider(providerType, credential);
|
|
11168
|
+
step.detail(
|
|
11169
|
+
chalk56.green(
|
|
11170
|
+
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}`
|
|
11185
11171
|
)
|
|
11186
11172
|
);
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11173
|
+
});
|
|
11174
|
+
}
|
|
11175
|
+
async function handleAgentCreation(ctx) {
|
|
11176
|
+
let agentName = ctx.options.name ?? DEFAULT_AGENT_NAME;
|
|
11177
|
+
await ctx.runner.step("Create New Project", async (step) => {
|
|
11178
|
+
if (!ctx.options.yes && !ctx.options.name && ctx.interactive) {
|
|
11179
|
+
let folderExists = true;
|
|
11180
|
+
while (folderExists) {
|
|
11181
|
+
step.connector();
|
|
11182
|
+
const inputName = await step.prompt(
|
|
11183
|
+
() => promptText(
|
|
11184
|
+
"Enter project name:",
|
|
11185
|
+
DEFAULT_AGENT_NAME,
|
|
11186
|
+
(value) => {
|
|
11187
|
+
if (!validateAgentName(value)) {
|
|
11188
|
+
return "Invalid name: 3-64 chars, alphanumeric + hyphens, start/end with letter/number";
|
|
11189
|
+
}
|
|
11190
|
+
return true;
|
|
11191
|
+
}
|
|
11192
|
+
)
|
|
11193
|
+
);
|
|
11194
|
+
if (!inputName) {
|
|
11195
|
+
process.exit(0);
|
|
11196
|
+
}
|
|
11197
|
+
agentName = inputName;
|
|
11198
|
+
if (existsSync11(agentName)) {
|
|
11199
|
+
step.detail(
|
|
11200
|
+
chalk56.yellow(`${agentName}/ already exists, choose another name`)
|
|
11201
|
+
);
|
|
11202
|
+
} else {
|
|
11203
|
+
folderExists = false;
|
|
11204
|
+
}
|
|
11205
|
+
}
|
|
11206
|
+
} else {
|
|
11207
|
+
if (!validateAgentName(agentName)) {
|
|
11208
|
+
console.error(
|
|
11209
|
+
chalk56.red(
|
|
11210
|
+
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
11211
|
+
)
|
|
11212
|
+
);
|
|
11213
|
+
process.exit(1);
|
|
11214
|
+
}
|
|
11215
|
+
if (existsSync11(agentName)) {
|
|
11216
|
+
console.error(chalk56.red(`${agentName}/ already exists`));
|
|
11217
|
+
console.log();
|
|
11218
|
+
console.log("Remove it first or choose a different name:");
|
|
11219
|
+
console.log(chalk56.cyan(` rm -rf ${agentName}`));
|
|
11220
|
+
process.exit(1);
|
|
11221
|
+
}
|
|
11222
|
+
}
|
|
11223
|
+
await mkdir7(agentName, { recursive: true });
|
|
11224
|
+
step.detail(chalk56.green(`Created ${agentName}/`));
|
|
11225
|
+
});
|
|
11200
11226
|
return agentName;
|
|
11201
11227
|
}
|
|
11202
11228
|
async function handlePluginInstallation(ctx, agentName) {
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
+
let pluginInstalled = false;
|
|
11230
|
+
await ctx.runner.step("Install Claude Plugin", async (step) => {
|
|
11231
|
+
let shouldInstall = true;
|
|
11232
|
+
if (!ctx.options.yes && ctx.interactive) {
|
|
11233
|
+
step.connector();
|
|
11234
|
+
const confirmed = await step.prompt(
|
|
11235
|
+
() => promptConfirm("Install VM0 Claude Plugin?", true)
|
|
11236
|
+
);
|
|
11237
|
+
shouldInstall = confirmed ?? true;
|
|
11238
|
+
}
|
|
11239
|
+
if (!shouldInstall) {
|
|
11240
|
+
step.detail(chalk56.dim("Skipped"));
|
|
11241
|
+
return;
|
|
11242
|
+
}
|
|
11243
|
+
const scope = "project";
|
|
11244
|
+
try {
|
|
11245
|
+
const agentDir = `${process.cwd()}/${agentName}`;
|
|
11246
|
+
const result = await installVm0Plugin(scope, agentDir);
|
|
11247
|
+
step.detail(
|
|
11248
|
+
chalk56.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11249
|
+
);
|
|
11250
|
+
pluginInstalled = true;
|
|
11251
|
+
} catch (error) {
|
|
11252
|
+
handlePluginError(error);
|
|
11253
|
+
}
|
|
11254
|
+
});
|
|
11255
|
+
return pluginInstalled;
|
|
11229
11256
|
}
|
|
11230
|
-
function printNextSteps(agentName) {
|
|
11257
|
+
function printNextSteps(agentName, pluginInstalled) {
|
|
11231
11258
|
console.log();
|
|
11232
11259
|
console.log(chalk56.bold("Next step:"));
|
|
11233
11260
|
console.log();
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
)
|
|
11261
|
+
if (pluginInstalled) {
|
|
11262
|
+
console.log(
|
|
11263
|
+
` ${chalk56.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
11264
|
+
);
|
|
11265
|
+
} else {
|
|
11266
|
+
console.log(` ${chalk56.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
11267
|
+
}
|
|
11237
11268
|
console.log();
|
|
11238
11269
|
}
|
|
11239
11270
|
var onboardCommand = new Command56().name("onboard").description("Guided setup for new VM0 users").option("-y, --yes", "Skip confirmation prompts").option("--name <name>", `Agent name (default: ${DEFAULT_AGENT_NAME})`).action(async (options) => {
|
|
11240
11271
|
const interactive = isInteractive();
|
|
11241
11272
|
if (interactive) {
|
|
11273
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
11242
11274
|
console.log();
|
|
11243
11275
|
renderOnboardWelcome();
|
|
11244
11276
|
console.log();
|
|
11245
11277
|
}
|
|
11246
|
-
const
|
|
11247
|
-
|
|
11278
|
+
const runner = createStepRunner({
|
|
11279
|
+
interactive,
|
|
11280
|
+
header: interactive ? renderOnboardWelcome : void 0
|
|
11281
|
+
});
|
|
11282
|
+
const ctx = { interactive, options, runner };
|
|
11248
11283
|
await handleAuthentication(ctx);
|
|
11249
11284
|
await handleModelProvider(ctx);
|
|
11250
11285
|
const agentName = await handleAgentCreation(ctx);
|
|
11251
|
-
await handlePluginInstallation(ctx, agentName);
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
|
|
11255
|
-
printNextSteps(agentName);
|
|
11286
|
+
const pluginInstalled = await handlePluginInstallation(ctx, agentName);
|
|
11287
|
+
await ctx.runner.finalStep("Completed", async () => {
|
|
11288
|
+
});
|
|
11289
|
+
printNextSteps(agentName, pluginInstalled);
|
|
11256
11290
|
});
|
|
11257
11291
|
|
|
11258
11292
|
// src/commands/setup-claude/index.ts
|
|
@@ -11281,7 +11315,7 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11281
11315
|
|
|
11282
11316
|
// src/index.ts
|
|
11283
11317
|
var program = new Command58();
|
|
11284
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
11318
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.6.0");
|
|
11285
11319
|
program.addCommand(authCommand);
|
|
11286
11320
|
program.addCommand(infoCommand);
|
|
11287
11321
|
program.addCommand(composeCommand);
|