@vm0/cli 9.13.1 → 9.14.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 +511 -349
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command59 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth/index.ts
|
|
7
7
|
import { Command as Command5 } from "commander";
|
|
@@ -2574,7 +2574,9 @@ var platformLogStatusSchema = z19.enum([
|
|
|
2574
2574
|
]);
|
|
2575
2575
|
var platformLogEntrySchema = z19.object({
|
|
2576
2576
|
id: z19.string().uuid(),
|
|
2577
|
+
sessionId: z19.string().nullable(),
|
|
2577
2578
|
agentName: z19.string(),
|
|
2579
|
+
framework: z19.string().nullable(),
|
|
2578
2580
|
status: platformLogStatusSchema,
|
|
2579
2581
|
createdAt: z19.string()
|
|
2580
2582
|
});
|
|
@@ -4893,7 +4895,7 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
4893
4895
|
)
|
|
4894
4896
|
);
|
|
4895
4897
|
if (options.autoUpdate !== false) {
|
|
4896
|
-
await silentUpgradeAfterCommand("9.
|
|
4898
|
+
await silentUpgradeAfterCommand("9.14.0");
|
|
4897
4899
|
}
|
|
4898
4900
|
} catch (error) {
|
|
4899
4901
|
if (error instanceof Error) {
|
|
@@ -7124,7 +7126,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
7124
7126
|
}
|
|
7125
7127
|
showNextSteps(result);
|
|
7126
7128
|
if (options.autoUpdate !== false) {
|
|
7127
|
-
await silentUpgradeAfterCommand("9.
|
|
7129
|
+
await silentUpgradeAfterCommand("9.14.0");
|
|
7128
7130
|
}
|
|
7129
7131
|
} catch (error) {
|
|
7130
7132
|
handleRunError(error, identifier);
|
|
@@ -8630,7 +8632,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
8630
8632
|
).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option5("--debug-no-mock-claude").hideHelp()).addOption(new Option5("--no-auto-update").hideHelp()).action(
|
|
8631
8633
|
async (prompt, options) => {
|
|
8632
8634
|
if (!options.noAutoUpdate) {
|
|
8633
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
8635
|
+
const shouldExit = await checkAndUpgrade("9.14.0", prompt);
|
|
8634
8636
|
if (shouldExit) {
|
|
8635
8637
|
process.exit(0);
|
|
8636
8638
|
}
|
|
@@ -9205,12 +9207,131 @@ var setCommand = new Command33().name("set").description("Set your scope slug").
|
|
|
9205
9207
|
var scopeCommand = new Command34().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand4).addCommand(setCommand);
|
|
9206
9208
|
|
|
9207
9209
|
// src/commands/agent/index.ts
|
|
9208
|
-
import { Command as
|
|
9210
|
+
import { Command as Command38 } from "commander";
|
|
9209
9211
|
|
|
9210
|
-
// src/commands/agent/
|
|
9212
|
+
// src/commands/agent/clone.ts
|
|
9211
9213
|
import { Command as Command35 } from "commander";
|
|
9212
9214
|
import chalk36 from "chalk";
|
|
9213
|
-
|
|
9215
|
+
import { existsSync as existsSync10, mkdtempSync as mkdtempSync5 } from "fs";
|
|
9216
|
+
import { mkdir as mkdir7, writeFile as writeFile6, readdir, copyFile, rm as rm3 } from "fs/promises";
|
|
9217
|
+
import { join as join7, dirname as dirname3 } from "path";
|
|
9218
|
+
import { tmpdir as tmpdir7 } from "os";
|
|
9219
|
+
import * as tar6 from "tar";
|
|
9220
|
+
import { stringify as yamlStringify } from "yaml";
|
|
9221
|
+
function cleanComposeContent(content) {
|
|
9222
|
+
const cleaned = {
|
|
9223
|
+
version: content.version,
|
|
9224
|
+
agents: {}
|
|
9225
|
+
};
|
|
9226
|
+
for (const [agentName, agent] of Object.entries(content.agents)) {
|
|
9227
|
+
const { image, working_dir: workingDir, ...rest } = agent;
|
|
9228
|
+
void image;
|
|
9229
|
+
void workingDir;
|
|
9230
|
+
cleaned.agents[agentName] = rest;
|
|
9231
|
+
}
|
|
9232
|
+
if (content.volumes) {
|
|
9233
|
+
cleaned.volumes = content.volumes;
|
|
9234
|
+
}
|
|
9235
|
+
return cleaned;
|
|
9236
|
+
}
|
|
9237
|
+
async function downloadInstructions(agentName, instructionsPath, destination) {
|
|
9238
|
+
const volumeName = getInstructionsStorageName(agentName);
|
|
9239
|
+
console.log(chalk36.dim("Downloading instructions..."));
|
|
9240
|
+
const downloadInfo = await getStorageDownload({
|
|
9241
|
+
name: volumeName,
|
|
9242
|
+
type: "volume"
|
|
9243
|
+
});
|
|
9244
|
+
if ("empty" in downloadInfo) {
|
|
9245
|
+
console.log(chalk36.yellow("\u26A0 Instructions volume is empty"));
|
|
9246
|
+
return false;
|
|
9247
|
+
}
|
|
9248
|
+
const response = await fetch(downloadInfo.url);
|
|
9249
|
+
if (!response.ok) {
|
|
9250
|
+
throw new Error(`Failed to download instructions: ${response.status}`);
|
|
9251
|
+
}
|
|
9252
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
9253
|
+
const tmpDir = mkdtempSync5(join7(tmpdir7(), "vm0-clone-"));
|
|
9254
|
+
const tarPath = join7(tmpDir, "archive.tar.gz");
|
|
9255
|
+
await writeFile6(tarPath, buffer);
|
|
9256
|
+
await tar6.extract({ file: tarPath, cwd: tmpDir, gzip: true });
|
|
9257
|
+
const files = await readdir(tmpDir);
|
|
9258
|
+
const mdFile = files.find((f) => f === "CLAUDE.md" || f === "AGENTS.md");
|
|
9259
|
+
if (!mdFile) {
|
|
9260
|
+
console.log(chalk36.yellow("\u26A0 No instructions file found in volume"));
|
|
9261
|
+
await rm3(tmpDir, { recursive: true, force: true });
|
|
9262
|
+
return false;
|
|
9263
|
+
}
|
|
9264
|
+
const destPath = join7(destination, instructionsPath);
|
|
9265
|
+
await mkdir7(dirname3(destPath), { recursive: true });
|
|
9266
|
+
await copyFile(join7(tmpDir, mdFile), destPath);
|
|
9267
|
+
await rm3(tmpDir, { recursive: true, force: true });
|
|
9268
|
+
return true;
|
|
9269
|
+
}
|
|
9270
|
+
var cloneCommand3 = new Command35().name("clone").description("Clone agent compose to local directory (latest version)").argument("<name>", "Agent compose name to clone").argument("[destination]", "Destination directory (default: agent name)").action(async (name, destination) => {
|
|
9271
|
+
try {
|
|
9272
|
+
const targetDir = destination || name;
|
|
9273
|
+
if (existsSync10(targetDir)) {
|
|
9274
|
+
console.error(chalk36.red(`\u2717 Directory "${targetDir}" already exists`));
|
|
9275
|
+
process.exit(1);
|
|
9276
|
+
}
|
|
9277
|
+
console.log(`Cloning agent compose: ${name}`);
|
|
9278
|
+
const compose = await getComposeByName(name);
|
|
9279
|
+
if (!compose) {
|
|
9280
|
+
console.error(chalk36.red(`\u2717 Agent compose not found: ${name}`));
|
|
9281
|
+
process.exit(1);
|
|
9282
|
+
}
|
|
9283
|
+
if (!compose.content || !compose.headVersionId) {
|
|
9284
|
+
console.error(chalk36.red(`\u2717 Agent compose has no content: ${name}`));
|
|
9285
|
+
process.exit(1);
|
|
9286
|
+
}
|
|
9287
|
+
const content = compose.content;
|
|
9288
|
+
const cleanedContent = cleanComposeContent(content);
|
|
9289
|
+
const yamlContent = yamlStringify(cleanedContent);
|
|
9290
|
+
await mkdir7(targetDir, { recursive: true });
|
|
9291
|
+
const yamlPath = join7(targetDir, "vm0.yaml");
|
|
9292
|
+
await writeFile6(yamlPath, yamlContent, "utf8");
|
|
9293
|
+
console.log(chalk36.green("\u2713 Created vm0.yaml"));
|
|
9294
|
+
const agentKey = Object.keys(content.agents)[0];
|
|
9295
|
+
const agent = agentKey ? content.agents[agentKey] : void 0;
|
|
9296
|
+
if (agent?.instructions) {
|
|
9297
|
+
try {
|
|
9298
|
+
const instructionsDownloaded = await downloadInstructions(
|
|
9299
|
+
name,
|
|
9300
|
+
agent.instructions,
|
|
9301
|
+
targetDir
|
|
9302
|
+
);
|
|
9303
|
+
if (instructionsDownloaded) {
|
|
9304
|
+
console.log(chalk36.green(`\u2713 Downloaded ${agent.instructions}`));
|
|
9305
|
+
}
|
|
9306
|
+
} catch (error) {
|
|
9307
|
+
console.log(
|
|
9308
|
+
chalk36.yellow(
|
|
9309
|
+
`\u26A0 Could not download instructions: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
9310
|
+
)
|
|
9311
|
+
);
|
|
9312
|
+
}
|
|
9313
|
+
}
|
|
9314
|
+
console.log();
|
|
9315
|
+
console.log(chalk36.green(`\u2713 Successfully cloned agent: ${name}`));
|
|
9316
|
+
console.log(chalk36.dim(` Location: ${targetDir}/`));
|
|
9317
|
+
console.log(chalk36.dim(` Version: ${compose.headVersionId.slice(0, 8)}`));
|
|
9318
|
+
} catch (error) {
|
|
9319
|
+
console.error(chalk36.red("\u2717 Clone failed"));
|
|
9320
|
+
if (error instanceof Error) {
|
|
9321
|
+
if (error.message.includes("Not authenticated")) {
|
|
9322
|
+
console.error(chalk36.dim(" Run: vm0 auth login"));
|
|
9323
|
+
} else {
|
|
9324
|
+
console.error(chalk36.dim(` ${error.message}`));
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9327
|
+
process.exit(1);
|
|
9328
|
+
}
|
|
9329
|
+
});
|
|
9330
|
+
|
|
9331
|
+
// src/commands/agent/list.ts
|
|
9332
|
+
import { Command as Command36 } from "commander";
|
|
9333
|
+
import chalk37 from "chalk";
|
|
9334
|
+
var listCommand4 = new Command36().name("list").alias("ls").description("List all agent composes").action(async () => {
|
|
9214
9335
|
try {
|
|
9215
9336
|
const response = await httpGet("/api/agent/composes/list");
|
|
9216
9337
|
if (!response.ok) {
|
|
@@ -9219,9 +9340,9 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
9219
9340
|
}
|
|
9220
9341
|
const data = await response.json();
|
|
9221
9342
|
if (data.composes.length === 0) {
|
|
9222
|
-
console.log(
|
|
9343
|
+
console.log(chalk37.dim("No agent composes found"));
|
|
9223
9344
|
console.log(
|
|
9224
|
-
|
|
9345
|
+
chalk37.dim(" Create one with: vm0 compose <agent-compose.yaml>")
|
|
9225
9346
|
);
|
|
9226
9347
|
return;
|
|
9227
9348
|
}
|
|
@@ -9229,9 +9350,9 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
9229
9350
|
const header = ["NAME".padEnd(nameWidth), "VERSION", "UPDATED"].join(
|
|
9230
9351
|
" "
|
|
9231
9352
|
);
|
|
9232
|
-
console.log(
|
|
9353
|
+
console.log(chalk37.dim(header));
|
|
9233
9354
|
for (const compose of data.composes) {
|
|
9234
|
-
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) :
|
|
9355
|
+
const versionShort = compose.headVersionId ? compose.headVersionId.slice(0, 8) : chalk37.dim("-");
|
|
9235
9356
|
const row = [
|
|
9236
9357
|
compose.name.padEnd(nameWidth),
|
|
9237
9358
|
versionShort,
|
|
@@ -9240,12 +9361,12 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
9240
9361
|
console.log(row);
|
|
9241
9362
|
}
|
|
9242
9363
|
} catch (error) {
|
|
9243
|
-
console.error(
|
|
9364
|
+
console.error(chalk37.red("\u2717 Failed to list agent composes"));
|
|
9244
9365
|
if (error instanceof Error) {
|
|
9245
9366
|
if (error.message.includes("Not authenticated")) {
|
|
9246
|
-
console.error(
|
|
9367
|
+
console.error(chalk37.dim(" Run: vm0 auth login"));
|
|
9247
9368
|
} else {
|
|
9248
|
-
console.error(
|
|
9369
|
+
console.error(chalk37.dim(` ${error.message}`));
|
|
9249
9370
|
}
|
|
9250
9371
|
}
|
|
9251
9372
|
process.exit(1);
|
|
@@ -9253,8 +9374,8 @@ var listCommand4 = new Command35().name("list").alias("ls").description("List al
|
|
|
9253
9374
|
});
|
|
9254
9375
|
|
|
9255
9376
|
// src/commands/agent/status.ts
|
|
9256
|
-
import { Command as
|
|
9257
|
-
import
|
|
9377
|
+
import { Command as Command37 } from "commander";
|
|
9378
|
+
import chalk38 from "chalk";
|
|
9258
9379
|
|
|
9259
9380
|
// src/lib/domain/source-derivation.ts
|
|
9260
9381
|
import * as fs9 from "fs/promises";
|
|
@@ -9378,27 +9499,27 @@ function formatVariableSources(sources) {
|
|
|
9378
9499
|
if (sources.secrets.length > 0) {
|
|
9379
9500
|
console.log(` Secrets:`);
|
|
9380
9501
|
for (const secret of sources.secrets) {
|
|
9381
|
-
const sourceInfo =
|
|
9502
|
+
const sourceInfo = chalk38.dim(`(${secret.source})`);
|
|
9382
9503
|
console.log(` - ${secret.name.padEnd(20)} ${sourceInfo}`);
|
|
9383
9504
|
}
|
|
9384
9505
|
}
|
|
9385
9506
|
if (sources.vars.length > 0) {
|
|
9386
9507
|
console.log(` Vars:`);
|
|
9387
9508
|
for (const v of sources.vars) {
|
|
9388
|
-
const sourceInfo =
|
|
9509
|
+
const sourceInfo = chalk38.dim(`(${v.source})`);
|
|
9389
9510
|
console.log(` - ${v.name.padEnd(20)} ${sourceInfo}`);
|
|
9390
9511
|
}
|
|
9391
9512
|
}
|
|
9392
9513
|
if (sources.credentials.length > 0) {
|
|
9393
9514
|
console.log(` Credentials:`);
|
|
9394
9515
|
for (const cred of sources.credentials) {
|
|
9395
|
-
const sourceInfo =
|
|
9516
|
+
const sourceInfo = chalk38.dim(`(${cred.source})`);
|
|
9396
9517
|
console.log(` - ${cred.name.padEnd(20)} ${sourceInfo}`);
|
|
9397
9518
|
}
|
|
9398
9519
|
}
|
|
9399
9520
|
}
|
|
9400
9521
|
function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
9401
|
-
console.log(` ${
|
|
9522
|
+
console.log(` ${chalk38.cyan(agentName)}:`);
|
|
9402
9523
|
console.log(` Framework: ${agent.framework}`);
|
|
9403
9524
|
if (agent.image) {
|
|
9404
9525
|
console.log(` Image: ${agent.image}`);
|
|
@@ -9417,16 +9538,16 @@ function formatAgentDetails(agentName, agent, agentSources, volumeConfigs) {
|
|
|
9417
9538
|
}
|
|
9418
9539
|
}
|
|
9419
9540
|
function formatComposeOutput(name, versionId, content, variableSources) {
|
|
9420
|
-
console.log(
|
|
9421
|
-
console.log(
|
|
9541
|
+
console.log(chalk38.bold("Name:") + ` ${name}`);
|
|
9542
|
+
console.log(chalk38.bold("Version:") + ` ${versionId}`);
|
|
9422
9543
|
console.log();
|
|
9423
|
-
console.log(
|
|
9544
|
+
console.log(chalk38.bold("Agents:"));
|
|
9424
9545
|
for (const [agentName, agent] of Object.entries(content.agents)) {
|
|
9425
9546
|
const agentSources = variableSources?.get(agentName);
|
|
9426
9547
|
formatAgentDetails(agentName, agent, agentSources, content.volumes);
|
|
9427
9548
|
}
|
|
9428
9549
|
}
|
|
9429
|
-
var statusCommand5 = new
|
|
9550
|
+
var statusCommand5 = new Command37().name("status").description("Show status of agent compose").argument(
|
|
9430
9551
|
"<name[:version]>",
|
|
9431
9552
|
"Agent name with optional version (e.g., my-agent:latest or my-agent:a1b2c3d4)"
|
|
9432
9553
|
).option("--no-sources", "Skip fetching skills to determine variable sources").action(async (argument, options) => {
|
|
@@ -9443,8 +9564,8 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9443
9564
|
}
|
|
9444
9565
|
const compose = await getComposeByName(name);
|
|
9445
9566
|
if (!compose) {
|
|
9446
|
-
console.error(
|
|
9447
|
-
console.error(
|
|
9567
|
+
console.error(chalk38.red(`\u2717 Agent compose not found: ${name}`));
|
|
9568
|
+
console.error(chalk38.dim(" Run: vm0 agent list"));
|
|
9448
9569
|
process.exit(1);
|
|
9449
9570
|
}
|
|
9450
9571
|
let resolvedVersionId = compose.headVersionId;
|
|
@@ -9455,9 +9576,9 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9455
9576
|
resolvedVersionId = versionInfo.versionId;
|
|
9456
9577
|
} catch (error) {
|
|
9457
9578
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
9458
|
-
console.error(
|
|
9579
|
+
console.error(chalk38.red(`\u2717 Version not found: ${version}`));
|
|
9459
9580
|
console.error(
|
|
9460
|
-
|
|
9581
|
+
chalk38.dim(
|
|
9461
9582
|
` HEAD version: ${compose.headVersionId?.slice(0, 8)}`
|
|
9462
9583
|
)
|
|
9463
9584
|
);
|
|
@@ -9470,7 +9591,7 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9470
9591
|
}
|
|
9471
9592
|
}
|
|
9472
9593
|
if (!resolvedVersionId || !compose.content) {
|
|
9473
|
-
console.error(
|
|
9594
|
+
console.error(chalk38.red(`\u2717 No version found for: ${name}`));
|
|
9474
9595
|
process.exit(1);
|
|
9475
9596
|
}
|
|
9476
9597
|
const content = compose.content;
|
|
@@ -9481,7 +9602,7 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9481
9602
|
});
|
|
9482
9603
|
} catch {
|
|
9483
9604
|
console.error(
|
|
9484
|
-
|
|
9605
|
+
chalk38.yellow(
|
|
9485
9606
|
"\u26A0 Warning: Failed to fetch skill sources, showing basic info"
|
|
9486
9607
|
)
|
|
9487
9608
|
);
|
|
@@ -9493,12 +9614,12 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9493
9614
|
variableSources
|
|
9494
9615
|
);
|
|
9495
9616
|
} catch (error) {
|
|
9496
|
-
console.error(
|
|
9617
|
+
console.error(chalk38.red("\u2717 Failed to get agent compose status"));
|
|
9497
9618
|
if (error instanceof Error) {
|
|
9498
9619
|
if (error.message.includes("Not authenticated")) {
|
|
9499
|
-
console.error(
|
|
9620
|
+
console.error(chalk38.dim(" Run: vm0 auth login"));
|
|
9500
9621
|
} else {
|
|
9501
|
-
console.error(
|
|
9622
|
+
console.error(chalk38.dim(` ${error.message}`));
|
|
9502
9623
|
}
|
|
9503
9624
|
}
|
|
9504
9625
|
process.exit(1);
|
|
@@ -9506,14 +9627,14 @@ var statusCommand5 = new Command36().name("status").description("Show status of
|
|
|
9506
9627
|
});
|
|
9507
9628
|
|
|
9508
9629
|
// src/commands/agent/index.ts
|
|
9509
|
-
var agentCommand = new
|
|
9630
|
+
var agentCommand = new Command38().name("agent").description("Manage agent composes").addCommand(cloneCommand3).addCommand(listCommand4).addCommand(statusCommand5);
|
|
9510
9631
|
|
|
9511
9632
|
// src/commands/init/index.ts
|
|
9512
|
-
import { Command as
|
|
9513
|
-
import
|
|
9633
|
+
import { Command as Command39 } from "commander";
|
|
9634
|
+
import chalk39 from "chalk";
|
|
9514
9635
|
import path15 from "path";
|
|
9515
|
-
import { existsSync as
|
|
9516
|
-
import { writeFile as
|
|
9636
|
+
import { existsSync as existsSync11 } from "fs";
|
|
9637
|
+
import { writeFile as writeFile7 } from "fs/promises";
|
|
9517
9638
|
var VM0_YAML_FILE = "vm0.yaml";
|
|
9518
9639
|
var AGENTS_MD_FILE = "AGENTS.md";
|
|
9519
9640
|
function generateVm0Yaml(agentName) {
|
|
@@ -9544,18 +9665,18 @@ You are a HackerNews AI content curator.
|
|
|
9544
9665
|
}
|
|
9545
9666
|
function checkExistingFiles() {
|
|
9546
9667
|
const existingFiles = [];
|
|
9547
|
-
if (
|
|
9548
|
-
if (
|
|
9668
|
+
if (existsSync11(VM0_YAML_FILE)) existingFiles.push(VM0_YAML_FILE);
|
|
9669
|
+
if (existsSync11(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
9549
9670
|
return existingFiles;
|
|
9550
9671
|
}
|
|
9551
|
-
var initCommand3 = new
|
|
9672
|
+
var initCommand3 = new Command39().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (required in non-interactive mode)").action(async (options) => {
|
|
9552
9673
|
const existingFiles = checkExistingFiles();
|
|
9553
9674
|
if (existingFiles.length > 0 && !options.force) {
|
|
9554
9675
|
for (const file of existingFiles) {
|
|
9555
|
-
console.log(
|
|
9676
|
+
console.log(chalk39.red(`\u2717 ${file} already exists`));
|
|
9556
9677
|
}
|
|
9557
9678
|
console.log();
|
|
9558
|
-
console.log(`To overwrite: ${
|
|
9679
|
+
console.log(`To overwrite: ${chalk39.cyan("vm0 init --force")}`);
|
|
9559
9680
|
process.exit(1);
|
|
9560
9681
|
}
|
|
9561
9682
|
let agentName;
|
|
@@ -9563,9 +9684,9 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9563
9684
|
agentName = options.name.trim();
|
|
9564
9685
|
} else if (!isInteractive()) {
|
|
9565
9686
|
console.error(
|
|
9566
|
-
|
|
9687
|
+
chalk39.red("\u2717 --name flag is required in non-interactive mode")
|
|
9567
9688
|
);
|
|
9568
|
-
console.error(
|
|
9689
|
+
console.error(chalk39.dim(" Usage: vm0 init --name <agent-name>"));
|
|
9569
9690
|
process.exit(1);
|
|
9570
9691
|
} else {
|
|
9571
9692
|
const dirName = path15.basename(process.cwd());
|
|
@@ -9581,47 +9702,47 @@ var initCommand3 = new Command38().name("init").description("Initialize a new VM
|
|
|
9581
9702
|
}
|
|
9582
9703
|
);
|
|
9583
9704
|
if (name === void 0) {
|
|
9584
|
-
console.log(
|
|
9705
|
+
console.log(chalk39.dim("Cancelled"));
|
|
9585
9706
|
return;
|
|
9586
9707
|
}
|
|
9587
9708
|
agentName = name;
|
|
9588
9709
|
}
|
|
9589
9710
|
if (!agentName || !validateAgentName(agentName)) {
|
|
9590
|
-
console.log(
|
|
9711
|
+
console.log(chalk39.red("\u2717 Invalid agent name"));
|
|
9591
9712
|
console.log(
|
|
9592
|
-
|
|
9713
|
+
chalk39.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
|
|
9593
9714
|
);
|
|
9594
|
-
console.log(
|
|
9715
|
+
console.log(chalk39.dim(" Must start and end with letter or number"));
|
|
9595
9716
|
process.exit(1);
|
|
9596
9717
|
}
|
|
9597
|
-
await
|
|
9718
|
+
await writeFile7(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
9598
9719
|
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
9599
|
-
console.log(
|
|
9600
|
-
await
|
|
9720
|
+
console.log(chalk39.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
9721
|
+
await writeFile7(AGENTS_MD_FILE, generateAgentsMd());
|
|
9601
9722
|
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
9602
|
-
console.log(
|
|
9723
|
+
console.log(chalk39.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
9603
9724
|
console.log();
|
|
9604
9725
|
console.log("Next steps:");
|
|
9605
9726
|
console.log(
|
|
9606
|
-
` 1. Set up model provider (one-time): ${
|
|
9727
|
+
` 1. Set up model provider (one-time): ${chalk39.cyan("vm0 model-provider setup")}`
|
|
9607
9728
|
);
|
|
9608
9729
|
console.log(
|
|
9609
|
-
` 2. Edit ${
|
|
9730
|
+
` 2. Edit ${chalk39.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
9610
9731
|
);
|
|
9611
9732
|
console.log(
|
|
9612
|
-
` Or install Claude plugin: ${
|
|
9733
|
+
` Or install Claude plugin: ${chalk39.cyan(`vm0 setup-claude && claude "/vm0-agent let's build an agent"`)}`
|
|
9613
9734
|
);
|
|
9614
9735
|
console.log(
|
|
9615
|
-
` 3. Run your agent: ${
|
|
9736
|
+
` 3. Run your agent: ${chalk39.cyan(`vm0 cook "let's start working"`)}`
|
|
9616
9737
|
);
|
|
9617
9738
|
});
|
|
9618
9739
|
|
|
9619
9740
|
// src/commands/schedule/index.ts
|
|
9620
|
-
import { Command as
|
|
9741
|
+
import { Command as Command46 } from "commander";
|
|
9621
9742
|
|
|
9622
9743
|
// src/commands/schedule/setup.ts
|
|
9623
|
-
import { Command as
|
|
9624
|
-
import
|
|
9744
|
+
import { Command as Command40 } from "commander";
|
|
9745
|
+
import chalk41 from "chalk";
|
|
9625
9746
|
|
|
9626
9747
|
// src/lib/domain/schedule-utils.ts
|
|
9627
9748
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -9763,7 +9884,7 @@ async function resolveScheduleByAgent(agentName) {
|
|
|
9763
9884
|
}
|
|
9764
9885
|
|
|
9765
9886
|
// src/commands/schedule/gather-configuration.ts
|
|
9766
|
-
import
|
|
9887
|
+
import chalk40 from "chalk";
|
|
9767
9888
|
var defaultPromptDeps = {
|
|
9768
9889
|
isInteractive,
|
|
9769
9890
|
promptConfirm,
|
|
@@ -9797,7 +9918,7 @@ async function handleSecrets(optionSecrets, existingSecretNames, deps) {
|
|
|
9797
9918
|
if (keepSecrets) {
|
|
9798
9919
|
return { secrets: {}, preserveExistingSecrets: true };
|
|
9799
9920
|
}
|
|
9800
|
-
console.log(
|
|
9921
|
+
console.log(chalk40.dim(" Note: You'll need to provide new secret values"));
|
|
9801
9922
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
9802
9923
|
}
|
|
9803
9924
|
return { secrets: {}, preserveExistingSecrets: false };
|
|
@@ -9818,17 +9939,17 @@ async function handleVars(optionVars, existingVars, deps) {
|
|
|
9818
9939
|
return {};
|
|
9819
9940
|
}
|
|
9820
9941
|
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
9821
|
-
console.log(
|
|
9942
|
+
console.log(chalk40.yellow("\nAgent requires the following configuration:"));
|
|
9822
9943
|
if (missingSecrets.length > 0) {
|
|
9823
|
-
console.log(
|
|
9944
|
+
console.log(chalk40.dim(" Secrets:"));
|
|
9824
9945
|
for (const name of missingSecrets) {
|
|
9825
|
-
console.log(
|
|
9946
|
+
console.log(chalk40.dim(` ${name}`));
|
|
9826
9947
|
}
|
|
9827
9948
|
}
|
|
9828
9949
|
if (missingVars.length > 0) {
|
|
9829
|
-
console.log(
|
|
9950
|
+
console.log(chalk40.dim(" Vars:"));
|
|
9830
9951
|
for (const name of missingVars) {
|
|
9831
|
-
console.log(
|
|
9952
|
+
console.log(chalk40.dim(` ${name}`));
|
|
9832
9953
|
}
|
|
9833
9954
|
}
|
|
9834
9955
|
console.log("");
|
|
@@ -9836,7 +9957,7 @@ function displayMissingRequirements(missingSecrets, missingVars) {
|
|
|
9836
9957
|
async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
9837
9958
|
for (const name of missingSecrets) {
|
|
9838
9959
|
const value = await deps.promptPassword(
|
|
9839
|
-
`Enter value for secret ${
|
|
9960
|
+
`Enter value for secret ${chalk40.cyan(name)}`
|
|
9840
9961
|
);
|
|
9841
9962
|
if (value) {
|
|
9842
9963
|
secrets[name] = value;
|
|
@@ -9846,7 +9967,7 @@ async function promptForMissingSecrets(missingSecrets, secrets, deps) {
|
|
|
9846
9967
|
async function promptForMissingVars(missingVars, vars, deps) {
|
|
9847
9968
|
for (const name of missingVars) {
|
|
9848
9969
|
const value = await deps.promptText(
|
|
9849
|
-
`Enter value for var ${
|
|
9970
|
+
`Enter value for var ${chalk40.cyan(name)}`,
|
|
9850
9971
|
""
|
|
9851
9972
|
);
|
|
9852
9973
|
if (value) {
|
|
@@ -9936,7 +10057,7 @@ function expandEnvVars(value) {
|
|
|
9936
10057
|
const envValue = process.env[varName];
|
|
9937
10058
|
if (envValue === void 0) {
|
|
9938
10059
|
console.warn(
|
|
9939
|
-
|
|
10060
|
+
chalk41.yellow(` Warning: Environment variable ${varName} not set`)
|
|
9940
10061
|
);
|
|
9941
10062
|
return match;
|
|
9942
10063
|
}
|
|
@@ -10003,7 +10124,7 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
|
|
|
10003
10124
|
}
|
|
10004
10125
|
if (!isInteractive()) {
|
|
10005
10126
|
console.error(
|
|
10006
|
-
|
|
10127
|
+
chalk41.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
|
|
10007
10128
|
);
|
|
10008
10129
|
process.exit(1);
|
|
10009
10130
|
}
|
|
@@ -10023,7 +10144,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10023
10144
|
const day2 = parseDayOption(optionDay, frequency);
|
|
10024
10145
|
if (day2 === void 0) {
|
|
10025
10146
|
console.error(
|
|
10026
|
-
|
|
10147
|
+
chalk41.red(
|
|
10027
10148
|
`\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
10028
10149
|
)
|
|
10029
10150
|
);
|
|
@@ -10032,7 +10153,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10032
10153
|
return day2;
|
|
10033
10154
|
}
|
|
10034
10155
|
if (!isInteractive()) {
|
|
10035
|
-
console.error(
|
|
10156
|
+
console.error(chalk41.red("\u2717 --day is required for weekly/monthly"));
|
|
10036
10157
|
process.exit(1);
|
|
10037
10158
|
}
|
|
10038
10159
|
if (frequency === "weekly") {
|
|
@@ -10051,7 +10172,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10051
10172
|
if (!dayStr) return null;
|
|
10052
10173
|
const day = parseInt(dayStr, 10);
|
|
10053
10174
|
if (isNaN(day) || day < 1 || day > 31) {
|
|
10054
|
-
console.error(
|
|
10175
|
+
console.error(chalk41.red("\u2717 Day must be between 1 and 31"));
|
|
10055
10176
|
process.exit(1);
|
|
10056
10177
|
}
|
|
10057
10178
|
return day;
|
|
@@ -10060,13 +10181,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
|
|
|
10060
10181
|
if (optionTime) {
|
|
10061
10182
|
const validation = validateTimeFormat(optionTime);
|
|
10062
10183
|
if (validation !== true) {
|
|
10063
|
-
console.error(
|
|
10184
|
+
console.error(chalk41.red(`\u2717 Invalid time: ${validation}`));
|
|
10064
10185
|
process.exit(1);
|
|
10065
10186
|
}
|
|
10066
10187
|
return optionTime;
|
|
10067
10188
|
}
|
|
10068
10189
|
if (!isInteractive()) {
|
|
10069
|
-
console.error(
|
|
10190
|
+
console.error(chalk41.red("\u2717 --time is required (HH:MM format)"));
|
|
10070
10191
|
process.exit(1);
|
|
10071
10192
|
}
|
|
10072
10193
|
return await promptText(
|
|
@@ -10079,7 +10200,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
10079
10200
|
if (optionDay && optionTime) {
|
|
10080
10201
|
if (!validateDateFormat(optionDay)) {
|
|
10081
10202
|
console.error(
|
|
10082
|
-
|
|
10203
|
+
chalk41.red(
|
|
10083
10204
|
`\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
|
|
10084
10205
|
)
|
|
10085
10206
|
);
|
|
@@ -10087,16 +10208,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
10087
10208
|
}
|
|
10088
10209
|
if (!validateTimeFormat(optionTime)) {
|
|
10089
10210
|
console.error(
|
|
10090
|
-
|
|
10211
|
+
chalk41.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
|
|
10091
10212
|
);
|
|
10092
10213
|
process.exit(1);
|
|
10093
10214
|
}
|
|
10094
10215
|
return `${optionDay} ${optionTime}`;
|
|
10095
10216
|
}
|
|
10096
10217
|
if (!isInteractive()) {
|
|
10097
|
-
console.error(
|
|
10218
|
+
console.error(chalk41.red("\u2717 One-time schedules require interactive mode"));
|
|
10098
10219
|
console.error(
|
|
10099
|
-
|
|
10220
|
+
chalk41.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
|
|
10100
10221
|
);
|
|
10101
10222
|
process.exit(1);
|
|
10102
10223
|
}
|
|
@@ -10127,7 +10248,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
|
|
|
10127
10248
|
async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
10128
10249
|
if (optionPrompt) return optionPrompt;
|
|
10129
10250
|
if (!isInteractive()) {
|
|
10130
|
-
console.error(
|
|
10251
|
+
console.error(chalk41.red("\u2717 --prompt is required"));
|
|
10131
10252
|
process.exit(1);
|
|
10132
10253
|
}
|
|
10133
10254
|
return await promptText(
|
|
@@ -10138,8 +10259,8 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
10138
10259
|
async function resolveAgent(agentName) {
|
|
10139
10260
|
const compose = await getComposeByName(agentName);
|
|
10140
10261
|
if (!compose) {
|
|
10141
|
-
console.error(
|
|
10142
|
-
console.error(
|
|
10262
|
+
console.error(chalk41.red(`\u2717 Agent not found: ${agentName}`));
|
|
10263
|
+
console.error(chalk41.dim(" Make sure the agent is composed first"));
|
|
10143
10264
|
process.exit(1);
|
|
10144
10265
|
}
|
|
10145
10266
|
return {
|
|
@@ -10186,7 +10307,7 @@ async function buildAndDeploy(params) {
|
|
|
10186
10307
|
const expandedSecrets = expandEnvVarsInObject(params.secrets);
|
|
10187
10308
|
console.log(
|
|
10188
10309
|
`
|
|
10189
|
-
Deploying schedule for agent ${
|
|
10310
|
+
Deploying schedule for agent ${chalk41.cyan(params.agentName)}...`
|
|
10190
10311
|
);
|
|
10191
10312
|
const deployResult = await deploySchedule({
|
|
10192
10313
|
name: params.scheduleName,
|
|
@@ -10202,12 +10323,12 @@ Deploying schedule for agent ${chalk40.cyan(params.agentName)}...`
|
|
|
10202
10323
|
return deployResult;
|
|
10203
10324
|
}
|
|
10204
10325
|
function handleSetupError(error) {
|
|
10205
|
-
console.error(
|
|
10326
|
+
console.error(chalk41.red("\u2717 Failed to setup schedule"));
|
|
10206
10327
|
if (error instanceof Error) {
|
|
10207
10328
|
if (error.message.includes("Not authenticated")) {
|
|
10208
|
-
console.error(
|
|
10329
|
+
console.error(chalk41.dim(" Run: vm0 auth login"));
|
|
10209
10330
|
} else {
|
|
10210
|
-
console.error(
|
|
10331
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
10211
10332
|
}
|
|
10212
10333
|
}
|
|
10213
10334
|
process.exit(1);
|
|
@@ -10215,56 +10336,56 @@ function handleSetupError(error) {
|
|
|
10215
10336
|
function displayDeployResult(agentName, deployResult) {
|
|
10216
10337
|
if (deployResult.created) {
|
|
10217
10338
|
console.log(
|
|
10218
|
-
|
|
10339
|
+
chalk41.green(`\u2713 Created schedule for agent ${chalk41.cyan(agentName)}`)
|
|
10219
10340
|
);
|
|
10220
10341
|
} else {
|
|
10221
10342
|
console.log(
|
|
10222
|
-
|
|
10343
|
+
chalk41.green(`\u2713 Updated schedule for agent ${chalk41.cyan(agentName)}`)
|
|
10223
10344
|
);
|
|
10224
10345
|
}
|
|
10225
|
-
console.log(
|
|
10346
|
+
console.log(chalk41.dim(` Timezone: ${deployResult.schedule.timezone}`));
|
|
10226
10347
|
if (deployResult.schedule.cronExpression) {
|
|
10227
|
-
console.log(
|
|
10348
|
+
console.log(chalk41.dim(` Cron: ${deployResult.schedule.cronExpression}`));
|
|
10228
10349
|
if (deployResult.schedule.nextRunAt) {
|
|
10229
10350
|
const nextRun = formatInTimezone(
|
|
10230
10351
|
deployResult.schedule.nextRunAt,
|
|
10231
10352
|
deployResult.schedule.timezone
|
|
10232
10353
|
);
|
|
10233
|
-
console.log(
|
|
10354
|
+
console.log(chalk41.dim(` Next run: ${nextRun}`));
|
|
10234
10355
|
}
|
|
10235
10356
|
} else if (deployResult.schedule.atTime) {
|
|
10236
10357
|
const atTimeFormatted = formatInTimezone(
|
|
10237
10358
|
deployResult.schedule.atTime,
|
|
10238
10359
|
deployResult.schedule.timezone
|
|
10239
10360
|
);
|
|
10240
|
-
console.log(
|
|
10361
|
+
console.log(chalk41.dim(` At: ${atTimeFormatted}`));
|
|
10241
10362
|
}
|
|
10242
10363
|
}
|
|
10243
10364
|
async function tryEnableSchedule(scheduleName, composeId, agentName) {
|
|
10244
10365
|
try {
|
|
10245
10366
|
await enableSchedule({ name: scheduleName, composeId });
|
|
10246
10367
|
console.log(
|
|
10247
|
-
|
|
10368
|
+
chalk41.green(`\u2713 Enabled schedule for agent ${chalk41.cyan(agentName)}`)
|
|
10248
10369
|
);
|
|
10249
10370
|
} catch (error) {
|
|
10250
|
-
console.error(
|
|
10371
|
+
console.error(chalk41.yellow("\u26A0 Failed to enable schedule"));
|
|
10251
10372
|
if (error instanceof ApiRequestError) {
|
|
10252
10373
|
if (error.code === "SCHEDULE_PAST") {
|
|
10253
|
-
console.error(
|
|
10374
|
+
console.error(chalk41.dim(" Scheduled time has already passed"));
|
|
10254
10375
|
} else {
|
|
10255
|
-
console.error(
|
|
10376
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
10256
10377
|
}
|
|
10257
10378
|
} else if (error instanceof Error) {
|
|
10258
|
-
console.error(
|
|
10379
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
10259
10380
|
}
|
|
10260
10381
|
console.log(
|
|
10261
|
-
` To enable manually: ${
|
|
10382
|
+
` To enable manually: ${chalk41.cyan(`vm0 schedule enable ${agentName}`)}`
|
|
10262
10383
|
);
|
|
10263
10384
|
}
|
|
10264
10385
|
}
|
|
10265
10386
|
function showEnableHint(agentName) {
|
|
10266
10387
|
console.log();
|
|
10267
|
-
console.log(` To enable: ${
|
|
10388
|
+
console.log(` To enable: ${chalk41.cyan(`vm0 schedule enable ${agentName}`)}`);
|
|
10268
10389
|
}
|
|
10269
10390
|
async function handleScheduleEnabling(params) {
|
|
10270
10391
|
const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
|
|
@@ -10285,13 +10406,13 @@ async function handleScheduleEnabling(params) {
|
|
|
10285
10406
|
showEnableHint(agentName);
|
|
10286
10407
|
}
|
|
10287
10408
|
}
|
|
10288
|
-
var setupCommand = new
|
|
10409
|
+
var setupCommand = new Command40().name("setup").description("Create or edit a schedule for an agent").argument("<agent-name>", "Agent name to configure schedule for").option("-f, --frequency <type>", "Frequency: daily|weekly|monthly|once").option("-t, --time <HH:MM>", "Time to run (24-hour format)").option("-d, --day <day>", "Day of week (mon-sun) or day of month (1-31)").option("-z, --timezone <tz>", "IANA timezone").option("-p, --prompt <text>", "Prompt to run").option("--var <name=value>", "Variable (can be repeated)", collect, []).option("--secret <name=value>", "Secret (can be repeated)", collect, []).option("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
|
|
10289
10410
|
try {
|
|
10290
10411
|
const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
|
|
10291
10412
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
10292
10413
|
const existingSchedule = await findExistingSchedule(agentName);
|
|
10293
10414
|
console.log(
|
|
10294
|
-
|
|
10415
|
+
chalk41.dim(
|
|
10295
10416
|
existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
|
|
10296
10417
|
)
|
|
10297
10418
|
);
|
|
@@ -10301,12 +10422,12 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
10301
10422
|
defaults.frequency
|
|
10302
10423
|
);
|
|
10303
10424
|
if (!frequency) {
|
|
10304
|
-
console.log(
|
|
10425
|
+
console.log(chalk41.dim("Cancelled"));
|
|
10305
10426
|
return;
|
|
10306
10427
|
}
|
|
10307
10428
|
const timing = await gatherTiming(frequency, options, defaults);
|
|
10308
10429
|
if (!timing) {
|
|
10309
|
-
console.log(
|
|
10430
|
+
console.log(chalk41.dim("Cancelled"));
|
|
10310
10431
|
return;
|
|
10311
10432
|
}
|
|
10312
10433
|
const { day, time, atTime } = timing;
|
|
@@ -10315,7 +10436,7 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
10315
10436
|
existingSchedule?.timezone
|
|
10316
10437
|
);
|
|
10317
10438
|
if (!timezone) {
|
|
10318
|
-
console.log(
|
|
10439
|
+
console.log(chalk41.dim("Cancelled"));
|
|
10319
10440
|
return;
|
|
10320
10441
|
}
|
|
10321
10442
|
const promptText_ = await gatherPromptText(
|
|
@@ -10323,7 +10444,7 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
10323
10444
|
existingSchedule?.prompt
|
|
10324
10445
|
);
|
|
10325
10446
|
if (!promptText_) {
|
|
10326
|
-
console.log(
|
|
10447
|
+
console.log(chalk41.dim("Cancelled"));
|
|
10327
10448
|
return;
|
|
10328
10449
|
}
|
|
10329
10450
|
const config = await gatherConfiguration({
|
|
@@ -10361,15 +10482,15 @@ var setupCommand = new Command39().name("setup").description("Create or edit a s
|
|
|
10361
10482
|
});
|
|
10362
10483
|
|
|
10363
10484
|
// src/commands/schedule/list.ts
|
|
10364
|
-
import { Command as
|
|
10365
|
-
import
|
|
10366
|
-
var listCommand5 = new
|
|
10485
|
+
import { Command as Command41 } from "commander";
|
|
10486
|
+
import chalk42 from "chalk";
|
|
10487
|
+
var listCommand5 = new Command41().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
10367
10488
|
try {
|
|
10368
10489
|
const result = await listSchedules();
|
|
10369
10490
|
if (result.schedules.length === 0) {
|
|
10370
|
-
console.log(
|
|
10491
|
+
console.log(chalk42.dim("No schedules found"));
|
|
10371
10492
|
console.log(
|
|
10372
|
-
|
|
10493
|
+
chalk42.dim(" Create one with: vm0 schedule setup <agent-name>")
|
|
10373
10494
|
);
|
|
10374
10495
|
return;
|
|
10375
10496
|
}
|
|
@@ -10389,10 +10510,10 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
10389
10510
|
"STATUS".padEnd(8),
|
|
10390
10511
|
"NEXT RUN"
|
|
10391
10512
|
].join(" ");
|
|
10392
|
-
console.log(
|
|
10513
|
+
console.log(chalk42.dim(header));
|
|
10393
10514
|
for (const schedule of result.schedules) {
|
|
10394
10515
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
10395
|
-
const status = schedule.enabled ?
|
|
10516
|
+
const status = schedule.enabled ? chalk42.green("enabled") : chalk42.yellow("disabled");
|
|
10396
10517
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
10397
10518
|
const row = [
|
|
10398
10519
|
schedule.composeName.padEnd(agentWidth),
|
|
@@ -10404,12 +10525,12 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
10404
10525
|
console.log(row);
|
|
10405
10526
|
}
|
|
10406
10527
|
} catch (error) {
|
|
10407
|
-
console.error(
|
|
10528
|
+
console.error(chalk42.red("\u2717 Failed to list schedules"));
|
|
10408
10529
|
if (error instanceof Error) {
|
|
10409
10530
|
if (error.message.includes("Not authenticated")) {
|
|
10410
|
-
console.error(
|
|
10531
|
+
console.error(chalk42.dim(" Run: vm0 auth login"));
|
|
10411
10532
|
} else {
|
|
10412
|
-
console.error(
|
|
10533
|
+
console.error(chalk42.dim(` ${error.message}`));
|
|
10413
10534
|
}
|
|
10414
10535
|
}
|
|
10415
10536
|
process.exit(1);
|
|
@@ -10417,45 +10538,45 @@ var listCommand5 = new Command40().name("list").alias("ls").description("List al
|
|
|
10417
10538
|
});
|
|
10418
10539
|
|
|
10419
10540
|
// src/commands/schedule/status.ts
|
|
10420
|
-
import { Command as
|
|
10421
|
-
import
|
|
10541
|
+
import { Command as Command42 } from "commander";
|
|
10542
|
+
import chalk43 from "chalk";
|
|
10422
10543
|
function formatDateTimeStyled(dateStr) {
|
|
10423
|
-
if (!dateStr) return
|
|
10544
|
+
if (!dateStr) return chalk43.dim("-");
|
|
10424
10545
|
const formatted = formatDateTime(dateStr);
|
|
10425
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
10546
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk43.dim("($1)"));
|
|
10426
10547
|
}
|
|
10427
10548
|
function formatTrigger(schedule) {
|
|
10428
10549
|
if (schedule.cronExpression) {
|
|
10429
10550
|
return schedule.cronExpression;
|
|
10430
10551
|
}
|
|
10431
10552
|
if (schedule.atTime) {
|
|
10432
|
-
return `${schedule.atTime} ${
|
|
10553
|
+
return `${schedule.atTime} ${chalk43.dim("(one-time)")}`;
|
|
10433
10554
|
}
|
|
10434
|
-
return
|
|
10555
|
+
return chalk43.dim("-");
|
|
10435
10556
|
}
|
|
10436
10557
|
function formatRunStatus2(status) {
|
|
10437
10558
|
switch (status) {
|
|
10438
10559
|
case "completed":
|
|
10439
|
-
return
|
|
10560
|
+
return chalk43.green(status);
|
|
10440
10561
|
case "failed":
|
|
10441
10562
|
case "timeout":
|
|
10442
|
-
return
|
|
10563
|
+
return chalk43.red(status);
|
|
10443
10564
|
case "running":
|
|
10444
|
-
return
|
|
10565
|
+
return chalk43.blue(status);
|
|
10445
10566
|
case "pending":
|
|
10446
|
-
return
|
|
10567
|
+
return chalk43.yellow(status);
|
|
10447
10568
|
default:
|
|
10448
10569
|
return status;
|
|
10449
10570
|
}
|
|
10450
10571
|
}
|
|
10451
10572
|
function printRunConfiguration(schedule) {
|
|
10452
|
-
const statusText = schedule.enabled ?
|
|
10573
|
+
const statusText = schedule.enabled ? chalk43.green("enabled") : chalk43.yellow("disabled");
|
|
10453
10574
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
10454
10575
|
console.log(
|
|
10455
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
10576
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk43.dim(`(${schedule.scopeSlug})`)}`
|
|
10456
10577
|
);
|
|
10457
10578
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
10458
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
10579
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk43.dim(promptPreview)}`);
|
|
10459
10580
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
10460
10581
|
console.log(
|
|
10461
10582
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -10492,7 +10613,7 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
10492
10613
|
console.log();
|
|
10493
10614
|
console.log("Recent Runs:");
|
|
10494
10615
|
console.log(
|
|
10495
|
-
|
|
10616
|
+
chalk43.dim("RUN ID STATUS CREATED")
|
|
10496
10617
|
);
|
|
10497
10618
|
for (const run of runs) {
|
|
10498
10619
|
const id = run.id;
|
|
@@ -10503,24 +10624,24 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
10503
10624
|
}
|
|
10504
10625
|
} catch {
|
|
10505
10626
|
console.log();
|
|
10506
|
-
console.log(
|
|
10627
|
+
console.log(chalk43.dim("Recent Runs: (unable to fetch)"));
|
|
10507
10628
|
}
|
|
10508
10629
|
}
|
|
10509
10630
|
function handleStatusError(error, agentName) {
|
|
10510
|
-
console.error(
|
|
10631
|
+
console.error(chalk43.red("\u2717 Failed to get schedule status"));
|
|
10511
10632
|
if (error instanceof Error) {
|
|
10512
10633
|
if (error.message.includes("Not authenticated")) {
|
|
10513
|
-
console.error(
|
|
10634
|
+
console.error(chalk43.dim(" Run: vm0 auth login"));
|
|
10514
10635
|
} else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
|
|
10515
|
-
console.error(
|
|
10516
|
-
console.error(
|
|
10636
|
+
console.error(chalk43.dim(` No schedule found for agent "${agentName}"`));
|
|
10637
|
+
console.error(chalk43.dim(" Run: vm0 schedule list"));
|
|
10517
10638
|
} else {
|
|
10518
|
-
console.error(
|
|
10639
|
+
console.error(chalk43.dim(` ${error.message}`));
|
|
10519
10640
|
}
|
|
10520
10641
|
}
|
|
10521
10642
|
process.exit(1);
|
|
10522
10643
|
}
|
|
10523
|
-
var statusCommand6 = new
|
|
10644
|
+
var statusCommand6 = new Command42().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
|
|
10524
10645
|
"-l, --limit <number>",
|
|
10525
10646
|
"Number of recent runs to show (0 to hide)",
|
|
10526
10647
|
"5"
|
|
@@ -10530,8 +10651,8 @@ var statusCommand6 = new Command41().name("status").description("Show detailed s
|
|
|
10530
10651
|
const { name, composeId } = resolved;
|
|
10531
10652
|
const schedule = await getScheduleByName({ name, composeId });
|
|
10532
10653
|
console.log();
|
|
10533
|
-
console.log(`Schedule for agent: ${
|
|
10534
|
-
console.log(
|
|
10654
|
+
console.log(`Schedule for agent: ${chalk43.cyan(agentName)}`);
|
|
10655
|
+
console.log(chalk43.dim("\u2501".repeat(50)));
|
|
10535
10656
|
printRunConfiguration(schedule);
|
|
10536
10657
|
printTimeSchedule(schedule);
|
|
10537
10658
|
const parsed = parseInt(options.limit, 10);
|
|
@@ -10547,24 +10668,24 @@ var statusCommand6 = new Command41().name("status").description("Show detailed s
|
|
|
10547
10668
|
});
|
|
10548
10669
|
|
|
10549
10670
|
// src/commands/schedule/delete.ts
|
|
10550
|
-
import { Command as
|
|
10551
|
-
import
|
|
10552
|
-
var deleteCommand = new
|
|
10671
|
+
import { Command as Command43 } from "commander";
|
|
10672
|
+
import chalk44 from "chalk";
|
|
10673
|
+
var deleteCommand = new Command43().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
|
|
10553
10674
|
try {
|
|
10554
10675
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10555
10676
|
if (!options.force) {
|
|
10556
10677
|
if (!isInteractive()) {
|
|
10557
10678
|
console.error(
|
|
10558
|
-
|
|
10679
|
+
chalk44.red("\u2717 --force required in non-interactive mode")
|
|
10559
10680
|
);
|
|
10560
10681
|
process.exit(1);
|
|
10561
10682
|
}
|
|
10562
10683
|
const confirmed = await promptConfirm(
|
|
10563
|
-
`Delete schedule for agent ${
|
|
10684
|
+
`Delete schedule for agent ${chalk44.cyan(agentName)}?`,
|
|
10564
10685
|
false
|
|
10565
10686
|
);
|
|
10566
10687
|
if (!confirmed) {
|
|
10567
|
-
console.log(
|
|
10688
|
+
console.log(chalk44.dim("Cancelled"));
|
|
10568
10689
|
return;
|
|
10569
10690
|
}
|
|
10570
10691
|
}
|
|
@@ -10573,20 +10694,20 @@ var deleteCommand = new Command42().name("delete").alias("rm").description("Dele
|
|
|
10573
10694
|
composeId: resolved.composeId
|
|
10574
10695
|
});
|
|
10575
10696
|
console.log(
|
|
10576
|
-
|
|
10697
|
+
chalk44.green(`\u2713 Deleted schedule for agent ${chalk44.cyan(agentName)}`)
|
|
10577
10698
|
);
|
|
10578
10699
|
} catch (error) {
|
|
10579
|
-
console.error(
|
|
10700
|
+
console.error(chalk44.red("\u2717 Failed to delete schedule"));
|
|
10580
10701
|
if (error instanceof Error) {
|
|
10581
10702
|
if (error.message.includes("Not authenticated")) {
|
|
10582
|
-
console.error(
|
|
10703
|
+
console.error(chalk44.dim(" Run: vm0 auth login"));
|
|
10583
10704
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
10584
10705
|
console.error(
|
|
10585
|
-
|
|
10706
|
+
chalk44.dim(` No schedule found for agent "${agentName}"`)
|
|
10586
10707
|
);
|
|
10587
|
-
console.error(
|
|
10708
|
+
console.error(chalk44.dim(" Run: vm0 schedule list"));
|
|
10588
10709
|
} else {
|
|
10589
|
-
console.error(
|
|
10710
|
+
console.error(chalk44.dim(` ${error.message}`));
|
|
10590
10711
|
}
|
|
10591
10712
|
}
|
|
10592
10713
|
process.exit(1);
|
|
@@ -10594,9 +10715,9 @@ var deleteCommand = new Command42().name("delete").alias("rm").description("Dele
|
|
|
10594
10715
|
});
|
|
10595
10716
|
|
|
10596
10717
|
// src/commands/schedule/enable.ts
|
|
10597
|
-
import { Command as
|
|
10598
|
-
import
|
|
10599
|
-
var enableCommand = new
|
|
10718
|
+
import { Command as Command44 } from "commander";
|
|
10719
|
+
import chalk45 from "chalk";
|
|
10720
|
+
var enableCommand = new Command44().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10600
10721
|
try {
|
|
10601
10722
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10602
10723
|
await enableSchedule({
|
|
@@ -10604,34 +10725,34 @@ var enableCommand = new Command43().name("enable").description("Enable a schedul
|
|
|
10604
10725
|
composeId: resolved.composeId
|
|
10605
10726
|
});
|
|
10606
10727
|
console.log(
|
|
10607
|
-
|
|
10728
|
+
chalk45.green(`\u2713 Enabled schedule for agent ${chalk45.cyan(agentName)}`)
|
|
10608
10729
|
);
|
|
10609
10730
|
} catch (error) {
|
|
10610
|
-
console.error(
|
|
10731
|
+
console.error(chalk45.red("\u2717 Failed to enable schedule"));
|
|
10611
10732
|
if (error instanceof ApiRequestError) {
|
|
10612
10733
|
if (error.code === "SCHEDULE_PAST") {
|
|
10613
|
-
console.error(
|
|
10614
|
-
console.error(
|
|
10734
|
+
console.error(chalk45.dim(" Scheduled time has already passed"));
|
|
10735
|
+
console.error(chalk45.dim(` Run: vm0 schedule setup ${agentName}`));
|
|
10615
10736
|
} else if (error.code === "NOT_FOUND") {
|
|
10616
10737
|
console.error(
|
|
10617
|
-
|
|
10738
|
+
chalk45.dim(` No schedule found for agent "${agentName}"`)
|
|
10618
10739
|
);
|
|
10619
|
-
console.error(
|
|
10740
|
+
console.error(chalk45.dim(" Run: vm0 schedule list"));
|
|
10620
10741
|
} else if (error.code === "UNAUTHORIZED") {
|
|
10621
|
-
console.error(
|
|
10742
|
+
console.error(chalk45.dim(" Run: vm0 auth login"));
|
|
10622
10743
|
} else {
|
|
10623
|
-
console.error(
|
|
10744
|
+
console.error(chalk45.dim(` ${error.message}`));
|
|
10624
10745
|
}
|
|
10625
10746
|
} else if (error instanceof Error) {
|
|
10626
10747
|
if (error.message.includes("Not authenticated")) {
|
|
10627
|
-
console.error(
|
|
10748
|
+
console.error(chalk45.dim(" Run: vm0 auth login"));
|
|
10628
10749
|
} else if (error.message.includes("No schedule found")) {
|
|
10629
10750
|
console.error(
|
|
10630
|
-
|
|
10751
|
+
chalk45.dim(` No schedule found for agent "${agentName}"`)
|
|
10631
10752
|
);
|
|
10632
|
-
console.error(
|
|
10753
|
+
console.error(chalk45.dim(" Run: vm0 schedule list"));
|
|
10633
10754
|
} else {
|
|
10634
|
-
console.error(
|
|
10755
|
+
console.error(chalk45.dim(` ${error.message}`));
|
|
10635
10756
|
}
|
|
10636
10757
|
}
|
|
10637
10758
|
process.exit(1);
|
|
@@ -10639,9 +10760,9 @@ var enableCommand = new Command43().name("enable").description("Enable a schedul
|
|
|
10639
10760
|
});
|
|
10640
10761
|
|
|
10641
10762
|
// src/commands/schedule/disable.ts
|
|
10642
|
-
import { Command as
|
|
10643
|
-
import
|
|
10644
|
-
var disableCommand = new
|
|
10763
|
+
import { Command as Command45 } from "commander";
|
|
10764
|
+
import chalk46 from "chalk";
|
|
10765
|
+
var disableCommand = new Command45().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
10645
10766
|
try {
|
|
10646
10767
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
10647
10768
|
await disableSchedule({
|
|
@@ -10649,20 +10770,20 @@ var disableCommand = new Command44().name("disable").description("Disable a sche
|
|
|
10649
10770
|
composeId: resolved.composeId
|
|
10650
10771
|
});
|
|
10651
10772
|
console.log(
|
|
10652
|
-
|
|
10773
|
+
chalk46.green(`\u2713 Disabled schedule for agent ${chalk46.cyan(agentName)}`)
|
|
10653
10774
|
);
|
|
10654
10775
|
} catch (error) {
|
|
10655
|
-
console.error(
|
|
10776
|
+
console.error(chalk46.red("\u2717 Failed to disable schedule"));
|
|
10656
10777
|
if (error instanceof Error) {
|
|
10657
10778
|
if (error.message.includes("Not authenticated")) {
|
|
10658
|
-
console.error(
|
|
10779
|
+
console.error(chalk46.dim(" Run: vm0 auth login"));
|
|
10659
10780
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
10660
10781
|
console.error(
|
|
10661
|
-
|
|
10782
|
+
chalk46.dim(` No schedule found for agent "${agentName}"`)
|
|
10662
10783
|
);
|
|
10663
|
-
console.error(
|
|
10784
|
+
console.error(chalk46.dim(" Run: vm0 schedule list"));
|
|
10664
10785
|
} else {
|
|
10665
|
-
console.error(
|
|
10786
|
+
console.error(chalk46.dim(` ${error.message}`));
|
|
10666
10787
|
}
|
|
10667
10788
|
}
|
|
10668
10789
|
process.exit(1);
|
|
@@ -10670,11 +10791,11 @@ var disableCommand = new Command44().name("disable").description("Disable a sche
|
|
|
10670
10791
|
});
|
|
10671
10792
|
|
|
10672
10793
|
// src/commands/schedule/index.ts
|
|
10673
|
-
var scheduleCommand = new
|
|
10794
|
+
var scheduleCommand = new Command46().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand5).addCommand(statusCommand6).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
|
|
10674
10795
|
|
|
10675
10796
|
// src/commands/usage/index.ts
|
|
10676
|
-
import { Command as
|
|
10677
|
-
import
|
|
10797
|
+
import { Command as Command47 } from "commander";
|
|
10798
|
+
import chalk47 from "chalk";
|
|
10678
10799
|
|
|
10679
10800
|
// src/lib/utils/duration-formatter.ts
|
|
10680
10801
|
function formatDuration(ms) {
|
|
@@ -10747,7 +10868,7 @@ function fillMissingDates(daily, startDate, endDate) {
|
|
|
10747
10868
|
result.sort((a, b) => b.date.localeCompare(a.date));
|
|
10748
10869
|
return result;
|
|
10749
10870
|
}
|
|
10750
|
-
var usageCommand = new
|
|
10871
|
+
var usageCommand = new Command47().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
|
|
10751
10872
|
"--until <date>",
|
|
10752
10873
|
"End date (ISO format or relative, defaults to now)"
|
|
10753
10874
|
).action(async (options) => {
|
|
@@ -10761,7 +10882,7 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10761
10882
|
endDate = new Date(untilMs);
|
|
10762
10883
|
} catch {
|
|
10763
10884
|
console.error(
|
|
10764
|
-
|
|
10885
|
+
chalk47.red(
|
|
10765
10886
|
"\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10766
10887
|
)
|
|
10767
10888
|
);
|
|
@@ -10776,7 +10897,7 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10776
10897
|
startDate = new Date(sinceMs);
|
|
10777
10898
|
} catch {
|
|
10778
10899
|
console.error(
|
|
10779
|
-
|
|
10900
|
+
chalk47.red(
|
|
10780
10901
|
"\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
10781
10902
|
)
|
|
10782
10903
|
);
|
|
@@ -10786,13 +10907,13 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10786
10907
|
startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
|
|
10787
10908
|
}
|
|
10788
10909
|
if (startDate >= endDate) {
|
|
10789
|
-
console.error(
|
|
10910
|
+
console.error(chalk47.red("\u2717 --since must be before --until"));
|
|
10790
10911
|
process.exit(1);
|
|
10791
10912
|
}
|
|
10792
10913
|
const rangeMs = endDate.getTime() - startDate.getTime();
|
|
10793
10914
|
if (rangeMs > MAX_RANGE_MS) {
|
|
10794
10915
|
console.error(
|
|
10795
|
-
|
|
10916
|
+
chalk47.red(
|
|
10796
10917
|
"\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
|
|
10797
10918
|
)
|
|
10798
10919
|
);
|
|
@@ -10809,19 +10930,19 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10809
10930
|
);
|
|
10810
10931
|
console.log();
|
|
10811
10932
|
console.log(
|
|
10812
|
-
|
|
10933
|
+
chalk47.bold(
|
|
10813
10934
|
`Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
|
|
10814
10935
|
)
|
|
10815
10936
|
);
|
|
10816
10937
|
console.log();
|
|
10817
|
-
console.log(
|
|
10938
|
+
console.log(chalk47.dim("DATE RUNS RUN TIME"));
|
|
10818
10939
|
for (const day of filledDaily) {
|
|
10819
10940
|
const dateDisplay = formatDateDisplay(day.date).padEnd(10);
|
|
10820
10941
|
const runsDisplay = String(day.run_count).padStart(6);
|
|
10821
10942
|
const timeDisplay = formatDuration(day.run_time_ms);
|
|
10822
10943
|
console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
|
|
10823
10944
|
}
|
|
10824
|
-
console.log(
|
|
10945
|
+
console.log(chalk47.dim("\u2500".repeat(29)));
|
|
10825
10946
|
const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
|
|
10826
10947
|
const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
|
|
10827
10948
|
console.log(
|
|
@@ -10831,68 +10952,68 @@ var usageCommand = new Command46().name("usage").description("View usage statist
|
|
|
10831
10952
|
} catch (error) {
|
|
10832
10953
|
if (error instanceof Error) {
|
|
10833
10954
|
if (error.message.includes("Not authenticated")) {
|
|
10834
|
-
console.error(
|
|
10835
|
-
console.error(
|
|
10955
|
+
console.error(chalk47.red("\u2717 Not authenticated"));
|
|
10956
|
+
console.error(chalk47.dim(" Run: vm0 auth login"));
|
|
10836
10957
|
} else {
|
|
10837
|
-
console.error(
|
|
10958
|
+
console.error(chalk47.red(`\u2717 ${error.message}`));
|
|
10838
10959
|
}
|
|
10839
10960
|
} else {
|
|
10840
|
-
console.error(
|
|
10961
|
+
console.error(chalk47.red("\u2717 An unexpected error occurred"));
|
|
10841
10962
|
}
|
|
10842
10963
|
process.exit(1);
|
|
10843
10964
|
}
|
|
10844
10965
|
});
|
|
10845
10966
|
|
|
10846
10967
|
// src/commands/credential/index.ts
|
|
10847
|
-
import { Command as
|
|
10968
|
+
import { Command as Command51 } from "commander";
|
|
10848
10969
|
|
|
10849
10970
|
// src/commands/credential/list.ts
|
|
10850
|
-
import { Command as
|
|
10851
|
-
import
|
|
10852
|
-
var listCommand6 = new
|
|
10971
|
+
import { Command as Command48 } from "commander";
|
|
10972
|
+
import chalk48 from "chalk";
|
|
10973
|
+
var listCommand6 = new Command48().name("list").alias("ls").description("List all credentials").action(async () => {
|
|
10853
10974
|
try {
|
|
10854
10975
|
const result = await listCredentials();
|
|
10855
10976
|
if (result.credentials.length === 0) {
|
|
10856
|
-
console.log(
|
|
10977
|
+
console.log(chalk48.dim("No credentials found"));
|
|
10857
10978
|
console.log();
|
|
10858
10979
|
console.log("To add a credential:");
|
|
10859
|
-
console.log(
|
|
10980
|
+
console.log(chalk48.cyan(" vm0 credential set MY_API_KEY <value>"));
|
|
10860
10981
|
return;
|
|
10861
10982
|
}
|
|
10862
|
-
console.log(
|
|
10983
|
+
console.log(chalk48.bold("Credentials:"));
|
|
10863
10984
|
console.log();
|
|
10864
10985
|
for (const credential of result.credentials) {
|
|
10865
|
-
const typeIndicator = credential.type === "model-provider" ?
|
|
10866
|
-
console.log(` ${
|
|
10986
|
+
const typeIndicator = credential.type === "model-provider" ? chalk48.dim(" [model-provider]") : "";
|
|
10987
|
+
console.log(` ${chalk48.cyan(credential.name)}${typeIndicator}`);
|
|
10867
10988
|
if (credential.description) {
|
|
10868
|
-
console.log(` ${
|
|
10989
|
+
console.log(` ${chalk48.dim(credential.description)}`);
|
|
10869
10990
|
}
|
|
10870
10991
|
console.log(
|
|
10871
|
-
` ${
|
|
10992
|
+
` ${chalk48.dim(`Updated: ${new Date(credential.updatedAt).toLocaleString()}`)}`
|
|
10872
10993
|
);
|
|
10873
10994
|
console.log();
|
|
10874
10995
|
}
|
|
10875
10996
|
console.log(
|
|
10876
|
-
|
|
10997
|
+
chalk48.dim(`Total: ${result.credentials.length} credential(s)`)
|
|
10877
10998
|
);
|
|
10878
10999
|
} catch (error) {
|
|
10879
11000
|
if (error instanceof Error) {
|
|
10880
11001
|
if (error.message.includes("Not authenticated")) {
|
|
10881
|
-
console.error(
|
|
11002
|
+
console.error(chalk48.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10882
11003
|
} else {
|
|
10883
|
-
console.error(
|
|
11004
|
+
console.error(chalk48.red(`\u2717 ${error.message}`));
|
|
10884
11005
|
}
|
|
10885
11006
|
} else {
|
|
10886
|
-
console.error(
|
|
11007
|
+
console.error(chalk48.red("\u2717 An unexpected error occurred"));
|
|
10887
11008
|
}
|
|
10888
11009
|
process.exit(1);
|
|
10889
11010
|
}
|
|
10890
11011
|
});
|
|
10891
11012
|
|
|
10892
11013
|
// src/commands/credential/set.ts
|
|
10893
|
-
import { Command as
|
|
10894
|
-
import
|
|
10895
|
-
var setCommand2 = new
|
|
11014
|
+
import { Command as Command49 } from "commander";
|
|
11015
|
+
import chalk49 from "chalk";
|
|
11016
|
+
var setCommand2 = new Command49().name("set").description("Create or update a credential").argument("<name>", "Credential name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Credential value").option("-d, --description <description>", "Optional description").action(
|
|
10896
11017
|
async (name, value, options) => {
|
|
10897
11018
|
try {
|
|
10898
11019
|
const credential = await setCredential({
|
|
@@ -10900,29 +11021,29 @@ var setCommand2 = new Command48().name("set").description("Create or update a cr
|
|
|
10900
11021
|
value,
|
|
10901
11022
|
description: options.description
|
|
10902
11023
|
});
|
|
10903
|
-
console.log(
|
|
11024
|
+
console.log(chalk49.green(`\u2713 Credential "${credential.name}" saved`));
|
|
10904
11025
|
console.log();
|
|
10905
11026
|
console.log("Use in vm0.yaml:");
|
|
10906
|
-
console.log(
|
|
10907
|
-
console.log(
|
|
11027
|
+
console.log(chalk49.cyan(` environment:`));
|
|
11028
|
+
console.log(chalk49.cyan(` ${name}: \${{ credentials.${name} }}`));
|
|
10908
11029
|
} catch (error) {
|
|
10909
11030
|
if (error instanceof Error) {
|
|
10910
11031
|
if (error.message.includes("Not authenticated")) {
|
|
10911
11032
|
console.error(
|
|
10912
|
-
|
|
11033
|
+
chalk49.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
10913
11034
|
);
|
|
10914
11035
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
10915
|
-
console.error(
|
|
11036
|
+
console.error(chalk49.red(`\u2717 ${error.message}`));
|
|
10916
11037
|
console.log();
|
|
10917
11038
|
console.log("Examples of valid credential names:");
|
|
10918
|
-
console.log(
|
|
10919
|
-
console.log(
|
|
10920
|
-
console.log(
|
|
11039
|
+
console.log(chalk49.dim(" MY_API_KEY"));
|
|
11040
|
+
console.log(chalk49.dim(" GITHUB_TOKEN"));
|
|
11041
|
+
console.log(chalk49.dim(" AWS_ACCESS_KEY_ID"));
|
|
10921
11042
|
} else {
|
|
10922
|
-
console.error(
|
|
11043
|
+
console.error(chalk49.red(`\u2717 ${error.message}`));
|
|
10923
11044
|
}
|
|
10924
11045
|
} else {
|
|
10925
|
-
console.error(
|
|
11046
|
+
console.error(chalk49.red("\u2717 An unexpected error occurred"));
|
|
10926
11047
|
}
|
|
10927
11048
|
process.exit(1);
|
|
10928
11049
|
}
|
|
@@ -10930,20 +11051,20 @@ var setCommand2 = new Command48().name("set").description("Create or update a cr
|
|
|
10930
11051
|
);
|
|
10931
11052
|
|
|
10932
11053
|
// src/commands/credential/delete.ts
|
|
10933
|
-
import { Command as
|
|
10934
|
-
import
|
|
10935
|
-
var deleteCommand2 = new
|
|
11054
|
+
import { Command as Command50 } from "commander";
|
|
11055
|
+
import chalk50 from "chalk";
|
|
11056
|
+
var deleteCommand2 = new Command50().name("delete").description("Delete a credential").argument("<name>", "Credential name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
10936
11057
|
try {
|
|
10937
11058
|
try {
|
|
10938
11059
|
await getCredential(name);
|
|
10939
11060
|
} catch {
|
|
10940
|
-
console.error(
|
|
11061
|
+
console.error(chalk50.red(`\u2717 Credential "${name}" not found`));
|
|
10941
11062
|
process.exit(1);
|
|
10942
11063
|
}
|
|
10943
11064
|
if (!options.yes) {
|
|
10944
11065
|
if (!isInteractive()) {
|
|
10945
11066
|
console.error(
|
|
10946
|
-
|
|
11067
|
+
chalk50.red("\u2717 --yes flag is required in non-interactive mode")
|
|
10947
11068
|
);
|
|
10948
11069
|
process.exit(1);
|
|
10949
11070
|
}
|
|
@@ -10952,43 +11073,43 @@ var deleteCommand2 = new Command49().name("delete").description("Delete a creden
|
|
|
10952
11073
|
false
|
|
10953
11074
|
);
|
|
10954
11075
|
if (!confirmed) {
|
|
10955
|
-
console.log(
|
|
11076
|
+
console.log(chalk50.dim("Cancelled"));
|
|
10956
11077
|
return;
|
|
10957
11078
|
}
|
|
10958
11079
|
}
|
|
10959
11080
|
await deleteCredential(name);
|
|
10960
|
-
console.log(
|
|
11081
|
+
console.log(chalk50.green(`\u2713 Credential "${name}" deleted`));
|
|
10961
11082
|
} catch (error) {
|
|
10962
11083
|
if (error instanceof Error) {
|
|
10963
11084
|
if (error.message.includes("Not authenticated")) {
|
|
10964
|
-
console.error(
|
|
11085
|
+
console.error(chalk50.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
10965
11086
|
} else {
|
|
10966
|
-
console.error(
|
|
11087
|
+
console.error(chalk50.red(`\u2717 ${error.message}`));
|
|
10967
11088
|
}
|
|
10968
11089
|
} else {
|
|
10969
|
-
console.error(
|
|
11090
|
+
console.error(chalk50.red("\u2717 An unexpected error occurred"));
|
|
10970
11091
|
}
|
|
10971
11092
|
process.exit(1);
|
|
10972
11093
|
}
|
|
10973
11094
|
});
|
|
10974
11095
|
|
|
10975
11096
|
// src/commands/credential/index.ts
|
|
10976
|
-
var credentialCommand = new
|
|
11097
|
+
var credentialCommand = new Command51().name("credential").description("Manage stored credentials for agent runs").addCommand(listCommand6).addCommand(setCommand2).addCommand(deleteCommand2);
|
|
10977
11098
|
|
|
10978
11099
|
// src/commands/model-provider/index.ts
|
|
10979
|
-
import { Command as
|
|
11100
|
+
import { Command as Command56 } from "commander";
|
|
10980
11101
|
|
|
10981
11102
|
// src/commands/model-provider/list.ts
|
|
10982
|
-
import { Command as
|
|
10983
|
-
import
|
|
10984
|
-
var listCommand7 = new
|
|
11103
|
+
import { Command as Command52 } from "commander";
|
|
11104
|
+
import chalk51 from "chalk";
|
|
11105
|
+
var listCommand7 = new Command52().name("list").alias("ls").description("List all model providers").action(async () => {
|
|
10985
11106
|
try {
|
|
10986
11107
|
const result = await listModelProviders();
|
|
10987
11108
|
if (result.modelProviders.length === 0) {
|
|
10988
|
-
console.log(
|
|
11109
|
+
console.log(chalk51.dim("No model providers configured"));
|
|
10989
11110
|
console.log();
|
|
10990
11111
|
console.log("To add a model provider:");
|
|
10991
|
-
console.log(
|
|
11112
|
+
console.log(chalk51.cyan(" vm0 model-provider setup"));
|
|
10992
11113
|
return;
|
|
10993
11114
|
}
|
|
10994
11115
|
const byFramework = result.modelProviders.reduce(
|
|
@@ -11002,16 +11123,16 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
11002
11123
|
},
|
|
11003
11124
|
{}
|
|
11004
11125
|
);
|
|
11005
|
-
console.log(
|
|
11126
|
+
console.log(chalk51.bold("Model Providers:"));
|
|
11006
11127
|
console.log();
|
|
11007
11128
|
for (const [framework, providers] of Object.entries(byFramework)) {
|
|
11008
|
-
console.log(` ${
|
|
11129
|
+
console.log(` ${chalk51.cyan(framework)}:`);
|
|
11009
11130
|
for (const provider of providers) {
|
|
11010
|
-
const defaultTag = provider.isDefault ?
|
|
11011
|
-
const modelTag = provider.selectedModel ?
|
|
11131
|
+
const defaultTag = provider.isDefault ? chalk51.green(" (default)") : "";
|
|
11132
|
+
const modelTag = provider.selectedModel ? chalk51.dim(` [${provider.selectedModel}]`) : "";
|
|
11012
11133
|
console.log(` ${provider.type}${defaultTag}${modelTag}`);
|
|
11013
11134
|
console.log(
|
|
11014
|
-
|
|
11135
|
+
chalk51.dim(
|
|
11015
11136
|
` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
|
|
11016
11137
|
)
|
|
11017
11138
|
);
|
|
@@ -11019,33 +11140,33 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
11019
11140
|
console.log();
|
|
11020
11141
|
}
|
|
11021
11142
|
console.log(
|
|
11022
|
-
|
|
11143
|
+
chalk51.dim(`Total: ${result.modelProviders.length} provider(s)`)
|
|
11023
11144
|
);
|
|
11024
11145
|
} catch (error) {
|
|
11025
11146
|
if (error instanceof Error) {
|
|
11026
11147
|
if (error.message.includes("Not authenticated")) {
|
|
11027
|
-
console.error(
|
|
11148
|
+
console.error(chalk51.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11028
11149
|
} else {
|
|
11029
|
-
console.error(
|
|
11150
|
+
console.error(chalk51.red(`\u2717 ${error.message}`));
|
|
11030
11151
|
}
|
|
11031
11152
|
} else {
|
|
11032
|
-
console.error(
|
|
11153
|
+
console.error(chalk51.red("\u2717 An unexpected error occurred"));
|
|
11033
11154
|
}
|
|
11034
11155
|
process.exit(1);
|
|
11035
11156
|
}
|
|
11036
11157
|
});
|
|
11037
11158
|
|
|
11038
11159
|
// src/commands/model-provider/setup.ts
|
|
11039
|
-
import { Command as
|
|
11040
|
-
import
|
|
11160
|
+
import { Command as Command53 } from "commander";
|
|
11161
|
+
import chalk52 from "chalk";
|
|
11041
11162
|
import prompts2 from "prompts";
|
|
11042
11163
|
function validateProviderType(typeStr) {
|
|
11043
11164
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(typeStr)) {
|
|
11044
|
-
console.error(
|
|
11165
|
+
console.error(chalk52.red(`\u2717 Invalid type "${typeStr}"`));
|
|
11045
11166
|
console.log();
|
|
11046
11167
|
console.log("Valid types:");
|
|
11047
11168
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
11048
|
-
console.log(` ${
|
|
11169
|
+
console.log(` ${chalk52.cyan(t)} - ${config.label}`);
|
|
11049
11170
|
}
|
|
11050
11171
|
process.exit(1);
|
|
11051
11172
|
}
|
|
@@ -11054,11 +11175,11 @@ function validateProviderType(typeStr) {
|
|
|
11054
11175
|
function validateModel(type, modelStr) {
|
|
11055
11176
|
const models = getModels(type);
|
|
11056
11177
|
if (models && !models.includes(modelStr)) {
|
|
11057
|
-
console.error(
|
|
11178
|
+
console.error(chalk52.red(`\u2717 Invalid model "${modelStr}"`));
|
|
11058
11179
|
console.log();
|
|
11059
11180
|
console.log("Valid models:");
|
|
11060
11181
|
for (const m of models) {
|
|
11061
|
-
console.log(` ${
|
|
11182
|
+
console.log(` ${chalk52.cyan(m)}`);
|
|
11062
11183
|
}
|
|
11063
11184
|
process.exit(1);
|
|
11064
11185
|
}
|
|
@@ -11073,7 +11194,12 @@ function handleNonInteractiveMode(options) {
|
|
|
11073
11194
|
const defaultModel = getDefaultModel(type);
|
|
11074
11195
|
selectedModel = defaultModel || void 0;
|
|
11075
11196
|
}
|
|
11076
|
-
return {
|
|
11197
|
+
return {
|
|
11198
|
+
type,
|
|
11199
|
+
credential: options.credential,
|
|
11200
|
+
selectedModel,
|
|
11201
|
+
isInteractiveMode: false
|
|
11202
|
+
};
|
|
11077
11203
|
}
|
|
11078
11204
|
async function promptForModelSelection(type) {
|
|
11079
11205
|
if (!hasModelSelection(type)) {
|
|
@@ -11102,11 +11228,11 @@ async function promptForModelSelection(type) {
|
|
|
11102
11228
|
}
|
|
11103
11229
|
async function handleInteractiveMode() {
|
|
11104
11230
|
if (!isInteractive()) {
|
|
11105
|
-
console.error(
|
|
11231
|
+
console.error(chalk52.red("\u2717 Interactive mode requires a TTY"));
|
|
11106
11232
|
console.log();
|
|
11107
11233
|
console.log("Use non-interactive mode:");
|
|
11108
11234
|
console.log(
|
|
11109
|
-
|
|
11235
|
+
chalk52.cyan(
|
|
11110
11236
|
' vm0 model-provider setup --type <type> --credential "<value>"'
|
|
11111
11237
|
)
|
|
11112
11238
|
);
|
|
@@ -11145,13 +11271,14 @@ async function handleInteractiveMode() {
|
|
|
11145
11271
|
const provider = await convertModelProviderCredential(type);
|
|
11146
11272
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
11147
11273
|
console.log(
|
|
11148
|
-
|
|
11274
|
+
chalk52.green(
|
|
11149
11275
|
`\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote}`
|
|
11150
11276
|
)
|
|
11151
11277
|
);
|
|
11278
|
+
await promptSetAsDefault(type, provider.framework, provider.isDefault);
|
|
11152
11279
|
return null;
|
|
11153
11280
|
}
|
|
11154
|
-
console.log(
|
|
11281
|
+
console.log(chalk52.dim("Aborted"));
|
|
11155
11282
|
process.exit(0);
|
|
11156
11283
|
}
|
|
11157
11284
|
if (checkResult.exists && checkResult.currentType === "model-provider") {
|
|
@@ -11172,12 +11299,17 @@ async function handleInteractiveMode() {
|
|
|
11172
11299
|
);
|
|
11173
11300
|
if (actionResponse.action === "keep") {
|
|
11174
11301
|
const selectedModel2 = await promptForModelSelection(type);
|
|
11175
|
-
return {
|
|
11302
|
+
return {
|
|
11303
|
+
type,
|
|
11304
|
+
keepExistingCredential: true,
|
|
11305
|
+
selectedModel: selectedModel2,
|
|
11306
|
+
isInteractiveMode: true
|
|
11307
|
+
};
|
|
11176
11308
|
}
|
|
11177
11309
|
}
|
|
11178
11310
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
11179
11311
|
console.log();
|
|
11180
|
-
console.log(
|
|
11312
|
+
console.log(chalk52.dim(config.helpText));
|
|
11181
11313
|
console.log();
|
|
11182
11314
|
const credentialResponse = await prompts2(
|
|
11183
11315
|
{
|
|
@@ -11190,26 +11322,42 @@ async function handleInteractiveMode() {
|
|
|
11190
11322
|
);
|
|
11191
11323
|
const credential = credentialResponse.credential;
|
|
11192
11324
|
const selectedModel = await promptForModelSelection(type);
|
|
11193
|
-
return { type, credential, selectedModel };
|
|
11325
|
+
return { type, credential, selectedModel, isInteractiveMode: true };
|
|
11194
11326
|
}
|
|
11195
11327
|
function handleSetupError2(error) {
|
|
11196
11328
|
if (error instanceof Error) {
|
|
11197
11329
|
if (error.message.includes("already exists")) {
|
|
11198
|
-
console.error(
|
|
11330
|
+
console.error(chalk52.red(`\u2717 ${error.message}`));
|
|
11199
11331
|
console.log();
|
|
11200
11332
|
console.log("To convert the existing credential, run:");
|
|
11201
|
-
console.log(
|
|
11333
|
+
console.log(chalk52.cyan(" vm0 model-provider setup --convert"));
|
|
11202
11334
|
} else if (error.message.includes("Not authenticated")) {
|
|
11203
|
-
console.error(
|
|
11335
|
+
console.error(chalk52.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11204
11336
|
} else {
|
|
11205
|
-
console.error(
|
|
11337
|
+
console.error(chalk52.red(`\u2717 ${error.message}`));
|
|
11206
11338
|
}
|
|
11207
11339
|
} else {
|
|
11208
|
-
console.error(
|
|
11340
|
+
console.error(chalk52.red("\u2717 An unexpected error occurred"));
|
|
11209
11341
|
}
|
|
11210
11342
|
process.exit(1);
|
|
11211
11343
|
}
|
|
11212
|
-
|
|
11344
|
+
async function promptSetAsDefault(type, framework, isDefault) {
|
|
11345
|
+
if (isDefault) return;
|
|
11346
|
+
const response = await prompts2(
|
|
11347
|
+
{
|
|
11348
|
+
type: "confirm",
|
|
11349
|
+
name: "setDefault",
|
|
11350
|
+
message: "Set this provider as default?",
|
|
11351
|
+
initial: false
|
|
11352
|
+
},
|
|
11353
|
+
{ onCancel: () => process.exit(0) }
|
|
11354
|
+
);
|
|
11355
|
+
if (response.setDefault) {
|
|
11356
|
+
await setModelProviderDefault(type);
|
|
11357
|
+
console.log(chalk52.green(`\u2713 Default for ${framework} set to "${type}"`));
|
|
11358
|
+
}
|
|
11359
|
+
}
|
|
11360
|
+
var setupCommand2 = new Command53().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
|
|
11213
11361
|
"-c, --credential <credential>",
|
|
11214
11362
|
"Credential value (for non-interactive mode)"
|
|
11215
11363
|
).option("-m, --model <model>", "Model selection (for non-interactive mode)").option("--convert", "Convert existing user credential to model provider").action(
|
|
@@ -11225,7 +11373,7 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
11225
11373
|
});
|
|
11226
11374
|
} else if (options.type || options.credential) {
|
|
11227
11375
|
console.error(
|
|
11228
|
-
|
|
11376
|
+
chalk52.red("\u2717 Both --type and --credential are required")
|
|
11229
11377
|
);
|
|
11230
11378
|
process.exit(1);
|
|
11231
11379
|
} else {
|
|
@@ -11244,15 +11392,22 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
11244
11392
|
const modelNote2 = provider2.selectedModel ? ` with model: ${provider2.selectedModel}` : "";
|
|
11245
11393
|
if (!hasModelSelection(input.type)) {
|
|
11246
11394
|
console.log(
|
|
11247
|
-
|
|
11395
|
+
chalk52.green(`\u2713 Model provider "${input.type}" unchanged`)
|
|
11248
11396
|
);
|
|
11249
11397
|
} else {
|
|
11250
11398
|
console.log(
|
|
11251
|
-
|
|
11399
|
+
chalk52.green(
|
|
11252
11400
|
`\u2713 Model provider "${input.type}" updated${defaultNote2}${modelNote2}`
|
|
11253
11401
|
)
|
|
11254
11402
|
);
|
|
11255
11403
|
}
|
|
11404
|
+
if (input.isInteractiveMode) {
|
|
11405
|
+
await promptSetAsDefault(
|
|
11406
|
+
input.type,
|
|
11407
|
+
provider2.framework,
|
|
11408
|
+
provider2.isDefault
|
|
11409
|
+
);
|
|
11410
|
+
}
|
|
11256
11411
|
return;
|
|
11257
11412
|
}
|
|
11258
11413
|
const { provider, created } = await upsertModelProvider({
|
|
@@ -11265,10 +11420,17 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
11265
11420
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
11266
11421
|
const modelNote = provider.selectedModel ? ` with model: ${provider.selectedModel}` : "";
|
|
11267
11422
|
console.log(
|
|
11268
|
-
|
|
11423
|
+
chalk52.green(
|
|
11269
11424
|
`\u2713 Model provider "${input.type}" ${action}${defaultNote}${modelNote}`
|
|
11270
11425
|
)
|
|
11271
11426
|
);
|
|
11427
|
+
if (input.isInteractiveMode) {
|
|
11428
|
+
await promptSetAsDefault(
|
|
11429
|
+
input.type,
|
|
11430
|
+
provider.framework,
|
|
11431
|
+
provider.isDefault
|
|
11432
|
+
);
|
|
11433
|
+
}
|
|
11272
11434
|
} catch (error) {
|
|
11273
11435
|
handleSetupError2(error);
|
|
11274
11436
|
}
|
|
@@ -11276,96 +11438,96 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
11276
11438
|
);
|
|
11277
11439
|
|
|
11278
11440
|
// src/commands/model-provider/delete.ts
|
|
11279
|
-
import { Command as
|
|
11280
|
-
import
|
|
11281
|
-
var deleteCommand3 = new
|
|
11441
|
+
import { Command as Command54 } from "commander";
|
|
11442
|
+
import chalk53 from "chalk";
|
|
11443
|
+
var deleteCommand3 = new Command54().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
|
|
11282
11444
|
try {
|
|
11283
11445
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
11284
|
-
console.error(
|
|
11446
|
+
console.error(chalk53.red(`\u2717 Invalid type "${type}"`));
|
|
11285
11447
|
console.log();
|
|
11286
11448
|
console.log("Valid types:");
|
|
11287
11449
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
11288
|
-
console.log(` ${
|
|
11450
|
+
console.log(` ${chalk53.cyan(t)} - ${config.label}`);
|
|
11289
11451
|
}
|
|
11290
11452
|
process.exit(1);
|
|
11291
11453
|
}
|
|
11292
11454
|
await deleteModelProvider(type);
|
|
11293
|
-
console.log(
|
|
11455
|
+
console.log(chalk53.green(`\u2713 Model provider "${type}" deleted`));
|
|
11294
11456
|
} catch (error) {
|
|
11295
11457
|
if (error instanceof Error) {
|
|
11296
11458
|
if (error.message.includes("not found")) {
|
|
11297
|
-
console.error(
|
|
11459
|
+
console.error(chalk53.red(`\u2717 Model provider "${type}" not found`));
|
|
11298
11460
|
} else if (error.message.includes("Not authenticated")) {
|
|
11299
|
-
console.error(
|
|
11461
|
+
console.error(chalk53.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11300
11462
|
} else {
|
|
11301
|
-
console.error(
|
|
11463
|
+
console.error(chalk53.red(`\u2717 ${error.message}`));
|
|
11302
11464
|
}
|
|
11303
11465
|
} else {
|
|
11304
|
-
console.error(
|
|
11466
|
+
console.error(chalk53.red("\u2717 An unexpected error occurred"));
|
|
11305
11467
|
}
|
|
11306
11468
|
process.exit(1);
|
|
11307
11469
|
}
|
|
11308
11470
|
});
|
|
11309
11471
|
|
|
11310
11472
|
// src/commands/model-provider/set-default.ts
|
|
11311
|
-
import { Command as
|
|
11312
|
-
import
|
|
11313
|
-
var setDefaultCommand = new
|
|
11473
|
+
import { Command as Command55 } from "commander";
|
|
11474
|
+
import chalk54 from "chalk";
|
|
11475
|
+
var setDefaultCommand = new Command55().name("set-default").description("Set a model provider as default for its framework").argument("<type>", "Model provider type to set as default").action(async (type) => {
|
|
11314
11476
|
try {
|
|
11315
11477
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
11316
|
-
console.error(
|
|
11478
|
+
console.error(chalk54.red(`\u2717 Invalid type "${type}"`));
|
|
11317
11479
|
console.log();
|
|
11318
11480
|
console.log("Valid types:");
|
|
11319
11481
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
11320
|
-
console.log(` ${
|
|
11482
|
+
console.log(` ${chalk54.cyan(t)} - ${config.label}`);
|
|
11321
11483
|
}
|
|
11322
11484
|
process.exit(1);
|
|
11323
11485
|
}
|
|
11324
11486
|
const provider = await setModelProviderDefault(type);
|
|
11325
11487
|
console.log(
|
|
11326
|
-
|
|
11488
|
+
chalk54.green(
|
|
11327
11489
|
`\u2713 Default for ${provider.framework} set to "${provider.type}"`
|
|
11328
11490
|
)
|
|
11329
11491
|
);
|
|
11330
11492
|
} catch (error) {
|
|
11331
11493
|
if (error instanceof Error) {
|
|
11332
11494
|
if (error.message.includes("not found")) {
|
|
11333
|
-
console.error(
|
|
11495
|
+
console.error(chalk54.red(`\u2717 Model provider "${type}" not found`));
|
|
11334
11496
|
} else if (error.message.includes("Not authenticated")) {
|
|
11335
|
-
console.error(
|
|
11497
|
+
console.error(chalk54.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11336
11498
|
} else {
|
|
11337
|
-
console.error(
|
|
11499
|
+
console.error(chalk54.red(`\u2717 ${error.message}`));
|
|
11338
11500
|
}
|
|
11339
11501
|
} else {
|
|
11340
|
-
console.error(
|
|
11502
|
+
console.error(chalk54.red("\u2717 An unexpected error occurred"));
|
|
11341
11503
|
}
|
|
11342
11504
|
process.exit(1);
|
|
11343
11505
|
}
|
|
11344
11506
|
});
|
|
11345
11507
|
|
|
11346
11508
|
// src/commands/model-provider/index.ts
|
|
11347
|
-
var modelProviderCommand = new
|
|
11509
|
+
var modelProviderCommand = new Command56().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand7).addCommand(setupCommand2).addCommand(deleteCommand3).addCommand(setDefaultCommand);
|
|
11348
11510
|
|
|
11349
11511
|
// src/commands/onboard/index.ts
|
|
11350
|
-
import { Command as
|
|
11351
|
-
import
|
|
11352
|
-
import { mkdir as
|
|
11353
|
-
import { existsSync as
|
|
11512
|
+
import { Command as Command57 } from "commander";
|
|
11513
|
+
import chalk58 from "chalk";
|
|
11514
|
+
import { mkdir as mkdir8 } from "fs/promises";
|
|
11515
|
+
import { existsSync as existsSync12 } from "fs";
|
|
11354
11516
|
|
|
11355
11517
|
// src/lib/ui/welcome-box.ts
|
|
11356
|
-
import
|
|
11518
|
+
import chalk55 from "chalk";
|
|
11357
11519
|
var gradientColors = [
|
|
11358
|
-
|
|
11520
|
+
chalk55.hex("#FFAB5E"),
|
|
11359
11521
|
// Line 1 - lightest
|
|
11360
|
-
|
|
11522
|
+
chalk55.hex("#FF9642"),
|
|
11361
11523
|
// Line 2
|
|
11362
|
-
|
|
11524
|
+
chalk55.hex("#FF8228"),
|
|
11363
11525
|
// Line 3
|
|
11364
|
-
|
|
11526
|
+
chalk55.hex("#FF6D0A"),
|
|
11365
11527
|
// Line 4
|
|
11366
|
-
|
|
11528
|
+
chalk55.hex("#E85D00"),
|
|
11367
11529
|
// Line 5
|
|
11368
|
-
|
|
11530
|
+
chalk55.hex("#CC4E00")
|
|
11369
11531
|
// Line 6 - darkest
|
|
11370
11532
|
];
|
|
11371
11533
|
var vm0LogoLines = [
|
|
@@ -11387,15 +11549,15 @@ function renderVm0Banner() {
|
|
|
11387
11549
|
function renderOnboardWelcome() {
|
|
11388
11550
|
renderVm0Banner();
|
|
11389
11551
|
console.log(` Build agentic workflows using natural language.`);
|
|
11390
|
-
console.log(` ${
|
|
11552
|
+
console.log(` ${chalk55.dim("Currently in beta, enjoy it free.")}`);
|
|
11391
11553
|
console.log(
|
|
11392
|
-
` ${
|
|
11554
|
+
` ${chalk55.dim("Star us on GitHub: https://github.com/vm0-ai/vm0")}`
|
|
11393
11555
|
);
|
|
11394
11556
|
console.log();
|
|
11395
11557
|
}
|
|
11396
11558
|
|
|
11397
11559
|
// src/lib/ui/step-runner.ts
|
|
11398
|
-
import
|
|
11560
|
+
import chalk56 from "chalk";
|
|
11399
11561
|
function createStepRunner(options = true) {
|
|
11400
11562
|
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
11401
11563
|
const interactive = opts.interactive ?? true;
|
|
@@ -11410,25 +11572,25 @@ function createStepRunner(options = true) {
|
|
|
11410
11572
|
}
|
|
11411
11573
|
for (const [i, step] of completedSteps.entries()) {
|
|
11412
11574
|
if (step.failed) {
|
|
11413
|
-
console.log(
|
|
11575
|
+
console.log(chalk56.red(`\u2717 ${step.label}`));
|
|
11414
11576
|
} else {
|
|
11415
|
-
console.log(
|
|
11577
|
+
console.log(chalk56.green(`\u25CF ${step.label}`));
|
|
11416
11578
|
}
|
|
11417
11579
|
const isLastStep = i === completedSteps.length - 1;
|
|
11418
11580
|
if (!isLastStep || !isFinal) {
|
|
11419
|
-
console.log(
|
|
11581
|
+
console.log(chalk56.dim("\u2502"));
|
|
11420
11582
|
}
|
|
11421
11583
|
}
|
|
11422
11584
|
}
|
|
11423
11585
|
async function executeStep(label, fn, isFinal) {
|
|
11424
11586
|
let stepFailed = false;
|
|
11425
|
-
console.log(
|
|
11587
|
+
console.log(chalk56.yellow(`\u25CB ${label}`));
|
|
11426
11588
|
const ctx = {
|
|
11427
11589
|
connector() {
|
|
11428
|
-
console.log(
|
|
11590
|
+
console.log(chalk56.dim("\u2502"));
|
|
11429
11591
|
},
|
|
11430
11592
|
detail(message) {
|
|
11431
|
-
console.log(`${
|
|
11593
|
+
console.log(`${chalk56.dim("\u2502")} ${message}`);
|
|
11432
11594
|
},
|
|
11433
11595
|
async prompt(promptFn) {
|
|
11434
11596
|
return await promptFn();
|
|
@@ -11445,12 +11607,12 @@ function createStepRunner(options = true) {
|
|
|
11445
11607
|
redrawCompletedSteps(isFinal);
|
|
11446
11608
|
} else {
|
|
11447
11609
|
if (stepFailed) {
|
|
11448
|
-
console.log(
|
|
11610
|
+
console.log(chalk56.red(`\u2717 ${label}`));
|
|
11449
11611
|
} else {
|
|
11450
|
-
console.log(
|
|
11612
|
+
console.log(chalk56.green(`\u25CF ${label}`));
|
|
11451
11613
|
}
|
|
11452
11614
|
if (!isFinal) {
|
|
11453
|
-
console.log(
|
|
11615
|
+
console.log(chalk56.dim("\u2502"));
|
|
11454
11616
|
}
|
|
11455
11617
|
}
|
|
11456
11618
|
}
|
|
@@ -11599,7 +11761,7 @@ async function setupModelProvider(type, credential, options) {
|
|
|
11599
11761
|
|
|
11600
11762
|
// src/lib/domain/onboard/claude-setup.ts
|
|
11601
11763
|
import { spawn as spawn3 } from "child_process";
|
|
11602
|
-
import
|
|
11764
|
+
import chalk57 from "chalk";
|
|
11603
11765
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
11604
11766
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
11605
11767
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
@@ -11637,12 +11799,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
11637
11799
|
}
|
|
11638
11800
|
function handlePluginError(error, context) {
|
|
11639
11801
|
const displayContext = context ?? "Claude plugin";
|
|
11640
|
-
console.error(
|
|
11802
|
+
console.error(chalk57.red(`Failed to install ${displayContext}`));
|
|
11641
11803
|
if (error instanceof Error) {
|
|
11642
|
-
console.error(
|
|
11804
|
+
console.error(chalk57.red(error.message));
|
|
11643
11805
|
}
|
|
11644
11806
|
console.error(
|
|
11645
|
-
|
|
11807
|
+
chalk57.dim("Please ensure Claude CLI is installed and accessible.")
|
|
11646
11808
|
);
|
|
11647
11809
|
process.exit(1);
|
|
11648
11810
|
}
|
|
@@ -11685,7 +11847,7 @@ async function updateMarketplace() {
|
|
|
11685
11847
|
]);
|
|
11686
11848
|
if (!result.success) {
|
|
11687
11849
|
console.warn(
|
|
11688
|
-
|
|
11850
|
+
chalk57.yellow(
|
|
11689
11851
|
`Warning: Could not update marketplace: ${result.error ?? "unknown error"}`
|
|
11690
11852
|
)
|
|
11691
11853
|
);
|
|
@@ -11723,7 +11885,7 @@ async function handleAuthentication(ctx) {
|
|
|
11723
11885
|
return;
|
|
11724
11886
|
}
|
|
11725
11887
|
if (!ctx.interactive) {
|
|
11726
|
-
console.error(
|
|
11888
|
+
console.error(chalk58.red("Error: Not authenticated"));
|
|
11727
11889
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
11728
11890
|
process.exit(1);
|
|
11729
11891
|
}
|
|
@@ -11731,16 +11893,16 @@ async function handleAuthentication(ctx) {
|
|
|
11731
11893
|
onInitiating: () => {
|
|
11732
11894
|
},
|
|
11733
11895
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
11734
|
-
step.detail(`Copy code: ${
|
|
11735
|
-
step.detail(`Open: ${
|
|
11736
|
-
step.detail(
|
|
11896
|
+
step.detail(`Copy code: ${chalk58.cyan.bold(code)}`);
|
|
11897
|
+
step.detail(`Open: ${chalk58.cyan(url)}`);
|
|
11898
|
+
step.detail(chalk58.dim(`Expires in ${expiresIn} minutes`));
|
|
11737
11899
|
},
|
|
11738
11900
|
onPolling: () => {
|
|
11739
11901
|
},
|
|
11740
11902
|
onSuccess: () => {
|
|
11741
11903
|
},
|
|
11742
11904
|
onError: (error) => {
|
|
11743
|
-
console.error(
|
|
11905
|
+
console.error(chalk58.red(`
|
|
11744
11906
|
${error.message}`));
|
|
11745
11907
|
process.exit(1);
|
|
11746
11908
|
}
|
|
@@ -11754,7 +11916,7 @@ async function handleModelProvider(ctx) {
|
|
|
11754
11916
|
return;
|
|
11755
11917
|
}
|
|
11756
11918
|
if (!ctx.interactive) {
|
|
11757
|
-
console.error(
|
|
11919
|
+
console.error(chalk58.red("Error: No model provider configured"));
|
|
11758
11920
|
console.error("Run 'vm0 model-provider setup' first");
|
|
11759
11921
|
process.exit(1);
|
|
11760
11922
|
}
|
|
@@ -11775,7 +11937,7 @@ async function handleModelProvider(ctx) {
|
|
|
11775
11937
|
const selectedChoice = choices.find((c20) => c20.type === providerType);
|
|
11776
11938
|
if (selectedChoice?.helpText) {
|
|
11777
11939
|
for (const line of selectedChoice.helpText.split("\n")) {
|
|
11778
|
-
step.detail(
|
|
11940
|
+
step.detail(chalk58.dim(line));
|
|
11779
11941
|
}
|
|
11780
11942
|
}
|
|
11781
11943
|
const credential = await step.prompt(
|
|
@@ -11784,7 +11946,7 @@ async function handleModelProvider(ctx) {
|
|
|
11784
11946
|
)
|
|
11785
11947
|
);
|
|
11786
11948
|
if (!credential) {
|
|
11787
|
-
console.log(
|
|
11949
|
+
console.log(chalk58.dim("Cancelled"));
|
|
11788
11950
|
process.exit(0);
|
|
11789
11951
|
}
|
|
11790
11952
|
let selectedModel;
|
|
@@ -11803,7 +11965,7 @@ async function handleModelProvider(ctx) {
|
|
|
11803
11965
|
() => promptSelect("Select model:", modelChoices)
|
|
11804
11966
|
);
|
|
11805
11967
|
if (modelSelection === void 0) {
|
|
11806
|
-
console.log(
|
|
11968
|
+
console.log(chalk58.dim("Cancelled"));
|
|
11807
11969
|
process.exit(0);
|
|
11808
11970
|
}
|
|
11809
11971
|
selectedModel = modelSelection === "" ? void 0 : modelSelection;
|
|
@@ -11813,7 +11975,7 @@ async function handleModelProvider(ctx) {
|
|
|
11813
11975
|
});
|
|
11814
11976
|
const modelNote = result.provider.selectedModel ? ` with model: ${result.provider.selectedModel}` : "";
|
|
11815
11977
|
step.detail(
|
|
11816
|
-
|
|
11978
|
+
chalk58.green(
|
|
11817
11979
|
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}${modelNote}`
|
|
11818
11980
|
)
|
|
11819
11981
|
);
|
|
@@ -11842,9 +12004,9 @@ async function handleAgentCreation(ctx) {
|
|
|
11842
12004
|
process.exit(0);
|
|
11843
12005
|
}
|
|
11844
12006
|
agentName = inputName;
|
|
11845
|
-
if (
|
|
12007
|
+
if (existsSync12(agentName)) {
|
|
11846
12008
|
step.detail(
|
|
11847
|
-
|
|
12009
|
+
chalk58.yellow(`${agentName}/ already exists, choose another name`)
|
|
11848
12010
|
);
|
|
11849
12011
|
} else {
|
|
11850
12012
|
folderExists = false;
|
|
@@ -11853,22 +12015,22 @@ async function handleAgentCreation(ctx) {
|
|
|
11853
12015
|
} else {
|
|
11854
12016
|
if (!validateAgentName(agentName)) {
|
|
11855
12017
|
console.error(
|
|
11856
|
-
|
|
12018
|
+
chalk58.red(
|
|
11857
12019
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
11858
12020
|
)
|
|
11859
12021
|
);
|
|
11860
12022
|
process.exit(1);
|
|
11861
12023
|
}
|
|
11862
|
-
if (
|
|
11863
|
-
console.error(
|
|
12024
|
+
if (existsSync12(agentName)) {
|
|
12025
|
+
console.error(chalk58.red(`${agentName}/ already exists`));
|
|
11864
12026
|
console.log();
|
|
11865
12027
|
console.log("Remove it first or choose a different name:");
|
|
11866
|
-
console.log(
|
|
12028
|
+
console.log(chalk58.cyan(` rm -rf ${agentName}`));
|
|
11867
12029
|
process.exit(1);
|
|
11868
12030
|
}
|
|
11869
12031
|
}
|
|
11870
|
-
await
|
|
11871
|
-
step.detail(
|
|
12032
|
+
await mkdir8(agentName, { recursive: true });
|
|
12033
|
+
step.detail(chalk58.green(`Created ${agentName}/`));
|
|
11872
12034
|
});
|
|
11873
12035
|
return agentName;
|
|
11874
12036
|
}
|
|
@@ -11884,7 +12046,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11884
12046
|
shouldInstall = confirmed ?? true;
|
|
11885
12047
|
}
|
|
11886
12048
|
if (!shouldInstall) {
|
|
11887
|
-
step.detail(
|
|
12049
|
+
step.detail(chalk58.dim("Skipped"));
|
|
11888
12050
|
return;
|
|
11889
12051
|
}
|
|
11890
12052
|
const scope = "project";
|
|
@@ -11892,7 +12054,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11892
12054
|
const agentDir = `${process.cwd()}/${agentName}`;
|
|
11893
12055
|
const result = await installVm0Plugin(scope, agentDir);
|
|
11894
12056
|
step.detail(
|
|
11895
|
-
|
|
12057
|
+
chalk58.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11896
12058
|
);
|
|
11897
12059
|
pluginInstalled = true;
|
|
11898
12060
|
} catch (error) {
|
|
@@ -11903,18 +12065,18 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
11903
12065
|
}
|
|
11904
12066
|
function printNextSteps(agentName, pluginInstalled) {
|
|
11905
12067
|
console.log();
|
|
11906
|
-
console.log(
|
|
12068
|
+
console.log(chalk58.bold("Next step:"));
|
|
11907
12069
|
console.log();
|
|
11908
12070
|
if (pluginInstalled) {
|
|
11909
12071
|
console.log(
|
|
11910
|
-
` ${
|
|
12072
|
+
` ${chalk58.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
11911
12073
|
);
|
|
11912
12074
|
} else {
|
|
11913
|
-
console.log(` ${
|
|
12075
|
+
console.log(` ${chalk58.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
11914
12076
|
}
|
|
11915
12077
|
console.log();
|
|
11916
12078
|
}
|
|
11917
|
-
var onboardCommand = new
|
|
12079
|
+
var onboardCommand = new Command57().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) => {
|
|
11918
12080
|
const interactive = isInteractive();
|
|
11919
12081
|
if (interactive) {
|
|
11920
12082
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
@@ -11937,15 +12099,15 @@ var onboardCommand = new Command56().name("onboard").description("Guided setup f
|
|
|
11937
12099
|
});
|
|
11938
12100
|
|
|
11939
12101
|
// src/commands/setup-claude/index.ts
|
|
11940
|
-
import { Command as
|
|
11941
|
-
import
|
|
11942
|
-
var setupClaudeCommand = new
|
|
11943
|
-
console.log(
|
|
12102
|
+
import { Command as Command58 } from "commander";
|
|
12103
|
+
import chalk59 from "chalk";
|
|
12104
|
+
var setupClaudeCommand = new Command58().name("setup-claude").description("Install VM0 Claude Plugin").option("--agent-dir <dir>", "Agent directory to run install in").option("--scope <scope>", "Installation scope (user or project)", "project").action(async (options) => {
|
|
12105
|
+
console.log(chalk59.dim("Installing VM0 Claude Plugin..."));
|
|
11944
12106
|
const scope = options.scope === "user" ? "user" : "project";
|
|
11945
12107
|
try {
|
|
11946
12108
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
11947
12109
|
console.log(
|
|
11948
|
-
|
|
12110
|
+
chalk59.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
11949
12111
|
);
|
|
11950
12112
|
} catch (error) {
|
|
11951
12113
|
handlePluginError(error);
|
|
@@ -11954,15 +12116,15 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11954
12116
|
console.log("Next step:");
|
|
11955
12117
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
11956
12118
|
console.log(
|
|
11957
|
-
|
|
12119
|
+
chalk59.cyan(
|
|
11958
12120
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
11959
12121
|
)
|
|
11960
12122
|
);
|
|
11961
12123
|
});
|
|
11962
12124
|
|
|
11963
12125
|
// src/index.ts
|
|
11964
|
-
var program = new
|
|
11965
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
12126
|
+
var program = new Command59();
|
|
12127
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.14.0");
|
|
11966
12128
|
program.addCommand(authCommand);
|
|
11967
12129
|
program.addCommand(infoCommand);
|
|
11968
12130
|
program.addCommand(composeCommand);
|