@vm0/cli 9.18.0 → 9.20.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 +818 -420
- 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 Command68 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/auth/index.ts
|
|
7
7
|
import { Command as Command5 } from "commander";
|
|
@@ -236,9 +236,9 @@ var infoCommand = new Command6().name("info").description("Display environment i
|
|
|
236
236
|
// src/commands/compose/index.ts
|
|
237
237
|
import { Command as Command7, Option } from "commander";
|
|
238
238
|
import chalk4 from "chalk";
|
|
239
|
-
import { readFile as readFile4 } from "fs/promises";
|
|
239
|
+
import { readFile as readFile4, rm as rm3 } from "fs/promises";
|
|
240
240
|
import { existsSync as existsSync4 } from "fs";
|
|
241
|
-
import { dirname as dirname2 } from "path";
|
|
241
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
242
242
|
import { parse as parseYaml2 } from "yaml";
|
|
243
243
|
|
|
244
244
|
// ../../packages/core/src/variable-expander.ts
|
|
@@ -3772,6 +3772,26 @@ async function httpGet(path16) {
|
|
|
3772
3772
|
headers
|
|
3773
3773
|
});
|
|
3774
3774
|
}
|
|
3775
|
+
async function httpPost(path16, body) {
|
|
3776
|
+
const baseUrl = await getBaseUrl();
|
|
3777
|
+
const headers = await getRawHeaders();
|
|
3778
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
3779
|
+
method: "POST",
|
|
3780
|
+
headers: {
|
|
3781
|
+
...headers,
|
|
3782
|
+
"Content-Type": "application/json"
|
|
3783
|
+
},
|
|
3784
|
+
body: JSON.stringify(body)
|
|
3785
|
+
});
|
|
3786
|
+
}
|
|
3787
|
+
async function httpDelete(path16) {
|
|
3788
|
+
const baseUrl = await getBaseUrl();
|
|
3789
|
+
const headers = await getRawHeaders();
|
|
3790
|
+
return fetch(`${baseUrl}${path16}`, {
|
|
3791
|
+
method: "DELETE",
|
|
3792
|
+
headers
|
|
3793
|
+
});
|
|
3794
|
+
}
|
|
3775
3795
|
|
|
3776
3796
|
// src/lib/api/domains/composes.ts
|
|
3777
3797
|
import { initClient } from "@ts-rest/core";
|
|
@@ -4427,11 +4447,6 @@ function validateAgentCompose(config) {
|
|
|
4427
4447
|
return { valid: true };
|
|
4428
4448
|
}
|
|
4429
4449
|
|
|
4430
|
-
// src/lib/storage/system-storage.ts
|
|
4431
|
-
import * as fs4 from "fs/promises";
|
|
4432
|
-
import * as path4 from "path";
|
|
4433
|
-
import * as os3 from "os";
|
|
4434
|
-
|
|
4435
4450
|
// src/lib/domain/github-skills.ts
|
|
4436
4451
|
import * as fs from "fs/promises";
|
|
4437
4452
|
import * as path from "path";
|
|
@@ -4474,6 +4489,49 @@ async function downloadGitHubSkill(parsed, destDir) {
|
|
|
4474
4489
|
await fs.rm(tempDir, { recursive: true, force: true });
|
|
4475
4490
|
}
|
|
4476
4491
|
}
|
|
4492
|
+
async function downloadGitHubDirectory(url) {
|
|
4493
|
+
const parsed = parseGitHubTreeUrl2(url);
|
|
4494
|
+
const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
|
|
4495
|
+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "vm0-github-"));
|
|
4496
|
+
try {
|
|
4497
|
+
try {
|
|
4498
|
+
await execAsync("git --version");
|
|
4499
|
+
} catch {
|
|
4500
|
+
throw new Error(
|
|
4501
|
+
"git command not found. Please install git to use GitHub URLs."
|
|
4502
|
+
);
|
|
4503
|
+
}
|
|
4504
|
+
await execAsync(`git init`, { cwd: tempDir });
|
|
4505
|
+
await execAsync(`git remote add origin "${repoUrl}"`, { cwd: tempDir });
|
|
4506
|
+
await execAsync(`git config core.sparseCheckout true`, { cwd: tempDir });
|
|
4507
|
+
const sparseFile = path.join(tempDir, ".git", "info", "sparse-checkout");
|
|
4508
|
+
await fs.writeFile(sparseFile, parsed.path + "\n");
|
|
4509
|
+
try {
|
|
4510
|
+
await execAsync(`git fetch --depth 1 origin "${parsed.branch}"`, {
|
|
4511
|
+
cwd: tempDir
|
|
4512
|
+
});
|
|
4513
|
+
} catch (error) {
|
|
4514
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
4515
|
+
if (message.includes("Authentication failed") || message.includes("could not read Username")) {
|
|
4516
|
+
throw new Error(`Cannot access repository. Is it private? URL: ${url}`);
|
|
4517
|
+
}
|
|
4518
|
+
if (message.includes("couldn't find remote ref")) {
|
|
4519
|
+
throw new Error(
|
|
4520
|
+
`Branch "${parsed.branch}" not found in repository: ${url}`
|
|
4521
|
+
);
|
|
4522
|
+
}
|
|
4523
|
+
throw error;
|
|
4524
|
+
}
|
|
4525
|
+
await execAsync(`git checkout "${parsed.branch}"`, { cwd: tempDir });
|
|
4526
|
+
return {
|
|
4527
|
+
dir: path.join(tempDir, parsed.path),
|
|
4528
|
+
tempRoot: tempDir
|
|
4529
|
+
};
|
|
4530
|
+
} catch (error) {
|
|
4531
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
4532
|
+
throw error;
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4477
4535
|
async function validateSkillDirectory(skillDir) {
|
|
4478
4536
|
const skillMdPath = path.join(skillDir, "SKILL.md");
|
|
4479
4537
|
try {
|
|
@@ -4516,6 +4574,11 @@ async function readSkillFrontmatter(skillDir) {
|
|
|
4516
4574
|
return parseSkillFrontmatter(content);
|
|
4517
4575
|
}
|
|
4518
4576
|
|
|
4577
|
+
// src/lib/storage/system-storage.ts
|
|
4578
|
+
import * as fs4 from "fs/promises";
|
|
4579
|
+
import * as path4 from "path";
|
|
4580
|
+
import * as os3 from "os";
|
|
4581
|
+
|
|
4519
4582
|
// src/lib/storage/direct-upload.ts
|
|
4520
4583
|
import { createHash } from "crypto";
|
|
4521
4584
|
import * as fs3 from "fs";
|
|
@@ -5144,6 +5207,9 @@ async function silentUpgradeAfterCommand(currentVersion) {
|
|
|
5144
5207
|
|
|
5145
5208
|
// src/commands/compose/index.ts
|
|
5146
5209
|
var DEFAULT_CONFIG_FILE = "vm0.yaml";
|
|
5210
|
+
function isGitHubTreeUrl(input) {
|
|
5211
|
+
return input.startsWith("https://github.com/") && input.includes("/tree/");
|
|
5212
|
+
}
|
|
5147
5213
|
function getSecretsFromComposeContent(content) {
|
|
5148
5214
|
const refs = extractVariableReferences(content);
|
|
5149
5215
|
const grouped = groupVariablesBySource(refs);
|
|
@@ -5177,6 +5243,14 @@ async function loadAndValidateConfig(configFile) {
|
|
|
5177
5243
|
const basePath = dirname2(configFile);
|
|
5178
5244
|
return { config, agentName, agent, basePath };
|
|
5179
5245
|
}
|
|
5246
|
+
function hasVolumes(config) {
|
|
5247
|
+
if (typeof config !== "object" || config === null) {
|
|
5248
|
+
return false;
|
|
5249
|
+
}
|
|
5250
|
+
const cfg = config;
|
|
5251
|
+
const volumes = cfg.volumes;
|
|
5252
|
+
return typeof volumes === "object" && volumes !== null && Object.keys(volumes).length > 0;
|
|
5253
|
+
}
|
|
5180
5254
|
function checkLegacyImageFormat(config) {
|
|
5181
5255
|
const cfg = config;
|
|
5182
5256
|
const agentsConfig = cfg.agents;
|
|
@@ -5326,47 +5400,140 @@ function mergeSkillVariables(agent, variables) {
|
|
|
5326
5400
|
agent.environment = environment;
|
|
5327
5401
|
}
|
|
5328
5402
|
}
|
|
5403
|
+
async function finalizeCompose(config, agent, variables, options) {
|
|
5404
|
+
const confirmed = await displayAndConfirmVariables(variables, options);
|
|
5405
|
+
if (!confirmed) {
|
|
5406
|
+
process.exit(0);
|
|
5407
|
+
}
|
|
5408
|
+
mergeSkillVariables(agent, variables);
|
|
5409
|
+
console.log("Uploading compose...");
|
|
5410
|
+
const response = await createOrUpdateCompose({ content: config });
|
|
5411
|
+
const scopeResponse = await getScope();
|
|
5412
|
+
const shortVersionId = response.versionId.slice(0, 8);
|
|
5413
|
+
const displayName = `${scopeResponse.slug}/${response.name}`;
|
|
5414
|
+
if (response.action === "created") {
|
|
5415
|
+
console.log(chalk4.green(`\u2713 Compose created: ${displayName}`));
|
|
5416
|
+
} else {
|
|
5417
|
+
console.log(chalk4.green(`\u2713 Compose version exists: ${displayName}`));
|
|
5418
|
+
}
|
|
5419
|
+
console.log(chalk4.dim(` Version: ${shortVersionId}`));
|
|
5420
|
+
console.log();
|
|
5421
|
+
console.log(" Run your agent:");
|
|
5422
|
+
console.log(
|
|
5423
|
+
chalk4.cyan(
|
|
5424
|
+
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
5425
|
+
)
|
|
5426
|
+
);
|
|
5427
|
+
if (options.autoUpdate !== false) {
|
|
5428
|
+
await silentUpgradeAfterCommand("9.20.0");
|
|
5429
|
+
}
|
|
5430
|
+
}
|
|
5431
|
+
async function handleGitHubCompose(url, options) {
|
|
5432
|
+
console.log(`Downloading from GitHub: ${url}`);
|
|
5433
|
+
const { dir: downloadedDir, tempRoot } = await downloadGitHubDirectory(url);
|
|
5434
|
+
const configFile = join6(downloadedDir, "vm0.yaml");
|
|
5435
|
+
try {
|
|
5436
|
+
if (!existsSync4(configFile)) {
|
|
5437
|
+
console.error(chalk4.red(`\u2717 vm0.yaml not found in the GitHub directory`));
|
|
5438
|
+
console.error(chalk4.dim(` URL: ${url}`));
|
|
5439
|
+
process.exit(1);
|
|
5440
|
+
}
|
|
5441
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(configFile);
|
|
5442
|
+
const existingCompose = await getComposeByName(agentName);
|
|
5443
|
+
if (existingCompose) {
|
|
5444
|
+
console.log();
|
|
5445
|
+
console.log(
|
|
5446
|
+
chalk4.yellow(`\u26A0 An agent named "${agentName}" already exists.`)
|
|
5447
|
+
);
|
|
5448
|
+
if (!isInteractive()) {
|
|
5449
|
+
if (!options.yes) {
|
|
5450
|
+
console.error(
|
|
5451
|
+
chalk4.red(
|
|
5452
|
+
`\u2717 Cannot overwrite existing agent in non-interactive mode`
|
|
5453
|
+
)
|
|
5454
|
+
);
|
|
5455
|
+
console.error(
|
|
5456
|
+
chalk4.dim(
|
|
5457
|
+
` Use --yes flag to confirm overwriting the existing agent.`
|
|
5458
|
+
)
|
|
5459
|
+
);
|
|
5460
|
+
process.exit(1);
|
|
5461
|
+
}
|
|
5462
|
+
} else {
|
|
5463
|
+
const confirmed = await promptConfirm(
|
|
5464
|
+
"Do you want to overwrite it?",
|
|
5465
|
+
false
|
|
5466
|
+
);
|
|
5467
|
+
if (!confirmed) {
|
|
5468
|
+
console.log(chalk4.yellow("Compose cancelled."));
|
|
5469
|
+
process.exit(0);
|
|
5470
|
+
}
|
|
5471
|
+
}
|
|
5472
|
+
}
|
|
5473
|
+
if (hasVolumes(config)) {
|
|
5474
|
+
console.error(
|
|
5475
|
+
chalk4.red(`\u2717 Volumes are not supported for GitHub URL compose`)
|
|
5476
|
+
);
|
|
5477
|
+
console.error(
|
|
5478
|
+
chalk4.dim(
|
|
5479
|
+
` Clone the repository locally and run: vm0 compose ./path/to/vm0.yaml`
|
|
5480
|
+
)
|
|
5481
|
+
);
|
|
5482
|
+
process.exit(1);
|
|
5483
|
+
}
|
|
5484
|
+
checkLegacyImageFormat(config);
|
|
5485
|
+
const skillResults = await uploadAssets(agentName, agent, basePath);
|
|
5486
|
+
const environment = agent.environment || {};
|
|
5487
|
+
const variables = await collectSkillVariables(
|
|
5488
|
+
skillResults,
|
|
5489
|
+
environment,
|
|
5490
|
+
agentName
|
|
5491
|
+
);
|
|
5492
|
+
await finalizeCompose(config, agent, variables, options);
|
|
5493
|
+
} finally {
|
|
5494
|
+
await rm3(tempRoot, { recursive: true, force: true });
|
|
5495
|
+
}
|
|
5496
|
+
}
|
|
5329
5497
|
var composeCommand = new Command7().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument(
|
|
5330
5498
|
"[agent-yaml]",
|
|
5331
|
-
`Path to agent YAML file (default: ${DEFAULT_CONFIG_FILE})`
|
|
5332
|
-
).option("-y, --yes", "Skip confirmation prompts for skill requirements").
|
|
5499
|
+
`Path to agent YAML file or GitHub tree URL (default: ${DEFAULT_CONFIG_FILE})`
|
|
5500
|
+
).option("-y, --yes", "Skip confirmation prompts for skill requirements").option(
|
|
5501
|
+
"--experimental-shared-compose",
|
|
5502
|
+
"Enable GitHub URL compose (experimental)"
|
|
5503
|
+
).addOption(new Option("--no-auto-update").hideHelp()).action(
|
|
5333
5504
|
async (configFile, options) => {
|
|
5334
5505
|
const resolvedConfigFile = configFile ?? DEFAULT_CONFIG_FILE;
|
|
5335
5506
|
try {
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
if (response.action === "created") {
|
|
5356
|
-
console.log(chalk4.green(`\u2713 Compose created: ${displayName}`));
|
|
5507
|
+
if (isGitHubTreeUrl(resolvedConfigFile)) {
|
|
5508
|
+
if (!options.experimentalSharedCompose) {
|
|
5509
|
+
console.error(
|
|
5510
|
+
chalk4.red(
|
|
5511
|
+
"\u2717 Composing shared agents requires --experimental-shared-compose flag"
|
|
5512
|
+
)
|
|
5513
|
+
);
|
|
5514
|
+
console.error();
|
|
5515
|
+
console.error(
|
|
5516
|
+
chalk4.dim(
|
|
5517
|
+
" Composing agents from other users carries security risks."
|
|
5518
|
+
)
|
|
5519
|
+
);
|
|
5520
|
+
console.error(
|
|
5521
|
+
chalk4.dim(" Only compose agents from users you trust.")
|
|
5522
|
+
);
|
|
5523
|
+
process.exit(1);
|
|
5524
|
+
}
|
|
5525
|
+
await handleGitHubCompose(resolvedConfigFile, options);
|
|
5357
5526
|
} else {
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
)
|
|
5367
|
-
|
|
5368
|
-
if (options.autoUpdate !== false) {
|
|
5369
|
-
await silentUpgradeAfterCommand("9.18.0");
|
|
5527
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(resolvedConfigFile);
|
|
5528
|
+
checkLegacyImageFormat(config);
|
|
5529
|
+
const skillResults = await uploadAssets(agentName, agent, basePath);
|
|
5530
|
+
const environment = agent.environment || {};
|
|
5531
|
+
const variables = await collectSkillVariables(
|
|
5532
|
+
skillResults,
|
|
5533
|
+
environment,
|
|
5534
|
+
agentName
|
|
5535
|
+
);
|
|
5536
|
+
await finalizeCompose(config, agent, variables, options);
|
|
5370
5537
|
}
|
|
5371
5538
|
} catch (error) {
|
|
5372
5539
|
if (error instanceof Error) {
|
|
@@ -7524,10 +7691,39 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
7524
7691
|
).option(
|
|
7525
7692
|
"--model-provider <type>",
|
|
7526
7693
|
"Override model provider (e.g., anthropic-api-key)"
|
|
7527
|
-
).option("--verbose", "Show full tool inputs and outputs").
|
|
7694
|
+
).option("--verbose", "Show full tool inputs and outputs").option(
|
|
7695
|
+
"--experimental-shared-agent",
|
|
7696
|
+
"Allow running agents shared by other users (required when running scope/agent format)"
|
|
7697
|
+
).addOption(new Option2("--debug-no-mock-claude").hideHelp()).addOption(new Option2("--no-auto-update").hideHelp()).action(
|
|
7528
7698
|
async (identifier, prompt, options) => {
|
|
7529
7699
|
try {
|
|
7530
7700
|
const { scope, name, version } = parseIdentifier(identifier);
|
|
7701
|
+
if (scope && !options.experimentalSharedAgent) {
|
|
7702
|
+
const userScope = await getScope();
|
|
7703
|
+
const isOwnScope = userScope.slug === scope;
|
|
7704
|
+
if (!isOwnScope) {
|
|
7705
|
+
console.error(
|
|
7706
|
+
chalk9.red(
|
|
7707
|
+
`\u2717 Running shared agents requires --experimental-shared-agent flag`
|
|
7708
|
+
)
|
|
7709
|
+
);
|
|
7710
|
+
console.error();
|
|
7711
|
+
console.error(
|
|
7712
|
+
chalk9.dim(
|
|
7713
|
+
" Running agent from other users carries security risks."
|
|
7714
|
+
)
|
|
7715
|
+
);
|
|
7716
|
+
console.error(chalk9.dim(" Only run agents from users you trust."));
|
|
7717
|
+
console.error();
|
|
7718
|
+
console.error("Example:");
|
|
7719
|
+
console.error(
|
|
7720
|
+
chalk9.cyan(
|
|
7721
|
+
` vm0 run ${identifier} --experimental-shared-agent "your prompt"`
|
|
7722
|
+
)
|
|
7723
|
+
);
|
|
7724
|
+
process.exit(1);
|
|
7725
|
+
}
|
|
7726
|
+
}
|
|
7531
7727
|
let composeId;
|
|
7532
7728
|
let composeContent;
|
|
7533
7729
|
if (isUUID(name)) {
|
|
@@ -7597,7 +7793,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
7597
7793
|
}
|
|
7598
7794
|
showNextSteps(result);
|
|
7599
7795
|
if (options.autoUpdate !== false) {
|
|
7600
|
-
await silentUpgradeAfterCommand("9.
|
|
7796
|
+
await silentUpgradeAfterCommand("9.20.0");
|
|
7601
7797
|
}
|
|
7602
7798
|
} catch (error) {
|
|
7603
7799
|
handleRunError(error, identifier);
|
|
@@ -8705,11 +8901,11 @@ import { config as dotenvConfig2 } from "dotenv";
|
|
|
8705
8901
|
|
|
8706
8902
|
// src/lib/domain/cook-state.ts
|
|
8707
8903
|
import { homedir as homedir2 } from "os";
|
|
8708
|
-
import { join as
|
|
8904
|
+
import { join as join7 } from "path";
|
|
8709
8905
|
import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
8710
8906
|
import { existsSync as existsSync7 } from "fs";
|
|
8711
|
-
var CONFIG_DIR2 =
|
|
8712
|
-
var COOK_STATE_FILE =
|
|
8907
|
+
var CONFIG_DIR2 = join7(homedir2(), ".vm0");
|
|
8908
|
+
var COOK_STATE_FILE = join7(CONFIG_DIR2, "cook.json");
|
|
8713
8909
|
var STALE_THRESHOLD_MS = 48 * 60 * 60 * 1e3;
|
|
8714
8910
|
async function loadCookStateFile() {
|
|
8715
8911
|
if (!existsSync7(COOK_STATE_FILE)) {
|
|
@@ -9104,7 +9300,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
9104
9300
|
).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(
|
|
9105
9301
|
async (prompt, options) => {
|
|
9106
9302
|
if (options.autoUpdate !== false) {
|
|
9107
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
9303
|
+
const shouldExit = await checkAndUpgrade("9.20.0", prompt);
|
|
9108
9304
|
if (shouldExit) {
|
|
9109
9305
|
process.exit(0);
|
|
9110
9306
|
}
|
|
@@ -9679,14 +9875,14 @@ var setCommand = new Command33().name("set").description("Set your scope slug").
|
|
|
9679
9875
|
var scopeCommand = new Command34().name("scope").description("Manage your scope (namespace for agents)").addCommand(statusCommand4).addCommand(setCommand);
|
|
9680
9876
|
|
|
9681
9877
|
// src/commands/agent/index.ts
|
|
9682
|
-
import { Command as
|
|
9878
|
+
import { Command as Command43 } from "commander";
|
|
9683
9879
|
|
|
9684
9880
|
// src/commands/agent/clone.ts
|
|
9685
9881
|
import { Command as Command35 } from "commander";
|
|
9686
9882
|
import chalk36 from "chalk";
|
|
9687
9883
|
import { mkdtempSync as mkdtempSync5 } from "fs";
|
|
9688
|
-
import { mkdir as mkdir7, writeFile as writeFile6, readdir, copyFile, rm as
|
|
9689
|
-
import { join as
|
|
9884
|
+
import { mkdir as mkdir7, writeFile as writeFile6, readdir, copyFile, rm as rm4 } from "fs/promises";
|
|
9885
|
+
import { join as join8, dirname as dirname3 } from "path";
|
|
9690
9886
|
import { tmpdir as tmpdir7 } from "os";
|
|
9691
9887
|
import * as tar6 from "tar";
|
|
9692
9888
|
import { stringify as yamlStringify } from "yaml";
|
|
@@ -9722,21 +9918,21 @@ async function downloadInstructions(agentName, instructionsPath, destination) {
|
|
|
9722
9918
|
throw new Error(`Failed to download instructions: ${response.status}`);
|
|
9723
9919
|
}
|
|
9724
9920
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
9725
|
-
const tmpDir = mkdtempSync5(
|
|
9726
|
-
const tarPath =
|
|
9921
|
+
const tmpDir = mkdtempSync5(join8(tmpdir7(), "vm0-clone-"));
|
|
9922
|
+
const tarPath = join8(tmpDir, "archive.tar.gz");
|
|
9727
9923
|
await writeFile6(tarPath, buffer);
|
|
9728
9924
|
await tar6.extract({ file: tarPath, cwd: tmpDir, gzip: true });
|
|
9729
9925
|
const files = await readdir(tmpDir);
|
|
9730
9926
|
const mdFile = files.find((f) => f === "CLAUDE.md" || f === "AGENTS.md");
|
|
9731
9927
|
if (!mdFile) {
|
|
9732
9928
|
console.log(chalk36.yellow("\u26A0 No instructions file found in volume"));
|
|
9733
|
-
await
|
|
9929
|
+
await rm4(tmpDir, { recursive: true, force: true });
|
|
9734
9930
|
return false;
|
|
9735
9931
|
}
|
|
9736
|
-
const destPath =
|
|
9932
|
+
const destPath = join8(destination, instructionsPath);
|
|
9737
9933
|
await mkdir7(dirname3(destPath), { recursive: true });
|
|
9738
|
-
await copyFile(
|
|
9739
|
-
await
|
|
9934
|
+
await copyFile(join8(tmpDir, mdFile), destPath);
|
|
9935
|
+
await rm4(tmpDir, { recursive: true, force: true });
|
|
9740
9936
|
return true;
|
|
9741
9937
|
}
|
|
9742
9938
|
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) => {
|
|
@@ -9761,7 +9957,7 @@ var cloneCommand3 = new Command35().name("clone").description("Clone agent compo
|
|
|
9761
9957
|
const cleanedContent = cleanComposeContent(content);
|
|
9762
9958
|
const yamlContent = yamlStringify(cleanedContent);
|
|
9763
9959
|
await mkdir7(targetDir, { recursive: true });
|
|
9764
|
-
const yamlPath =
|
|
9960
|
+
const yamlPath = join8(targetDir, "vm0.yaml");
|
|
9765
9961
|
await writeFile6(yamlPath, yamlContent, "utf8");
|
|
9766
9962
|
console.log(chalk36.green("\u2713 Created vm0.yaml"));
|
|
9767
9963
|
const agentKey = Object.keys(content.agents)[0];
|
|
@@ -10099,12 +10295,214 @@ var statusCommand5 = new Command37().name("status").description("Show status of
|
|
|
10099
10295
|
}
|
|
10100
10296
|
});
|
|
10101
10297
|
|
|
10298
|
+
// src/commands/agent/public.ts
|
|
10299
|
+
import { Command as Command38 } from "commander";
|
|
10300
|
+
import chalk39 from "chalk";
|
|
10301
|
+
var publicCommand = new Command38().name("experimental-public").description("Make an agent public (accessible to all authenticated users)").argument("<name>", "Agent name").action(async (name) => {
|
|
10302
|
+
try {
|
|
10303
|
+
const compose = await getComposeByName(name);
|
|
10304
|
+
if (!compose) {
|
|
10305
|
+
console.error(chalk39.red(`\u2717 Agent not found: ${name}`));
|
|
10306
|
+
process.exit(1);
|
|
10307
|
+
}
|
|
10308
|
+
const scope = await getScope();
|
|
10309
|
+
const response = await httpPost(
|
|
10310
|
+
`/api/agent/composes/${compose.id}/permissions`,
|
|
10311
|
+
{ granteeType: "public" }
|
|
10312
|
+
);
|
|
10313
|
+
if (!response.ok) {
|
|
10314
|
+
const error = await response.json();
|
|
10315
|
+
if (response.status === 409) {
|
|
10316
|
+
console.log(chalk39.yellow(`Agent "${name}" is already public`));
|
|
10317
|
+
return;
|
|
10318
|
+
}
|
|
10319
|
+
throw new Error(error.error?.message || "Failed to make agent public");
|
|
10320
|
+
}
|
|
10321
|
+
const fullName = `${scope.slug}/${name}`;
|
|
10322
|
+
console.log(chalk39.green(`\u2713 Agent "${name}" is now public`));
|
|
10323
|
+
console.log();
|
|
10324
|
+
console.log("Others can now run your agent with:");
|
|
10325
|
+
console.log(
|
|
10326
|
+
chalk39.cyan(
|
|
10327
|
+
` vm0 run ${fullName} --experimental-shared-agent "your prompt"`
|
|
10328
|
+
)
|
|
10329
|
+
);
|
|
10330
|
+
} catch (error) {
|
|
10331
|
+
console.error(chalk39.red("\u2717 Failed to make agent public"));
|
|
10332
|
+
if (error instanceof Error) {
|
|
10333
|
+
console.error(chalk39.dim(` ${error.message}`));
|
|
10334
|
+
}
|
|
10335
|
+
process.exit(1);
|
|
10336
|
+
}
|
|
10337
|
+
});
|
|
10338
|
+
|
|
10339
|
+
// src/commands/agent/private.ts
|
|
10340
|
+
import { Command as Command39 } from "commander";
|
|
10341
|
+
import chalk40 from "chalk";
|
|
10342
|
+
var privateCommand = new Command39().name("experimental-private").description("Make an agent private (remove public access)").argument("<name>", "Agent name").action(async (name) => {
|
|
10343
|
+
try {
|
|
10344
|
+
const compose = await getComposeByName(name);
|
|
10345
|
+
if (!compose) {
|
|
10346
|
+
console.error(chalk40.red(`\u2717 Agent not found: ${name}`));
|
|
10347
|
+
process.exit(1);
|
|
10348
|
+
}
|
|
10349
|
+
const response = await httpDelete(
|
|
10350
|
+
`/api/agent/composes/${compose.id}/permissions?type=public`
|
|
10351
|
+
);
|
|
10352
|
+
if (!response.ok) {
|
|
10353
|
+
const error = await response.json();
|
|
10354
|
+
if (response.status === 404) {
|
|
10355
|
+
console.log(chalk40.yellow(`Agent "${name}" is already private`));
|
|
10356
|
+
return;
|
|
10357
|
+
}
|
|
10358
|
+
throw new Error(error.error?.message || "Failed to make agent private");
|
|
10359
|
+
}
|
|
10360
|
+
console.log(chalk40.green(`\u2713 Agent "${name}" is now private`));
|
|
10361
|
+
} catch (error) {
|
|
10362
|
+
console.error(chalk40.red("\u2717 Failed to make agent private"));
|
|
10363
|
+
if (error instanceof Error) {
|
|
10364
|
+
console.error(chalk40.dim(` ${error.message}`));
|
|
10365
|
+
}
|
|
10366
|
+
process.exit(1);
|
|
10367
|
+
}
|
|
10368
|
+
});
|
|
10369
|
+
|
|
10370
|
+
// src/commands/agent/share.ts
|
|
10371
|
+
import { Command as Command40 } from "commander";
|
|
10372
|
+
import chalk41 from "chalk";
|
|
10373
|
+
var shareCommand = new Command40().name("experimental-share").description("Share an agent with a user by email").argument("<name>", "Agent name").requiredOption("--email <email>", "Email address to share with").action(async (name, options) => {
|
|
10374
|
+
try {
|
|
10375
|
+
const compose = await getComposeByName(name);
|
|
10376
|
+
if (!compose) {
|
|
10377
|
+
console.error(chalk41.red(`\u2717 Agent not found: ${name}`));
|
|
10378
|
+
process.exit(1);
|
|
10379
|
+
}
|
|
10380
|
+
const scope = await getScope();
|
|
10381
|
+
const response = await httpPost(
|
|
10382
|
+
`/api/agent/composes/${compose.id}/permissions`,
|
|
10383
|
+
{ granteeType: "email", granteeEmail: options.email }
|
|
10384
|
+
);
|
|
10385
|
+
if (!response.ok) {
|
|
10386
|
+
const error = await response.json();
|
|
10387
|
+
if (response.status === 409) {
|
|
10388
|
+
console.log(
|
|
10389
|
+
chalk41.yellow(
|
|
10390
|
+
`Agent "${name}" is already shared with ${options.email}`
|
|
10391
|
+
)
|
|
10392
|
+
);
|
|
10393
|
+
return;
|
|
10394
|
+
}
|
|
10395
|
+
throw new Error(error.error?.message || "Failed to share agent");
|
|
10396
|
+
}
|
|
10397
|
+
const fullName = `${scope.slug}/${name}`;
|
|
10398
|
+
console.log(
|
|
10399
|
+
chalk41.green(`\u2713 Agent "${name}" shared with ${options.email}`)
|
|
10400
|
+
);
|
|
10401
|
+
console.log();
|
|
10402
|
+
console.log("They can now run your agent with:");
|
|
10403
|
+
console.log(
|
|
10404
|
+
chalk41.cyan(
|
|
10405
|
+
` vm0 run ${fullName} --experimental-shared-agent "your prompt"`
|
|
10406
|
+
)
|
|
10407
|
+
);
|
|
10408
|
+
} catch (error) {
|
|
10409
|
+
console.error(chalk41.red("\u2717 Failed to share agent"));
|
|
10410
|
+
if (error instanceof Error) {
|
|
10411
|
+
console.error(chalk41.dim(` ${error.message}`));
|
|
10412
|
+
}
|
|
10413
|
+
process.exit(1);
|
|
10414
|
+
}
|
|
10415
|
+
});
|
|
10416
|
+
|
|
10417
|
+
// src/commands/agent/unshare.ts
|
|
10418
|
+
import { Command as Command41 } from "commander";
|
|
10419
|
+
import chalk42 from "chalk";
|
|
10420
|
+
var unshareCommand = new Command41().name("experimental-unshare").description("Remove sharing from a user").argument("<name>", "Agent name").requiredOption("--email <email>", "Email address to unshare").action(async (name, options) => {
|
|
10421
|
+
try {
|
|
10422
|
+
const compose = await getComposeByName(name);
|
|
10423
|
+
if (!compose) {
|
|
10424
|
+
console.error(chalk42.red(`\u2717 Agent not found: ${name}`));
|
|
10425
|
+
process.exit(1);
|
|
10426
|
+
}
|
|
10427
|
+
const response = await httpDelete(
|
|
10428
|
+
`/api/agent/composes/${compose.id}/permissions?type=email&email=${encodeURIComponent(options.email)}`
|
|
10429
|
+
);
|
|
10430
|
+
if (!response.ok) {
|
|
10431
|
+
const error = await response.json();
|
|
10432
|
+
if (response.status === 404) {
|
|
10433
|
+
console.log(
|
|
10434
|
+
chalk42.yellow(`Agent "${name}" is not shared with ${options.email}`)
|
|
10435
|
+
);
|
|
10436
|
+
return;
|
|
10437
|
+
}
|
|
10438
|
+
throw new Error(error.error?.message || "Failed to unshare agent");
|
|
10439
|
+
}
|
|
10440
|
+
console.log(
|
|
10441
|
+
chalk42.green(`\u2713 Removed sharing of "${name}" from ${options.email}`)
|
|
10442
|
+
);
|
|
10443
|
+
} catch (error) {
|
|
10444
|
+
console.error(chalk42.red("\u2717 Failed to unshare agent"));
|
|
10445
|
+
if (error instanceof Error) {
|
|
10446
|
+
console.error(chalk42.dim(` ${error.message}`));
|
|
10447
|
+
}
|
|
10448
|
+
process.exit(1);
|
|
10449
|
+
}
|
|
10450
|
+
});
|
|
10451
|
+
|
|
10452
|
+
// src/commands/agent/permission.ts
|
|
10453
|
+
import { Command as Command42 } from "commander";
|
|
10454
|
+
import chalk43 from "chalk";
|
|
10455
|
+
var permissionCommand = new Command42().name("experimental-permission").description("List all permissions for an agent").argument("<name>", "Agent name").action(async (name) => {
|
|
10456
|
+
try {
|
|
10457
|
+
const compose = await getComposeByName(name);
|
|
10458
|
+
if (!compose) {
|
|
10459
|
+
console.error(chalk43.red(`\u2717 Agent not found: ${name}`));
|
|
10460
|
+
process.exit(1);
|
|
10461
|
+
}
|
|
10462
|
+
const response = await httpGet(
|
|
10463
|
+
`/api/agent/composes/${compose.id}/permissions`
|
|
10464
|
+
);
|
|
10465
|
+
if (!response.ok) {
|
|
10466
|
+
const error = await response.json();
|
|
10467
|
+
throw new Error(error.error?.message || "Failed to list permissions");
|
|
10468
|
+
}
|
|
10469
|
+
const data = await response.json();
|
|
10470
|
+
if (data.permissions.length === 0) {
|
|
10471
|
+
console.log(chalk43.dim("No permissions set (private agent)"));
|
|
10472
|
+
return;
|
|
10473
|
+
}
|
|
10474
|
+
console.log(
|
|
10475
|
+
chalk43.dim(
|
|
10476
|
+
"TYPE EMAIL PERMISSION GRANTED"
|
|
10477
|
+
)
|
|
10478
|
+
);
|
|
10479
|
+
console.log(
|
|
10480
|
+
chalk43.dim(
|
|
10481
|
+
"------- ----------------------------- ---------- ----------"
|
|
10482
|
+
)
|
|
10483
|
+
);
|
|
10484
|
+
for (const p of data.permissions) {
|
|
10485
|
+
const type = p.granteeType.padEnd(7);
|
|
10486
|
+
const email = (p.granteeEmail ?? "-").padEnd(29);
|
|
10487
|
+
const permission = p.permission.padEnd(10);
|
|
10488
|
+
const granted = formatRelativeTime(p.createdAt);
|
|
10489
|
+
console.log(`${type} ${email} ${permission} ${granted}`);
|
|
10490
|
+
}
|
|
10491
|
+
} catch (error) {
|
|
10492
|
+
console.error(chalk43.red("\u2717 Failed to list permissions"));
|
|
10493
|
+
if (error instanceof Error) {
|
|
10494
|
+
console.error(chalk43.dim(` ${error.message}`));
|
|
10495
|
+
}
|
|
10496
|
+
process.exit(1);
|
|
10497
|
+
}
|
|
10498
|
+
});
|
|
10499
|
+
|
|
10102
10500
|
// src/commands/agent/index.ts
|
|
10103
|
-
var agentCommand = new
|
|
10501
|
+
var agentCommand = new Command43().name("agent").description("Manage agent composes").addCommand(cloneCommand3).addCommand(listCommand4).addCommand(statusCommand5).addCommand(publicCommand).addCommand(privateCommand).addCommand(shareCommand).addCommand(unshareCommand).addCommand(permissionCommand);
|
|
10104
10502
|
|
|
10105
10503
|
// src/commands/init/index.ts
|
|
10106
|
-
import { Command as
|
|
10107
|
-
import
|
|
10504
|
+
import { Command as Command44 } from "commander";
|
|
10505
|
+
import chalk44 from "chalk";
|
|
10108
10506
|
import path15 from "path";
|
|
10109
10507
|
import { existsSync as existsSync10 } from "fs";
|
|
10110
10508
|
import { writeFile as writeFile7 } from "fs/promises";
|
|
@@ -10142,14 +10540,14 @@ function checkExistingFiles() {
|
|
|
10142
10540
|
if (existsSync10(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
10143
10541
|
return existingFiles;
|
|
10144
10542
|
}
|
|
10145
|
-
var initCommand3 = new
|
|
10543
|
+
var initCommand3 = new Command44().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) => {
|
|
10146
10544
|
const existingFiles = checkExistingFiles();
|
|
10147
10545
|
if (existingFiles.length > 0 && !options.force) {
|
|
10148
10546
|
for (const file of existingFiles) {
|
|
10149
|
-
console.log(
|
|
10547
|
+
console.log(chalk44.red(`\u2717 ${file} already exists`));
|
|
10150
10548
|
}
|
|
10151
10549
|
console.log();
|
|
10152
|
-
console.log(`To overwrite: ${
|
|
10550
|
+
console.log(`To overwrite: ${chalk44.cyan("vm0 init --force")}`);
|
|
10153
10551
|
process.exit(1);
|
|
10154
10552
|
}
|
|
10155
10553
|
let agentName;
|
|
@@ -10157,9 +10555,9 @@ var initCommand3 = new Command39().name("init").description("Initialize a new VM
|
|
|
10157
10555
|
agentName = options.name.trim();
|
|
10158
10556
|
} else if (!isInteractive()) {
|
|
10159
10557
|
console.error(
|
|
10160
|
-
|
|
10558
|
+
chalk44.red("\u2717 --name flag is required in non-interactive mode")
|
|
10161
10559
|
);
|
|
10162
|
-
console.error(
|
|
10560
|
+
console.error(chalk44.dim(" Usage: vm0 init --name <agent-name>"));
|
|
10163
10561
|
process.exit(1);
|
|
10164
10562
|
} else {
|
|
10165
10563
|
const dirName = path15.basename(process.cwd());
|
|
@@ -10175,47 +10573,47 @@ var initCommand3 = new Command39().name("init").description("Initialize a new VM
|
|
|
10175
10573
|
}
|
|
10176
10574
|
);
|
|
10177
10575
|
if (name === void 0) {
|
|
10178
|
-
console.log(
|
|
10576
|
+
console.log(chalk44.dim("Cancelled"));
|
|
10179
10577
|
return;
|
|
10180
10578
|
}
|
|
10181
10579
|
agentName = name;
|
|
10182
10580
|
}
|
|
10183
10581
|
if (!agentName || !validateAgentName(agentName)) {
|
|
10184
|
-
console.log(
|
|
10582
|
+
console.log(chalk44.red("\u2717 Invalid agent name"));
|
|
10185
10583
|
console.log(
|
|
10186
|
-
|
|
10584
|
+
chalk44.dim(" Must be 3-64 characters, alphanumeric and hyphens only")
|
|
10187
10585
|
);
|
|
10188
|
-
console.log(
|
|
10586
|
+
console.log(chalk44.dim(" Must start and end with letter or number"));
|
|
10189
10587
|
process.exit(1);
|
|
10190
10588
|
}
|
|
10191
10589
|
await writeFile7(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
10192
10590
|
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
10193
|
-
console.log(
|
|
10591
|
+
console.log(chalk44.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
10194
10592
|
await writeFile7(AGENTS_MD_FILE, generateAgentsMd());
|
|
10195
10593
|
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
10196
|
-
console.log(
|
|
10594
|
+
console.log(chalk44.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
10197
10595
|
console.log();
|
|
10198
10596
|
console.log("Next steps:");
|
|
10199
10597
|
console.log(
|
|
10200
|
-
` 1. Set up model provider (one-time): ${
|
|
10598
|
+
` 1. Set up model provider (one-time): ${chalk44.cyan("vm0 model-provider setup")}`
|
|
10201
10599
|
);
|
|
10202
10600
|
console.log(
|
|
10203
|
-
` 2. Edit ${
|
|
10601
|
+
` 2. Edit ${chalk44.cyan("AGENTS.md")} to customize your agent's workflow`
|
|
10204
10602
|
);
|
|
10205
10603
|
console.log(
|
|
10206
|
-
` Or install Claude plugin: ${
|
|
10604
|
+
` Or install Claude plugin: ${chalk44.cyan(`vm0 setup-claude && claude "/vm0-agent let's build an agent"`)}`
|
|
10207
10605
|
);
|
|
10208
10606
|
console.log(
|
|
10209
|
-
` 3. Run your agent: ${
|
|
10607
|
+
` 3. Run your agent: ${chalk44.cyan(`vm0 cook "let's start working"`)}`
|
|
10210
10608
|
);
|
|
10211
10609
|
});
|
|
10212
10610
|
|
|
10213
10611
|
// src/commands/schedule/index.ts
|
|
10214
|
-
import { Command as
|
|
10612
|
+
import { Command as Command51 } from "commander";
|
|
10215
10613
|
|
|
10216
10614
|
// src/commands/schedule/setup.ts
|
|
10217
|
-
import { Command as
|
|
10218
|
-
import
|
|
10615
|
+
import { Command as Command45 } from "commander";
|
|
10616
|
+
import chalk46 from "chalk";
|
|
10219
10617
|
|
|
10220
10618
|
// src/lib/domain/schedule-utils.ts
|
|
10221
10619
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -10357,7 +10755,7 @@ async function resolveScheduleByAgent(agentName) {
|
|
|
10357
10755
|
}
|
|
10358
10756
|
|
|
10359
10757
|
// src/commands/schedule/gather-configuration.ts
|
|
10360
|
-
import
|
|
10758
|
+
import chalk45 from "chalk";
|
|
10361
10759
|
var defaultPromptDeps = {
|
|
10362
10760
|
isInteractive,
|
|
10363
10761
|
promptConfirm,
|
|
@@ -10385,7 +10783,7 @@ async function handleExistingSecrets(existingSecretNames, deps) {
|
|
|
10385
10783
|
return true;
|
|
10386
10784
|
}
|
|
10387
10785
|
console.log(
|
|
10388
|
-
|
|
10786
|
+
chalk45.dim(
|
|
10389
10787
|
" Note: Secrets will be cleared. Use 'vm0 secret set' to add platform secrets."
|
|
10390
10788
|
)
|
|
10391
10789
|
);
|
|
@@ -10410,21 +10808,21 @@ async function handleVars(optionVars, existingVars, deps) {
|
|
|
10410
10808
|
}
|
|
10411
10809
|
function displayMissingRequirements(missingSecrets, missingVars) {
|
|
10412
10810
|
if (missingSecrets.length > 0) {
|
|
10413
|
-
console.log(
|
|
10811
|
+
console.log(chalk45.yellow("\nAgent requires the following secrets:"));
|
|
10414
10812
|
for (const name of missingSecrets) {
|
|
10415
|
-
console.log(
|
|
10813
|
+
console.log(chalk45.dim(` ${name}`));
|
|
10416
10814
|
}
|
|
10417
10815
|
console.log();
|
|
10418
10816
|
console.log("Set secrets using the platform:");
|
|
10419
10817
|
for (const name of missingSecrets) {
|
|
10420
|
-
console.log(
|
|
10818
|
+
console.log(chalk45.cyan(` vm0 secret set ${name} <value>`));
|
|
10421
10819
|
}
|
|
10422
10820
|
console.log();
|
|
10423
10821
|
}
|
|
10424
10822
|
if (missingVars.length > 0) {
|
|
10425
|
-
console.log(
|
|
10823
|
+
console.log(chalk45.yellow("\nAgent requires the following variables:"));
|
|
10426
10824
|
for (const name of missingVars) {
|
|
10427
|
-
console.log(
|
|
10825
|
+
console.log(chalk45.dim(` ${name}`));
|
|
10428
10826
|
}
|
|
10429
10827
|
console.log();
|
|
10430
10828
|
}
|
|
@@ -10432,7 +10830,7 @@ function displayMissingRequirements(missingSecrets, missingVars) {
|
|
|
10432
10830
|
async function promptForMissingVars(missingVars, vars, deps) {
|
|
10433
10831
|
for (const name of missingVars) {
|
|
10434
10832
|
const value = await deps.promptText(
|
|
10435
|
-
`Enter value for var ${
|
|
10833
|
+
`Enter value for var ${chalk45.cyan(name)}`,
|
|
10436
10834
|
""
|
|
10437
10835
|
);
|
|
10438
10836
|
if (value) {
|
|
@@ -10520,7 +10918,7 @@ function expandEnvVars(value) {
|
|
|
10520
10918
|
const envValue = process.env[varName];
|
|
10521
10919
|
if (envValue === void 0) {
|
|
10522
10920
|
console.warn(
|
|
10523
|
-
|
|
10921
|
+
chalk46.yellow(` Warning: Environment variable ${varName} not set`)
|
|
10524
10922
|
);
|
|
10525
10923
|
return match;
|
|
10526
10924
|
}
|
|
@@ -10587,7 +10985,7 @@ async function gatherFrequency(optionFrequency, existingFrequency) {
|
|
|
10587
10985
|
}
|
|
10588
10986
|
if (!isInteractive()) {
|
|
10589
10987
|
console.error(
|
|
10590
|
-
|
|
10988
|
+
chalk46.red("\u2717 --frequency is required (daily|weekly|monthly|once)")
|
|
10591
10989
|
);
|
|
10592
10990
|
process.exit(1);
|
|
10593
10991
|
}
|
|
@@ -10607,7 +11005,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10607
11005
|
const day2 = parseDayOption(optionDay, frequency);
|
|
10608
11006
|
if (day2 === void 0) {
|
|
10609
11007
|
console.error(
|
|
10610
|
-
|
|
11008
|
+
chalk46.red(
|
|
10611
11009
|
`\u2717 Invalid day: ${optionDay}. Use mon-sun for weekly or 1-31 for monthly.`
|
|
10612
11010
|
)
|
|
10613
11011
|
);
|
|
@@ -10616,7 +11014,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10616
11014
|
return day2;
|
|
10617
11015
|
}
|
|
10618
11016
|
if (!isInteractive()) {
|
|
10619
|
-
console.error(
|
|
11017
|
+
console.error(chalk46.red("\u2717 --day is required for weekly/monthly"));
|
|
10620
11018
|
process.exit(1);
|
|
10621
11019
|
}
|
|
10622
11020
|
if (frequency === "weekly") {
|
|
@@ -10635,7 +11033,7 @@ async function gatherDay(frequency, optionDay, existingDay) {
|
|
|
10635
11033
|
if (!dayStr) return null;
|
|
10636
11034
|
const day = parseInt(dayStr, 10);
|
|
10637
11035
|
if (isNaN(day) || day < 1 || day > 31) {
|
|
10638
|
-
console.error(
|
|
11036
|
+
console.error(chalk46.red("\u2717 Day must be between 1 and 31"));
|
|
10639
11037
|
process.exit(1);
|
|
10640
11038
|
}
|
|
10641
11039
|
return day;
|
|
@@ -10644,13 +11042,13 @@ async function gatherRecurringTime(optionTime, existingTime) {
|
|
|
10644
11042
|
if (optionTime) {
|
|
10645
11043
|
const validation = validateTimeFormat(optionTime);
|
|
10646
11044
|
if (validation !== true) {
|
|
10647
|
-
console.error(
|
|
11045
|
+
console.error(chalk46.red(`\u2717 Invalid time: ${validation}`));
|
|
10648
11046
|
process.exit(1);
|
|
10649
11047
|
}
|
|
10650
11048
|
return optionTime;
|
|
10651
11049
|
}
|
|
10652
11050
|
if (!isInteractive()) {
|
|
10653
|
-
console.error(
|
|
11051
|
+
console.error(chalk46.red("\u2717 --time is required (HH:MM format)"));
|
|
10654
11052
|
process.exit(1);
|
|
10655
11053
|
}
|
|
10656
11054
|
return await promptText(
|
|
@@ -10663,7 +11061,7 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
10663
11061
|
if (optionDay && optionTime) {
|
|
10664
11062
|
if (!validateDateFormat(optionDay)) {
|
|
10665
11063
|
console.error(
|
|
10666
|
-
|
|
11064
|
+
chalk46.red(
|
|
10667
11065
|
`\u2717 Invalid date format: ${optionDay}. Use YYYY-MM-DD format.`
|
|
10668
11066
|
)
|
|
10669
11067
|
);
|
|
@@ -10671,16 +11069,16 @@ async function gatherOneTimeSchedule(optionDay, optionTime, existingTime) {
|
|
|
10671
11069
|
}
|
|
10672
11070
|
if (!validateTimeFormat(optionTime)) {
|
|
10673
11071
|
console.error(
|
|
10674
|
-
|
|
11072
|
+
chalk46.red(`\u2717 Invalid time format: ${optionTime}. Use HH:MM format.`)
|
|
10675
11073
|
);
|
|
10676
11074
|
process.exit(1);
|
|
10677
11075
|
}
|
|
10678
11076
|
return `${optionDay} ${optionTime}`;
|
|
10679
11077
|
}
|
|
10680
11078
|
if (!isInteractive()) {
|
|
10681
|
-
console.error(
|
|
11079
|
+
console.error(chalk46.red("\u2717 One-time schedules require interactive mode"));
|
|
10682
11080
|
console.error(
|
|
10683
|
-
|
|
11081
|
+
chalk46.dim(" Or provide --day (YYYY-MM-DD) and --time (HH:MM) flags")
|
|
10684
11082
|
);
|
|
10685
11083
|
process.exit(1);
|
|
10686
11084
|
}
|
|
@@ -10711,7 +11109,7 @@ async function gatherTimezone(optionTimezone, existingTimezone) {
|
|
|
10711
11109
|
async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
10712
11110
|
if (optionPrompt) return optionPrompt;
|
|
10713
11111
|
if (!isInteractive()) {
|
|
10714
|
-
console.error(
|
|
11112
|
+
console.error(chalk46.red("\u2717 --prompt is required"));
|
|
10715
11113
|
process.exit(1);
|
|
10716
11114
|
}
|
|
10717
11115
|
return await promptText(
|
|
@@ -10722,8 +11120,8 @@ async function gatherPromptText(optionPrompt, existingPrompt) {
|
|
|
10722
11120
|
async function resolveAgent(agentName) {
|
|
10723
11121
|
const compose = await getComposeByName(agentName);
|
|
10724
11122
|
if (!compose) {
|
|
10725
|
-
console.error(
|
|
10726
|
-
console.error(
|
|
11123
|
+
console.error(chalk46.red(`\u2717 Agent not found: ${agentName}`));
|
|
11124
|
+
console.error(chalk46.dim(" Make sure the agent is composed first"));
|
|
10727
11125
|
process.exit(1);
|
|
10728
11126
|
}
|
|
10729
11127
|
return {
|
|
@@ -10770,7 +11168,7 @@ async function buildAndDeploy(params) {
|
|
|
10770
11168
|
const expandedSecrets = expandEnvVarsInObject(params.secrets);
|
|
10771
11169
|
console.log(
|
|
10772
11170
|
`
|
|
10773
|
-
Deploying schedule for agent ${
|
|
11171
|
+
Deploying schedule for agent ${chalk46.cyan(params.agentName)}...`
|
|
10774
11172
|
);
|
|
10775
11173
|
const deployResult = await deploySchedule({
|
|
10776
11174
|
name: params.scheduleName,
|
|
@@ -10786,12 +11184,12 @@ Deploying schedule for agent ${chalk41.cyan(params.agentName)}...`
|
|
|
10786
11184
|
return deployResult;
|
|
10787
11185
|
}
|
|
10788
11186
|
function handleSetupError(error) {
|
|
10789
|
-
console.error(
|
|
11187
|
+
console.error(chalk46.red("\u2717 Failed to setup schedule"));
|
|
10790
11188
|
if (error instanceof Error) {
|
|
10791
11189
|
if (error.message.includes("Not authenticated")) {
|
|
10792
|
-
console.error(
|
|
11190
|
+
console.error(chalk46.dim(" Run: vm0 auth login"));
|
|
10793
11191
|
} else {
|
|
10794
|
-
console.error(
|
|
11192
|
+
console.error(chalk46.dim(` ${error.message}`));
|
|
10795
11193
|
}
|
|
10796
11194
|
}
|
|
10797
11195
|
process.exit(1);
|
|
@@ -10799,56 +11197,56 @@ function handleSetupError(error) {
|
|
|
10799
11197
|
function displayDeployResult(agentName, deployResult) {
|
|
10800
11198
|
if (deployResult.created) {
|
|
10801
11199
|
console.log(
|
|
10802
|
-
|
|
11200
|
+
chalk46.green(`\u2713 Created schedule for agent ${chalk46.cyan(agentName)}`)
|
|
10803
11201
|
);
|
|
10804
11202
|
} else {
|
|
10805
11203
|
console.log(
|
|
10806
|
-
|
|
11204
|
+
chalk46.green(`\u2713 Updated schedule for agent ${chalk46.cyan(agentName)}`)
|
|
10807
11205
|
);
|
|
10808
11206
|
}
|
|
10809
|
-
console.log(
|
|
11207
|
+
console.log(chalk46.dim(` Timezone: ${deployResult.schedule.timezone}`));
|
|
10810
11208
|
if (deployResult.schedule.cronExpression) {
|
|
10811
|
-
console.log(
|
|
11209
|
+
console.log(chalk46.dim(` Cron: ${deployResult.schedule.cronExpression}`));
|
|
10812
11210
|
if (deployResult.schedule.nextRunAt) {
|
|
10813
11211
|
const nextRun = formatInTimezone(
|
|
10814
11212
|
deployResult.schedule.nextRunAt,
|
|
10815
11213
|
deployResult.schedule.timezone
|
|
10816
11214
|
);
|
|
10817
|
-
console.log(
|
|
11215
|
+
console.log(chalk46.dim(` Next run: ${nextRun}`));
|
|
10818
11216
|
}
|
|
10819
11217
|
} else if (deployResult.schedule.atTime) {
|
|
10820
11218
|
const atTimeFormatted = formatInTimezone(
|
|
10821
11219
|
deployResult.schedule.atTime,
|
|
10822
11220
|
deployResult.schedule.timezone
|
|
10823
11221
|
);
|
|
10824
|
-
console.log(
|
|
11222
|
+
console.log(chalk46.dim(` At: ${atTimeFormatted}`));
|
|
10825
11223
|
}
|
|
10826
11224
|
}
|
|
10827
11225
|
async function tryEnableSchedule(scheduleName, composeId, agentName) {
|
|
10828
11226
|
try {
|
|
10829
11227
|
await enableSchedule({ name: scheduleName, composeId });
|
|
10830
11228
|
console.log(
|
|
10831
|
-
|
|
11229
|
+
chalk46.green(`\u2713 Enabled schedule for agent ${chalk46.cyan(agentName)}`)
|
|
10832
11230
|
);
|
|
10833
11231
|
} catch (error) {
|
|
10834
|
-
console.error(
|
|
11232
|
+
console.error(chalk46.yellow("\u26A0 Failed to enable schedule"));
|
|
10835
11233
|
if (error instanceof ApiRequestError) {
|
|
10836
11234
|
if (error.code === "SCHEDULE_PAST") {
|
|
10837
|
-
console.error(
|
|
11235
|
+
console.error(chalk46.dim(" Scheduled time has already passed"));
|
|
10838
11236
|
} else {
|
|
10839
|
-
console.error(
|
|
11237
|
+
console.error(chalk46.dim(` ${error.message}`));
|
|
10840
11238
|
}
|
|
10841
11239
|
} else if (error instanceof Error) {
|
|
10842
|
-
console.error(
|
|
11240
|
+
console.error(chalk46.dim(` ${error.message}`));
|
|
10843
11241
|
}
|
|
10844
11242
|
console.log(
|
|
10845
|
-
` To enable manually: ${
|
|
11243
|
+
` To enable manually: ${chalk46.cyan(`vm0 schedule enable ${agentName}`)}`
|
|
10846
11244
|
);
|
|
10847
11245
|
}
|
|
10848
11246
|
}
|
|
10849
11247
|
function showEnableHint(agentName) {
|
|
10850
11248
|
console.log();
|
|
10851
|
-
console.log(` To enable: ${
|
|
11249
|
+
console.log(` To enable: ${chalk46.cyan(`vm0 schedule enable ${agentName}`)}`);
|
|
10852
11250
|
}
|
|
10853
11251
|
async function handleScheduleEnabling(params) {
|
|
10854
11252
|
const { scheduleName, composeId, agentName, enableFlag, shouldPromptEnable } = params;
|
|
@@ -10869,13 +11267,13 @@ async function handleScheduleEnabling(params) {
|
|
|
10869
11267
|
showEnableHint(agentName);
|
|
10870
11268
|
}
|
|
10871
11269
|
}
|
|
10872
|
-
var setupCommand = new
|
|
11270
|
+
var setupCommand = new Command45().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("--artifact-name <name>", "Artifact name", "artifact").option("-e, --enable", "Enable schedule immediately after creation").action(async (agentName, options) => {
|
|
10873
11271
|
try {
|
|
10874
11272
|
const { composeId, scheduleName, composeContent } = await resolveAgent(agentName);
|
|
10875
11273
|
const requiredConfig = extractRequiredConfiguration(composeContent);
|
|
10876
11274
|
const existingSchedule = await findExistingSchedule(agentName);
|
|
10877
11275
|
console.log(
|
|
10878
|
-
|
|
11276
|
+
chalk46.dim(
|
|
10879
11277
|
existingSchedule ? `Editing existing schedule for agent ${agentName}` : `Creating new schedule for agent ${agentName}`
|
|
10880
11278
|
)
|
|
10881
11279
|
);
|
|
@@ -10885,12 +11283,12 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10885
11283
|
defaults.frequency
|
|
10886
11284
|
);
|
|
10887
11285
|
if (!frequency) {
|
|
10888
|
-
console.log(
|
|
11286
|
+
console.log(chalk46.dim("Cancelled"));
|
|
10889
11287
|
return;
|
|
10890
11288
|
}
|
|
10891
11289
|
const timing = await gatherTiming(frequency, options, defaults);
|
|
10892
11290
|
if (!timing) {
|
|
10893
|
-
console.log(
|
|
11291
|
+
console.log(chalk46.dim("Cancelled"));
|
|
10894
11292
|
return;
|
|
10895
11293
|
}
|
|
10896
11294
|
const { day, time, atTime } = timing;
|
|
@@ -10899,7 +11297,7 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10899
11297
|
existingSchedule?.timezone
|
|
10900
11298
|
);
|
|
10901
11299
|
if (!timezone) {
|
|
10902
|
-
console.log(
|
|
11300
|
+
console.log(chalk46.dim("Cancelled"));
|
|
10903
11301
|
return;
|
|
10904
11302
|
}
|
|
10905
11303
|
const promptText_ = await gatherPromptText(
|
|
@@ -10907,7 +11305,7 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10907
11305
|
existingSchedule?.prompt
|
|
10908
11306
|
);
|
|
10909
11307
|
if (!promptText_) {
|
|
10910
|
-
console.log(
|
|
11308
|
+
console.log(chalk46.dim("Cancelled"));
|
|
10911
11309
|
return;
|
|
10912
11310
|
}
|
|
10913
11311
|
const config = await gatherConfiguration({
|
|
@@ -10947,15 +11345,15 @@ var setupCommand = new Command40().name("setup").description("Create or edit a s
|
|
|
10947
11345
|
});
|
|
10948
11346
|
|
|
10949
11347
|
// src/commands/schedule/list.ts
|
|
10950
|
-
import { Command as
|
|
10951
|
-
import
|
|
10952
|
-
var listCommand5 = new
|
|
11348
|
+
import { Command as Command46 } from "commander";
|
|
11349
|
+
import chalk47 from "chalk";
|
|
11350
|
+
var listCommand5 = new Command46().name("list").alias("ls").description("List all schedules").action(async () => {
|
|
10953
11351
|
try {
|
|
10954
11352
|
const result = await listSchedules();
|
|
10955
11353
|
if (result.schedules.length === 0) {
|
|
10956
|
-
console.log(
|
|
11354
|
+
console.log(chalk47.dim("No schedules found"));
|
|
10957
11355
|
console.log(
|
|
10958
|
-
|
|
11356
|
+
chalk47.dim(" Create one with: vm0 schedule setup <agent-name>")
|
|
10959
11357
|
);
|
|
10960
11358
|
return;
|
|
10961
11359
|
}
|
|
@@ -10975,10 +11373,10 @@ var listCommand5 = new Command41().name("list").alias("ls").description("List al
|
|
|
10975
11373
|
"STATUS".padEnd(8),
|
|
10976
11374
|
"NEXT RUN"
|
|
10977
11375
|
].join(" ");
|
|
10978
|
-
console.log(
|
|
11376
|
+
console.log(chalk47.dim(header));
|
|
10979
11377
|
for (const schedule of result.schedules) {
|
|
10980
11378
|
const trigger = schedule.cronExpression ? `${schedule.cronExpression} (${schedule.timezone})` : schedule.atTime || "-";
|
|
10981
|
-
const status = schedule.enabled ?
|
|
11379
|
+
const status = schedule.enabled ? chalk47.green("enabled") : chalk47.yellow("disabled");
|
|
10982
11380
|
const nextRun = schedule.enabled ? formatRelativeTime2(schedule.nextRunAt) : "-";
|
|
10983
11381
|
const row = [
|
|
10984
11382
|
schedule.composeName.padEnd(agentWidth),
|
|
@@ -10990,12 +11388,12 @@ var listCommand5 = new Command41().name("list").alias("ls").description("List al
|
|
|
10990
11388
|
console.log(row);
|
|
10991
11389
|
}
|
|
10992
11390
|
} catch (error) {
|
|
10993
|
-
console.error(
|
|
11391
|
+
console.error(chalk47.red("\u2717 Failed to list schedules"));
|
|
10994
11392
|
if (error instanceof Error) {
|
|
10995
11393
|
if (error.message.includes("Not authenticated")) {
|
|
10996
|
-
console.error(
|
|
11394
|
+
console.error(chalk47.dim(" Run: vm0 auth login"));
|
|
10997
11395
|
} else {
|
|
10998
|
-
console.error(
|
|
11396
|
+
console.error(chalk47.dim(` ${error.message}`));
|
|
10999
11397
|
}
|
|
11000
11398
|
}
|
|
11001
11399
|
process.exit(1);
|
|
@@ -11003,45 +11401,45 @@ var listCommand5 = new Command41().name("list").alias("ls").description("List al
|
|
|
11003
11401
|
});
|
|
11004
11402
|
|
|
11005
11403
|
// src/commands/schedule/status.ts
|
|
11006
|
-
import { Command as
|
|
11007
|
-
import
|
|
11404
|
+
import { Command as Command47 } from "commander";
|
|
11405
|
+
import chalk48 from "chalk";
|
|
11008
11406
|
function formatDateTimeStyled(dateStr) {
|
|
11009
|
-
if (!dateStr) return
|
|
11407
|
+
if (!dateStr) return chalk48.dim("-");
|
|
11010
11408
|
const formatted = formatDateTime(dateStr);
|
|
11011
|
-
return formatted.replace(/\(([^)]+)\)$/,
|
|
11409
|
+
return formatted.replace(/\(([^)]+)\)$/, chalk48.dim("($1)"));
|
|
11012
11410
|
}
|
|
11013
11411
|
function formatTrigger(schedule) {
|
|
11014
11412
|
if (schedule.cronExpression) {
|
|
11015
11413
|
return schedule.cronExpression;
|
|
11016
11414
|
}
|
|
11017
11415
|
if (schedule.atTime) {
|
|
11018
|
-
return `${schedule.atTime} ${
|
|
11416
|
+
return `${schedule.atTime} ${chalk48.dim("(one-time)")}`;
|
|
11019
11417
|
}
|
|
11020
|
-
return
|
|
11418
|
+
return chalk48.dim("-");
|
|
11021
11419
|
}
|
|
11022
11420
|
function formatRunStatus2(status) {
|
|
11023
11421
|
switch (status) {
|
|
11024
11422
|
case "completed":
|
|
11025
|
-
return
|
|
11423
|
+
return chalk48.green(status);
|
|
11026
11424
|
case "failed":
|
|
11027
11425
|
case "timeout":
|
|
11028
|
-
return
|
|
11426
|
+
return chalk48.red(status);
|
|
11029
11427
|
case "running":
|
|
11030
|
-
return
|
|
11428
|
+
return chalk48.blue(status);
|
|
11031
11429
|
case "pending":
|
|
11032
|
-
return
|
|
11430
|
+
return chalk48.yellow(status);
|
|
11033
11431
|
default:
|
|
11034
11432
|
return status;
|
|
11035
11433
|
}
|
|
11036
11434
|
}
|
|
11037
11435
|
function printRunConfiguration(schedule) {
|
|
11038
|
-
const statusText = schedule.enabled ?
|
|
11436
|
+
const statusText = schedule.enabled ? chalk48.green("enabled") : chalk48.yellow("disabled");
|
|
11039
11437
|
console.log(`${"Status:".padEnd(16)}${statusText}`);
|
|
11040
11438
|
console.log(
|
|
11041
|
-
`${"Agent:".padEnd(16)}${schedule.composeName} ${
|
|
11439
|
+
`${"Agent:".padEnd(16)}${schedule.composeName} ${chalk48.dim(`(${schedule.scopeSlug})`)}`
|
|
11042
11440
|
);
|
|
11043
11441
|
const promptPreview = schedule.prompt.length > 60 ? schedule.prompt.slice(0, 57) + "..." : schedule.prompt;
|
|
11044
|
-
console.log(`${"Prompt:".padEnd(16)}${
|
|
11442
|
+
console.log(`${"Prompt:".padEnd(16)}${chalk48.dim(promptPreview)}`);
|
|
11045
11443
|
if (schedule.vars && Object.keys(schedule.vars).length > 0) {
|
|
11046
11444
|
console.log(
|
|
11047
11445
|
`${"Variables:".padEnd(16)}${Object.keys(schedule.vars).join(", ")}`
|
|
@@ -11078,7 +11476,7 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
11078
11476
|
console.log();
|
|
11079
11477
|
console.log("Recent Runs:");
|
|
11080
11478
|
console.log(
|
|
11081
|
-
|
|
11479
|
+
chalk48.dim("RUN ID STATUS CREATED")
|
|
11082
11480
|
);
|
|
11083
11481
|
for (const run of runs) {
|
|
11084
11482
|
const id = run.id;
|
|
@@ -11089,24 +11487,24 @@ async function printRecentRuns(name, composeId, limit) {
|
|
|
11089
11487
|
}
|
|
11090
11488
|
} catch {
|
|
11091
11489
|
console.log();
|
|
11092
|
-
console.log(
|
|
11490
|
+
console.log(chalk48.dim("Recent Runs: (unable to fetch)"));
|
|
11093
11491
|
}
|
|
11094
11492
|
}
|
|
11095
11493
|
function handleStatusError(error, agentName) {
|
|
11096
|
-
console.error(
|
|
11494
|
+
console.error(chalk48.red("\u2717 Failed to get schedule status"));
|
|
11097
11495
|
if (error instanceof Error) {
|
|
11098
11496
|
if (error.message.includes("Not authenticated")) {
|
|
11099
|
-
console.error(
|
|
11497
|
+
console.error(chalk48.dim(" Run: vm0 auth login"));
|
|
11100
11498
|
} else if (error.message.includes("not found") || error.message.includes("Not found") || error.message.includes("No schedule found")) {
|
|
11101
|
-
console.error(
|
|
11102
|
-
console.error(
|
|
11499
|
+
console.error(chalk48.dim(` No schedule found for agent "${agentName}"`));
|
|
11500
|
+
console.error(chalk48.dim(" Run: vm0 schedule list"));
|
|
11103
11501
|
} else {
|
|
11104
|
-
console.error(
|
|
11502
|
+
console.error(chalk48.dim(` ${error.message}`));
|
|
11105
11503
|
}
|
|
11106
11504
|
}
|
|
11107
11505
|
process.exit(1);
|
|
11108
11506
|
}
|
|
11109
|
-
var statusCommand6 = new
|
|
11507
|
+
var statusCommand6 = new Command47().name("status").description("Show detailed status of a schedule").argument("<agent-name>", "Agent name").option(
|
|
11110
11508
|
"-l, --limit <number>",
|
|
11111
11509
|
"Number of recent runs to show (0 to hide)",
|
|
11112
11510
|
"5"
|
|
@@ -11116,8 +11514,8 @@ var statusCommand6 = new Command42().name("status").description("Show detailed s
|
|
|
11116
11514
|
const { name, composeId } = resolved;
|
|
11117
11515
|
const schedule = await getScheduleByName({ name, composeId });
|
|
11118
11516
|
console.log();
|
|
11119
|
-
console.log(`Schedule for agent: ${
|
|
11120
|
-
console.log(
|
|
11517
|
+
console.log(`Schedule for agent: ${chalk48.cyan(agentName)}`);
|
|
11518
|
+
console.log(chalk48.dim("\u2501".repeat(50)));
|
|
11121
11519
|
printRunConfiguration(schedule);
|
|
11122
11520
|
printTimeSchedule(schedule);
|
|
11123
11521
|
const parsed = parseInt(options.limit, 10);
|
|
@@ -11133,24 +11531,24 @@ var statusCommand6 = new Command42().name("status").description("Show detailed s
|
|
|
11133
11531
|
});
|
|
11134
11532
|
|
|
11135
11533
|
// src/commands/schedule/delete.ts
|
|
11136
|
-
import { Command as
|
|
11137
|
-
import
|
|
11138
|
-
var deleteCommand = new
|
|
11534
|
+
import { Command as Command48 } from "commander";
|
|
11535
|
+
import chalk49 from "chalk";
|
|
11536
|
+
var deleteCommand = new Command48().name("delete").alias("rm").description("Delete a schedule").argument("<agent-name>", "Agent name").option("-f, --force", "Skip confirmation prompt").action(async (agentName, options) => {
|
|
11139
11537
|
try {
|
|
11140
11538
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
11141
11539
|
if (!options.force) {
|
|
11142
11540
|
if (!isInteractive()) {
|
|
11143
11541
|
console.error(
|
|
11144
|
-
|
|
11542
|
+
chalk49.red("\u2717 --force required in non-interactive mode")
|
|
11145
11543
|
);
|
|
11146
11544
|
process.exit(1);
|
|
11147
11545
|
}
|
|
11148
11546
|
const confirmed = await promptConfirm(
|
|
11149
|
-
`Delete schedule for agent ${
|
|
11547
|
+
`Delete schedule for agent ${chalk49.cyan(agentName)}?`,
|
|
11150
11548
|
false
|
|
11151
11549
|
);
|
|
11152
11550
|
if (!confirmed) {
|
|
11153
|
-
console.log(
|
|
11551
|
+
console.log(chalk49.dim("Cancelled"));
|
|
11154
11552
|
return;
|
|
11155
11553
|
}
|
|
11156
11554
|
}
|
|
@@ -11159,20 +11557,20 @@ var deleteCommand = new Command43().name("delete").alias("rm").description("Dele
|
|
|
11159
11557
|
composeId: resolved.composeId
|
|
11160
11558
|
});
|
|
11161
11559
|
console.log(
|
|
11162
|
-
|
|
11560
|
+
chalk49.green(`\u2713 Deleted schedule for agent ${chalk49.cyan(agentName)}`)
|
|
11163
11561
|
);
|
|
11164
11562
|
} catch (error) {
|
|
11165
|
-
console.error(
|
|
11563
|
+
console.error(chalk49.red("\u2717 Failed to delete schedule"));
|
|
11166
11564
|
if (error instanceof Error) {
|
|
11167
11565
|
if (error.message.includes("Not authenticated")) {
|
|
11168
|
-
console.error(
|
|
11566
|
+
console.error(chalk49.dim(" Run: vm0 auth login"));
|
|
11169
11567
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
11170
11568
|
console.error(
|
|
11171
|
-
|
|
11569
|
+
chalk49.dim(` No schedule found for agent "${agentName}"`)
|
|
11172
11570
|
);
|
|
11173
|
-
console.error(
|
|
11571
|
+
console.error(chalk49.dim(" Run: vm0 schedule list"));
|
|
11174
11572
|
} else {
|
|
11175
|
-
console.error(
|
|
11573
|
+
console.error(chalk49.dim(` ${error.message}`));
|
|
11176
11574
|
}
|
|
11177
11575
|
}
|
|
11178
11576
|
process.exit(1);
|
|
@@ -11180,9 +11578,9 @@ var deleteCommand = new Command43().name("delete").alias("rm").description("Dele
|
|
|
11180
11578
|
});
|
|
11181
11579
|
|
|
11182
11580
|
// src/commands/schedule/enable.ts
|
|
11183
|
-
import { Command as
|
|
11184
|
-
import
|
|
11185
|
-
var enableCommand = new
|
|
11581
|
+
import { Command as Command49 } from "commander";
|
|
11582
|
+
import chalk50 from "chalk";
|
|
11583
|
+
var enableCommand = new Command49().name("enable").description("Enable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
11186
11584
|
try {
|
|
11187
11585
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
11188
11586
|
await enableSchedule({
|
|
@@ -11190,34 +11588,34 @@ var enableCommand = new Command44().name("enable").description("Enable a schedul
|
|
|
11190
11588
|
composeId: resolved.composeId
|
|
11191
11589
|
});
|
|
11192
11590
|
console.log(
|
|
11193
|
-
|
|
11591
|
+
chalk50.green(`\u2713 Enabled schedule for agent ${chalk50.cyan(agentName)}`)
|
|
11194
11592
|
);
|
|
11195
11593
|
} catch (error) {
|
|
11196
|
-
console.error(
|
|
11594
|
+
console.error(chalk50.red("\u2717 Failed to enable schedule"));
|
|
11197
11595
|
if (error instanceof ApiRequestError) {
|
|
11198
11596
|
if (error.code === "SCHEDULE_PAST") {
|
|
11199
|
-
console.error(
|
|
11200
|
-
console.error(
|
|
11597
|
+
console.error(chalk50.dim(" Scheduled time has already passed"));
|
|
11598
|
+
console.error(chalk50.dim(` Run: vm0 schedule setup ${agentName}`));
|
|
11201
11599
|
} else if (error.code === "NOT_FOUND") {
|
|
11202
11600
|
console.error(
|
|
11203
|
-
|
|
11601
|
+
chalk50.dim(` No schedule found for agent "${agentName}"`)
|
|
11204
11602
|
);
|
|
11205
|
-
console.error(
|
|
11603
|
+
console.error(chalk50.dim(" Run: vm0 schedule list"));
|
|
11206
11604
|
} else if (error.code === "UNAUTHORIZED") {
|
|
11207
|
-
console.error(
|
|
11605
|
+
console.error(chalk50.dim(" Run: vm0 auth login"));
|
|
11208
11606
|
} else {
|
|
11209
|
-
console.error(
|
|
11607
|
+
console.error(chalk50.dim(` ${error.message}`));
|
|
11210
11608
|
}
|
|
11211
11609
|
} else if (error instanceof Error) {
|
|
11212
11610
|
if (error.message.includes("Not authenticated")) {
|
|
11213
|
-
console.error(
|
|
11611
|
+
console.error(chalk50.dim(" Run: vm0 auth login"));
|
|
11214
11612
|
} else if (error.message.includes("No schedule found")) {
|
|
11215
11613
|
console.error(
|
|
11216
|
-
|
|
11614
|
+
chalk50.dim(` No schedule found for agent "${agentName}"`)
|
|
11217
11615
|
);
|
|
11218
|
-
console.error(
|
|
11616
|
+
console.error(chalk50.dim(" Run: vm0 schedule list"));
|
|
11219
11617
|
} else {
|
|
11220
|
-
console.error(
|
|
11618
|
+
console.error(chalk50.dim(` ${error.message}`));
|
|
11221
11619
|
}
|
|
11222
11620
|
}
|
|
11223
11621
|
process.exit(1);
|
|
@@ -11225,9 +11623,9 @@ var enableCommand = new Command44().name("enable").description("Enable a schedul
|
|
|
11225
11623
|
});
|
|
11226
11624
|
|
|
11227
11625
|
// src/commands/schedule/disable.ts
|
|
11228
|
-
import { Command as
|
|
11229
|
-
import
|
|
11230
|
-
var disableCommand = new
|
|
11626
|
+
import { Command as Command50 } from "commander";
|
|
11627
|
+
import chalk51 from "chalk";
|
|
11628
|
+
var disableCommand = new Command50().name("disable").description("Disable a schedule").argument("<agent-name>", "Agent name").action(async (agentName) => {
|
|
11231
11629
|
try {
|
|
11232
11630
|
const resolved = await resolveScheduleByAgent(agentName);
|
|
11233
11631
|
await disableSchedule({
|
|
@@ -11235,20 +11633,20 @@ var disableCommand = new Command45().name("disable").description("Disable a sche
|
|
|
11235
11633
|
composeId: resolved.composeId
|
|
11236
11634
|
});
|
|
11237
11635
|
console.log(
|
|
11238
|
-
|
|
11636
|
+
chalk51.green(`\u2713 Disabled schedule for agent ${chalk51.cyan(agentName)}`)
|
|
11239
11637
|
);
|
|
11240
11638
|
} catch (error) {
|
|
11241
|
-
console.error(
|
|
11639
|
+
console.error(chalk51.red("\u2717 Failed to disable schedule"));
|
|
11242
11640
|
if (error instanceof Error) {
|
|
11243
11641
|
if (error.message.includes("Not authenticated")) {
|
|
11244
|
-
console.error(
|
|
11642
|
+
console.error(chalk51.dim(" Run: vm0 auth login"));
|
|
11245
11643
|
} else if (error.message.toLowerCase().includes("not found") || error.message.includes("No schedule found")) {
|
|
11246
11644
|
console.error(
|
|
11247
|
-
|
|
11645
|
+
chalk51.dim(` No schedule found for agent "${agentName}"`)
|
|
11248
11646
|
);
|
|
11249
|
-
console.error(
|
|
11647
|
+
console.error(chalk51.dim(" Run: vm0 schedule list"));
|
|
11250
11648
|
} else {
|
|
11251
|
-
console.error(
|
|
11649
|
+
console.error(chalk51.dim(` ${error.message}`));
|
|
11252
11650
|
}
|
|
11253
11651
|
}
|
|
11254
11652
|
process.exit(1);
|
|
@@ -11256,11 +11654,11 @@ var disableCommand = new Command45().name("disable").description("Disable a sche
|
|
|
11256
11654
|
});
|
|
11257
11655
|
|
|
11258
11656
|
// src/commands/schedule/index.ts
|
|
11259
|
-
var scheduleCommand = new
|
|
11657
|
+
var scheduleCommand = new Command51().name("schedule").description("Manage agent schedules").addCommand(setupCommand).addCommand(listCommand5).addCommand(statusCommand6).addCommand(deleteCommand).addCommand(enableCommand).addCommand(disableCommand);
|
|
11260
11658
|
|
|
11261
11659
|
// src/commands/usage/index.ts
|
|
11262
|
-
import { Command as
|
|
11263
|
-
import
|
|
11660
|
+
import { Command as Command52 } from "commander";
|
|
11661
|
+
import chalk52 from "chalk";
|
|
11264
11662
|
|
|
11265
11663
|
// src/lib/utils/duration-formatter.ts
|
|
11266
11664
|
function formatDuration(ms) {
|
|
@@ -11333,7 +11731,7 @@ function fillMissingDates(daily, startDate, endDate) {
|
|
|
11333
11731
|
result.sort((a, b) => b.date.localeCompare(a.date));
|
|
11334
11732
|
return result;
|
|
11335
11733
|
}
|
|
11336
|
-
var usageCommand = new
|
|
11734
|
+
var usageCommand = new Command52().name("usage").description("View usage statistics").option("--since <date>", "Start date (ISO format or relative: 7d, 30d)").option(
|
|
11337
11735
|
"--until <date>",
|
|
11338
11736
|
"End date (ISO format or relative, defaults to now)"
|
|
11339
11737
|
).action(async (options) => {
|
|
@@ -11347,7 +11745,7 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11347
11745
|
endDate = new Date(untilMs);
|
|
11348
11746
|
} catch {
|
|
11349
11747
|
console.error(
|
|
11350
|
-
|
|
11748
|
+
chalk52.red(
|
|
11351
11749
|
"\u2717 Invalid --until format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
11352
11750
|
)
|
|
11353
11751
|
);
|
|
@@ -11362,7 +11760,7 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11362
11760
|
startDate = new Date(sinceMs);
|
|
11363
11761
|
} catch {
|
|
11364
11762
|
console.error(
|
|
11365
|
-
|
|
11763
|
+
chalk52.red(
|
|
11366
11764
|
"\u2717 Invalid --since format. Use ISO (2026-01-01) or relative (7d, 30d)"
|
|
11367
11765
|
)
|
|
11368
11766
|
);
|
|
@@ -11372,13 +11770,13 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11372
11770
|
startDate = new Date(endDate.getTime() - DEFAULT_RANGE_MS);
|
|
11373
11771
|
}
|
|
11374
11772
|
if (startDate >= endDate) {
|
|
11375
|
-
console.error(
|
|
11773
|
+
console.error(chalk52.red("\u2717 --since must be before --until"));
|
|
11376
11774
|
process.exit(1);
|
|
11377
11775
|
}
|
|
11378
11776
|
const rangeMs = endDate.getTime() - startDate.getTime();
|
|
11379
11777
|
if (rangeMs > MAX_RANGE_MS) {
|
|
11380
11778
|
console.error(
|
|
11381
|
-
|
|
11779
|
+
chalk52.red(
|
|
11382
11780
|
"\u2717 Time range exceeds maximum of 30 days. Use --until to specify an end date"
|
|
11383
11781
|
)
|
|
11384
11782
|
);
|
|
@@ -11395,19 +11793,19 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11395
11793
|
);
|
|
11396
11794
|
console.log();
|
|
11397
11795
|
console.log(
|
|
11398
|
-
|
|
11796
|
+
chalk52.bold(
|
|
11399
11797
|
`Usage Summary (${formatDateRange(usage.period.start, usage.period.end)})`
|
|
11400
11798
|
)
|
|
11401
11799
|
);
|
|
11402
11800
|
console.log();
|
|
11403
|
-
console.log(
|
|
11801
|
+
console.log(chalk52.dim("DATE RUNS RUN TIME"));
|
|
11404
11802
|
for (const day of filledDaily) {
|
|
11405
11803
|
const dateDisplay = formatDateDisplay(day.date).padEnd(10);
|
|
11406
11804
|
const runsDisplay = String(day.run_count).padStart(6);
|
|
11407
11805
|
const timeDisplay = formatDuration(day.run_time_ms);
|
|
11408
11806
|
console.log(`${dateDisplay}${runsDisplay} ${timeDisplay}`);
|
|
11409
11807
|
}
|
|
11410
|
-
console.log(
|
|
11808
|
+
console.log(chalk52.dim("\u2500".repeat(29)));
|
|
11411
11809
|
const totalRunsDisplay = String(usage.summary.total_runs).padStart(6);
|
|
11412
11810
|
const totalTimeDisplay = formatDuration(usage.summary.total_run_time_ms);
|
|
11413
11811
|
console.log(
|
|
@@ -11417,66 +11815,66 @@ var usageCommand = new Command47().name("usage").description("View usage statist
|
|
|
11417
11815
|
} catch (error) {
|
|
11418
11816
|
if (error instanceof Error) {
|
|
11419
11817
|
if (error.message.includes("Not authenticated")) {
|
|
11420
|
-
console.error(
|
|
11421
|
-
console.error(
|
|
11818
|
+
console.error(chalk52.red("\u2717 Not authenticated"));
|
|
11819
|
+
console.error(chalk52.dim(" Run: vm0 auth login"));
|
|
11422
11820
|
} else {
|
|
11423
|
-
console.error(
|
|
11821
|
+
console.error(chalk52.red(`\u2717 ${error.message}`));
|
|
11424
11822
|
}
|
|
11425
11823
|
} else {
|
|
11426
|
-
console.error(
|
|
11824
|
+
console.error(chalk52.red("\u2717 An unexpected error occurred"));
|
|
11427
11825
|
}
|
|
11428
11826
|
process.exit(1);
|
|
11429
11827
|
}
|
|
11430
11828
|
});
|
|
11431
11829
|
|
|
11432
11830
|
// src/commands/secret/index.ts
|
|
11433
|
-
import { Command as
|
|
11831
|
+
import { Command as Command56 } from "commander";
|
|
11434
11832
|
|
|
11435
11833
|
// src/commands/secret/list.ts
|
|
11436
|
-
import { Command as
|
|
11437
|
-
import
|
|
11438
|
-
var listCommand6 = new
|
|
11834
|
+
import { Command as Command53 } from "commander";
|
|
11835
|
+
import chalk53 from "chalk";
|
|
11836
|
+
var listCommand6 = new Command53().name("list").alias("ls").description("List all secrets").action(async () => {
|
|
11439
11837
|
try {
|
|
11440
11838
|
const result = await listSecrets();
|
|
11441
11839
|
if (result.secrets.length === 0) {
|
|
11442
|
-
console.log(
|
|
11840
|
+
console.log(chalk53.dim("No secrets found"));
|
|
11443
11841
|
console.log();
|
|
11444
11842
|
console.log("To add a secret:");
|
|
11445
|
-
console.log(
|
|
11843
|
+
console.log(chalk53.cyan(" vm0 secret set MY_API_KEY <value>"));
|
|
11446
11844
|
return;
|
|
11447
11845
|
}
|
|
11448
|
-
console.log(
|
|
11846
|
+
console.log(chalk53.bold("Secrets:"));
|
|
11449
11847
|
console.log();
|
|
11450
11848
|
for (const secret of result.secrets) {
|
|
11451
|
-
const typeIndicator = secret.type === "model-provider" ?
|
|
11452
|
-
console.log(` ${
|
|
11849
|
+
const typeIndicator = secret.type === "model-provider" ? chalk53.dim(" [model-provider]") : "";
|
|
11850
|
+
console.log(` ${chalk53.cyan(secret.name)}${typeIndicator}`);
|
|
11453
11851
|
if (secret.description) {
|
|
11454
|
-
console.log(` ${
|
|
11852
|
+
console.log(` ${chalk53.dim(secret.description)}`);
|
|
11455
11853
|
}
|
|
11456
11854
|
console.log(
|
|
11457
|
-
` ${
|
|
11855
|
+
` ${chalk53.dim(`Updated: ${new Date(secret.updatedAt).toLocaleString()}`)}`
|
|
11458
11856
|
);
|
|
11459
11857
|
console.log();
|
|
11460
11858
|
}
|
|
11461
|
-
console.log(
|
|
11859
|
+
console.log(chalk53.dim(`Total: ${result.secrets.length} secret(s)`));
|
|
11462
11860
|
} catch (error) {
|
|
11463
11861
|
if (error instanceof Error) {
|
|
11464
11862
|
if (error.message.includes("Not authenticated")) {
|
|
11465
|
-
console.error(
|
|
11863
|
+
console.error(chalk53.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11466
11864
|
} else {
|
|
11467
|
-
console.error(
|
|
11865
|
+
console.error(chalk53.red(`\u2717 ${error.message}`));
|
|
11468
11866
|
}
|
|
11469
11867
|
} else {
|
|
11470
|
-
console.error(
|
|
11868
|
+
console.error(chalk53.red("\u2717 An unexpected error occurred"));
|
|
11471
11869
|
}
|
|
11472
11870
|
process.exit(1);
|
|
11473
11871
|
}
|
|
11474
11872
|
});
|
|
11475
11873
|
|
|
11476
11874
|
// src/commands/secret/set.ts
|
|
11477
|
-
import { Command as
|
|
11478
|
-
import
|
|
11479
|
-
var setCommand2 = new
|
|
11875
|
+
import { Command as Command54 } from "commander";
|
|
11876
|
+
import chalk54 from "chalk";
|
|
11877
|
+
var setCommand2 = new Command54().name("set").description("Create or update a secret").argument("<name>", "Secret name (uppercase, e.g., MY_API_KEY)").argument("<value>", "Secret value").option("-d, --description <description>", "Optional description").action(
|
|
11480
11878
|
async (name, value, options) => {
|
|
11481
11879
|
try {
|
|
11482
11880
|
const secret = await setSecret({
|
|
@@ -11484,29 +11882,29 @@ var setCommand2 = new Command49().name("set").description("Create or update a se
|
|
|
11484
11882
|
value,
|
|
11485
11883
|
description: options.description
|
|
11486
11884
|
});
|
|
11487
|
-
console.log(
|
|
11885
|
+
console.log(chalk54.green(`\u2713 Secret "${secret.name}" saved`));
|
|
11488
11886
|
console.log();
|
|
11489
11887
|
console.log("Use in vm0.yaml:");
|
|
11490
|
-
console.log(
|
|
11491
|
-
console.log(
|
|
11888
|
+
console.log(chalk54.cyan(` environment:`));
|
|
11889
|
+
console.log(chalk54.cyan(` ${name}: \${{ secrets.${name} }}`));
|
|
11492
11890
|
} catch (error) {
|
|
11493
11891
|
if (error instanceof Error) {
|
|
11494
11892
|
if (error.message.includes("Not authenticated")) {
|
|
11495
11893
|
console.error(
|
|
11496
|
-
|
|
11894
|
+
chalk54.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
11497
11895
|
);
|
|
11498
11896
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
11499
|
-
console.error(
|
|
11897
|
+
console.error(chalk54.red(`\u2717 ${error.message}`));
|
|
11500
11898
|
console.log();
|
|
11501
11899
|
console.log("Examples of valid secret names:");
|
|
11502
|
-
console.log(
|
|
11503
|
-
console.log(
|
|
11504
|
-
console.log(
|
|
11900
|
+
console.log(chalk54.dim(" MY_API_KEY"));
|
|
11901
|
+
console.log(chalk54.dim(" GITHUB_TOKEN"));
|
|
11902
|
+
console.log(chalk54.dim(" AWS_ACCESS_KEY_ID"));
|
|
11505
11903
|
} else {
|
|
11506
|
-
console.error(
|
|
11904
|
+
console.error(chalk54.red(`\u2717 ${error.message}`));
|
|
11507
11905
|
}
|
|
11508
11906
|
} else {
|
|
11509
|
-
console.error(
|
|
11907
|
+
console.error(chalk54.red("\u2717 An unexpected error occurred"));
|
|
11510
11908
|
}
|
|
11511
11909
|
process.exit(1);
|
|
11512
11910
|
}
|
|
@@ -11514,20 +11912,20 @@ var setCommand2 = new Command49().name("set").description("Create or update a se
|
|
|
11514
11912
|
);
|
|
11515
11913
|
|
|
11516
11914
|
// src/commands/secret/delete.ts
|
|
11517
|
-
import { Command as
|
|
11518
|
-
import
|
|
11519
|
-
var deleteCommand2 = new
|
|
11915
|
+
import { Command as Command55 } from "commander";
|
|
11916
|
+
import chalk55 from "chalk";
|
|
11917
|
+
var deleteCommand2 = new Command55().name("delete").description("Delete a secret").argument("<name>", "Secret name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
11520
11918
|
try {
|
|
11521
11919
|
try {
|
|
11522
11920
|
await getSecret(name);
|
|
11523
11921
|
} catch {
|
|
11524
|
-
console.error(
|
|
11922
|
+
console.error(chalk55.red(`\u2717 Secret "${name}" not found`));
|
|
11525
11923
|
process.exit(1);
|
|
11526
11924
|
}
|
|
11527
11925
|
if (!options.yes) {
|
|
11528
11926
|
if (!isInteractive()) {
|
|
11529
11927
|
console.error(
|
|
11530
|
-
|
|
11928
|
+
chalk55.red("\u2717 --yes flag is required in non-interactive mode")
|
|
11531
11929
|
);
|
|
11532
11930
|
process.exit(1);
|
|
11533
11931
|
}
|
|
@@ -11536,83 +11934,83 @@ var deleteCommand2 = new Command50().name("delete").description("Delete a secret
|
|
|
11536
11934
|
false
|
|
11537
11935
|
);
|
|
11538
11936
|
if (!confirmed) {
|
|
11539
|
-
console.log(
|
|
11937
|
+
console.log(chalk55.dim("Cancelled"));
|
|
11540
11938
|
return;
|
|
11541
11939
|
}
|
|
11542
11940
|
}
|
|
11543
11941
|
await deleteSecret(name);
|
|
11544
|
-
console.log(
|
|
11942
|
+
console.log(chalk55.green(`\u2713 Secret "${name}" deleted`));
|
|
11545
11943
|
} catch (error) {
|
|
11546
11944
|
if (error instanceof Error) {
|
|
11547
11945
|
if (error.message.includes("Not authenticated")) {
|
|
11548
|
-
console.error(
|
|
11946
|
+
console.error(chalk55.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11549
11947
|
} else {
|
|
11550
|
-
console.error(
|
|
11948
|
+
console.error(chalk55.red(`\u2717 ${error.message}`));
|
|
11551
11949
|
}
|
|
11552
11950
|
} else {
|
|
11553
|
-
console.error(
|
|
11951
|
+
console.error(chalk55.red("\u2717 An unexpected error occurred"));
|
|
11554
11952
|
}
|
|
11555
11953
|
process.exit(1);
|
|
11556
11954
|
}
|
|
11557
11955
|
});
|
|
11558
11956
|
|
|
11559
11957
|
// src/commands/secret/index.ts
|
|
11560
|
-
var secretCommand = new
|
|
11958
|
+
var secretCommand = new Command56().name("secret").description("Manage stored secrets for agent runs").addCommand(listCommand6).addCommand(setCommand2).addCommand(deleteCommand2);
|
|
11561
11959
|
|
|
11562
11960
|
// src/commands/variable/index.ts
|
|
11563
|
-
import { Command as
|
|
11961
|
+
import { Command as Command60 } from "commander";
|
|
11564
11962
|
|
|
11565
11963
|
// src/commands/variable/list.ts
|
|
11566
|
-
import { Command as
|
|
11567
|
-
import
|
|
11964
|
+
import { Command as Command57 } from "commander";
|
|
11965
|
+
import chalk56 from "chalk";
|
|
11568
11966
|
function truncateValue(value, maxLength = 60) {
|
|
11569
11967
|
if (value.length <= maxLength) {
|
|
11570
11968
|
return value;
|
|
11571
11969
|
}
|
|
11572
11970
|
return value.slice(0, maxLength - 15) + "... [truncated]";
|
|
11573
11971
|
}
|
|
11574
|
-
var listCommand7 = new
|
|
11972
|
+
var listCommand7 = new Command57().name("list").alias("ls").description("List all variables").action(async () => {
|
|
11575
11973
|
try {
|
|
11576
11974
|
const result = await listVariables();
|
|
11577
11975
|
if (result.variables.length === 0) {
|
|
11578
|
-
console.log(
|
|
11976
|
+
console.log(chalk56.dim("No variables found"));
|
|
11579
11977
|
console.log();
|
|
11580
11978
|
console.log("To add a variable:");
|
|
11581
|
-
console.log(
|
|
11979
|
+
console.log(chalk56.cyan(" vm0 variable set MY_VAR <value>"));
|
|
11582
11980
|
return;
|
|
11583
11981
|
}
|
|
11584
|
-
console.log(
|
|
11982
|
+
console.log(chalk56.bold("Variables:"));
|
|
11585
11983
|
console.log();
|
|
11586
11984
|
for (const variable of result.variables) {
|
|
11587
11985
|
const displayValue = truncateValue(variable.value);
|
|
11588
|
-
console.log(` ${
|
|
11986
|
+
console.log(` ${chalk56.cyan(variable.name)} = ${displayValue}`);
|
|
11589
11987
|
if (variable.description) {
|
|
11590
|
-
console.log(` ${
|
|
11988
|
+
console.log(` ${chalk56.dim(variable.description)}`);
|
|
11591
11989
|
}
|
|
11592
11990
|
console.log(
|
|
11593
|
-
` ${
|
|
11991
|
+
` ${chalk56.dim(`Updated: ${new Date(variable.updatedAt).toLocaleString()}`)}`
|
|
11594
11992
|
);
|
|
11595
11993
|
console.log();
|
|
11596
11994
|
}
|
|
11597
|
-
console.log(
|
|
11995
|
+
console.log(chalk56.dim(`Total: ${result.variables.length} variable(s)`));
|
|
11598
11996
|
} catch (error) {
|
|
11599
11997
|
if (error instanceof Error) {
|
|
11600
11998
|
if (error.message.includes("Not authenticated")) {
|
|
11601
|
-
console.error(
|
|
11999
|
+
console.error(chalk56.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11602
12000
|
} else {
|
|
11603
|
-
console.error(
|
|
12001
|
+
console.error(chalk56.red(`\u2717 ${error.message}`));
|
|
11604
12002
|
}
|
|
11605
12003
|
} else {
|
|
11606
|
-
console.error(
|
|
12004
|
+
console.error(chalk56.red("\u2717 An unexpected error occurred"));
|
|
11607
12005
|
}
|
|
11608
12006
|
process.exit(1);
|
|
11609
12007
|
}
|
|
11610
12008
|
});
|
|
11611
12009
|
|
|
11612
12010
|
// src/commands/variable/set.ts
|
|
11613
|
-
import { Command as
|
|
11614
|
-
import
|
|
11615
|
-
var setCommand3 = new
|
|
12011
|
+
import { Command as Command58 } from "commander";
|
|
12012
|
+
import chalk57 from "chalk";
|
|
12013
|
+
var setCommand3 = new Command58().name("set").description("Create or update a variable").argument("<name>", "Variable name (uppercase, e.g., MY_VAR)").argument("<value>", "Variable value").option("-d, --description <description>", "Optional description").action(
|
|
11616
12014
|
async (name, value, options) => {
|
|
11617
12015
|
try {
|
|
11618
12016
|
const variable = await setVariable({
|
|
@@ -11620,29 +12018,29 @@ var setCommand3 = new Command53().name("set").description("Create or update a va
|
|
|
11620
12018
|
value,
|
|
11621
12019
|
description: options.description
|
|
11622
12020
|
});
|
|
11623
|
-
console.log(
|
|
12021
|
+
console.log(chalk57.green(`\u2713 Variable "${variable.name}" saved`));
|
|
11624
12022
|
console.log();
|
|
11625
12023
|
console.log("Use in vm0.yaml:");
|
|
11626
|
-
console.log(
|
|
11627
|
-
console.log(
|
|
12024
|
+
console.log(chalk57.cyan(` environment:`));
|
|
12025
|
+
console.log(chalk57.cyan(` ${name}: \${{ vars.${name} }}`));
|
|
11628
12026
|
} catch (error) {
|
|
11629
12027
|
if (error instanceof Error) {
|
|
11630
12028
|
if (error.message.includes("Not authenticated")) {
|
|
11631
12029
|
console.error(
|
|
11632
|
-
|
|
12030
|
+
chalk57.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
11633
12031
|
);
|
|
11634
12032
|
} else if (error.message.includes("must contain only uppercase")) {
|
|
11635
|
-
console.error(
|
|
12033
|
+
console.error(chalk57.red(`\u2717 ${error.message}`));
|
|
11636
12034
|
console.log();
|
|
11637
12035
|
console.log("Examples of valid variable names:");
|
|
11638
|
-
console.log(
|
|
11639
|
-
console.log(
|
|
11640
|
-
console.log(
|
|
12036
|
+
console.log(chalk57.dim(" MY_VAR"));
|
|
12037
|
+
console.log(chalk57.dim(" API_URL"));
|
|
12038
|
+
console.log(chalk57.dim(" DEBUG_MODE"));
|
|
11641
12039
|
} else {
|
|
11642
|
-
console.error(
|
|
12040
|
+
console.error(chalk57.red(`\u2717 ${error.message}`));
|
|
11643
12041
|
}
|
|
11644
12042
|
} else {
|
|
11645
|
-
console.error(
|
|
12043
|
+
console.error(chalk57.red("\u2717 An unexpected error occurred"));
|
|
11646
12044
|
}
|
|
11647
12045
|
process.exit(1);
|
|
11648
12046
|
}
|
|
@@ -11650,15 +12048,15 @@ var setCommand3 = new Command53().name("set").description("Create or update a va
|
|
|
11650
12048
|
);
|
|
11651
12049
|
|
|
11652
12050
|
// src/commands/variable/delete.ts
|
|
11653
|
-
import { Command as
|
|
11654
|
-
import
|
|
11655
|
-
var deleteCommand3 = new
|
|
12051
|
+
import { Command as Command59 } from "commander";
|
|
12052
|
+
import chalk58 from "chalk";
|
|
12053
|
+
var deleteCommand3 = new Command59().name("delete").description("Delete a variable").argument("<name>", "Variable name to delete").option("-y, --yes", "Skip confirmation prompt").action(async (name, options) => {
|
|
11656
12054
|
try {
|
|
11657
12055
|
try {
|
|
11658
12056
|
await getVariable(name);
|
|
11659
12057
|
} catch (error) {
|
|
11660
12058
|
if (error instanceof Error && error.message.toLowerCase().includes("not found")) {
|
|
11661
|
-
console.error(
|
|
12059
|
+
console.error(chalk58.red(`\u2717 Variable "${name}" not found`));
|
|
11662
12060
|
process.exit(1);
|
|
11663
12061
|
}
|
|
11664
12062
|
throw error;
|
|
@@ -11666,7 +12064,7 @@ var deleteCommand3 = new Command54().name("delete").description("Delete a variab
|
|
|
11666
12064
|
if (!options.yes) {
|
|
11667
12065
|
if (!isInteractive()) {
|
|
11668
12066
|
console.error(
|
|
11669
|
-
|
|
12067
|
+
chalk58.red("\u2717 --yes flag is required in non-interactive mode")
|
|
11670
12068
|
);
|
|
11671
12069
|
process.exit(1);
|
|
11672
12070
|
}
|
|
@@ -11675,43 +12073,43 @@ var deleteCommand3 = new Command54().name("delete").description("Delete a variab
|
|
|
11675
12073
|
false
|
|
11676
12074
|
);
|
|
11677
12075
|
if (!confirmed) {
|
|
11678
|
-
console.log(
|
|
12076
|
+
console.log(chalk58.dim("Cancelled"));
|
|
11679
12077
|
return;
|
|
11680
12078
|
}
|
|
11681
12079
|
}
|
|
11682
12080
|
await deleteVariable(name);
|
|
11683
|
-
console.log(
|
|
12081
|
+
console.log(chalk58.green(`\u2713 Variable "${name}" deleted`));
|
|
11684
12082
|
} catch (error) {
|
|
11685
12083
|
if (error instanceof Error) {
|
|
11686
12084
|
if (error.message.includes("Not authenticated")) {
|
|
11687
|
-
console.error(
|
|
12085
|
+
console.error(chalk58.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11688
12086
|
} else {
|
|
11689
|
-
console.error(
|
|
12087
|
+
console.error(chalk58.red(`\u2717 ${error.message}`));
|
|
11690
12088
|
}
|
|
11691
12089
|
} else {
|
|
11692
|
-
console.error(
|
|
12090
|
+
console.error(chalk58.red("\u2717 An unexpected error occurred"));
|
|
11693
12091
|
}
|
|
11694
12092
|
process.exit(1);
|
|
11695
12093
|
}
|
|
11696
12094
|
});
|
|
11697
12095
|
|
|
11698
12096
|
// src/commands/variable/index.ts
|
|
11699
|
-
var variableCommand = new
|
|
12097
|
+
var variableCommand = new Command60().name("variable").description("Manage stored variables for agent runs").addCommand(listCommand7).addCommand(setCommand3).addCommand(deleteCommand3);
|
|
11700
12098
|
|
|
11701
12099
|
// src/commands/model-provider/index.ts
|
|
11702
|
-
import { Command as
|
|
12100
|
+
import { Command as Command65 } from "commander";
|
|
11703
12101
|
|
|
11704
12102
|
// src/commands/model-provider/list.ts
|
|
11705
|
-
import { Command as
|
|
11706
|
-
import
|
|
11707
|
-
var listCommand8 = new
|
|
12103
|
+
import { Command as Command61 } from "commander";
|
|
12104
|
+
import chalk59 from "chalk";
|
|
12105
|
+
var listCommand8 = new Command61().name("list").alias("ls").description("List all model providers").action(async () => {
|
|
11708
12106
|
try {
|
|
11709
12107
|
const result = await listModelProviders();
|
|
11710
12108
|
if (result.modelProviders.length === 0) {
|
|
11711
|
-
console.log(
|
|
12109
|
+
console.log(chalk59.dim("No model providers configured"));
|
|
11712
12110
|
console.log();
|
|
11713
12111
|
console.log("To add a model provider:");
|
|
11714
|
-
console.log(
|
|
12112
|
+
console.log(chalk59.cyan(" vm0 model-provider setup"));
|
|
11715
12113
|
return;
|
|
11716
12114
|
}
|
|
11717
12115
|
const byFramework = result.modelProviders.reduce(
|
|
@@ -11725,16 +12123,16 @@ var listCommand8 = new Command56().name("list").alias("ls").description("List al
|
|
|
11725
12123
|
},
|
|
11726
12124
|
{}
|
|
11727
12125
|
);
|
|
11728
|
-
console.log(
|
|
12126
|
+
console.log(chalk59.bold("Model Providers:"));
|
|
11729
12127
|
console.log();
|
|
11730
12128
|
for (const [framework, providers] of Object.entries(byFramework)) {
|
|
11731
|
-
console.log(` ${
|
|
12129
|
+
console.log(` ${chalk59.cyan(framework)}:`);
|
|
11732
12130
|
for (const provider of providers) {
|
|
11733
|
-
const defaultTag = provider.isDefault ?
|
|
11734
|
-
const modelTag = provider.selectedModel ?
|
|
12131
|
+
const defaultTag = provider.isDefault ? chalk59.green(" (default)") : "";
|
|
12132
|
+
const modelTag = provider.selectedModel ? chalk59.dim(` [${provider.selectedModel}]`) : "";
|
|
11735
12133
|
console.log(` ${provider.type}${defaultTag}${modelTag}`);
|
|
11736
12134
|
console.log(
|
|
11737
|
-
|
|
12135
|
+
chalk59.dim(
|
|
11738
12136
|
` Updated: ${new Date(provider.updatedAt).toLocaleString()}`
|
|
11739
12137
|
)
|
|
11740
12138
|
);
|
|
@@ -11742,33 +12140,33 @@ var listCommand8 = new Command56().name("list").alias("ls").description("List al
|
|
|
11742
12140
|
console.log();
|
|
11743
12141
|
}
|
|
11744
12142
|
console.log(
|
|
11745
|
-
|
|
12143
|
+
chalk59.dim(`Total: ${result.modelProviders.length} provider(s)`)
|
|
11746
12144
|
);
|
|
11747
12145
|
} catch (error) {
|
|
11748
12146
|
if (error instanceof Error) {
|
|
11749
12147
|
if (error.message.includes("Not authenticated")) {
|
|
11750
|
-
console.error(
|
|
12148
|
+
console.error(chalk59.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
11751
12149
|
} else {
|
|
11752
|
-
console.error(
|
|
12150
|
+
console.error(chalk59.red(`\u2717 ${error.message}`));
|
|
11753
12151
|
}
|
|
11754
12152
|
} else {
|
|
11755
|
-
console.error(
|
|
12153
|
+
console.error(chalk59.red("\u2717 An unexpected error occurred"));
|
|
11756
12154
|
}
|
|
11757
12155
|
process.exit(1);
|
|
11758
12156
|
}
|
|
11759
12157
|
});
|
|
11760
12158
|
|
|
11761
12159
|
// src/commands/model-provider/setup.ts
|
|
11762
|
-
import { Command as
|
|
11763
|
-
import
|
|
12160
|
+
import { Command as Command62 } from "commander";
|
|
12161
|
+
import chalk60 from "chalk";
|
|
11764
12162
|
import prompts2 from "prompts";
|
|
11765
12163
|
function validateProviderType(typeStr) {
|
|
11766
12164
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(typeStr)) {
|
|
11767
|
-
console.error(
|
|
12165
|
+
console.error(chalk60.red(`\u2717 Invalid type "${typeStr}"`));
|
|
11768
12166
|
console.log();
|
|
11769
12167
|
console.log("Valid types:");
|
|
11770
12168
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
11771
|
-
console.log(` ${
|
|
12169
|
+
console.log(` ${chalk60.cyan(t)} - ${config.label}`);
|
|
11772
12170
|
}
|
|
11773
12171
|
process.exit(1);
|
|
11774
12172
|
}
|
|
@@ -11780,11 +12178,11 @@ function validateModel(type, modelStr) {
|
|
|
11780
12178
|
return modelStr;
|
|
11781
12179
|
}
|
|
11782
12180
|
if (models && !models.includes(modelStr)) {
|
|
11783
|
-
console.error(
|
|
12181
|
+
console.error(chalk60.red(`\u2717 Invalid model "${modelStr}"`));
|
|
11784
12182
|
console.log();
|
|
11785
12183
|
console.log("Valid models:");
|
|
11786
12184
|
for (const m of models) {
|
|
11787
|
-
console.log(` ${
|
|
12185
|
+
console.log(` ${chalk60.cyan(m)}`);
|
|
11788
12186
|
}
|
|
11789
12187
|
process.exit(1);
|
|
11790
12188
|
}
|
|
@@ -11793,12 +12191,12 @@ function validateModel(type, modelStr) {
|
|
|
11793
12191
|
function validateAuthMethod(type, authMethodStr) {
|
|
11794
12192
|
const authMethods = getAuthMethodsForType(type);
|
|
11795
12193
|
if (!authMethods || !(authMethodStr in authMethods)) {
|
|
11796
|
-
console.error(
|
|
12194
|
+
console.error(chalk60.red(`\u2717 Invalid auth method "${authMethodStr}"`));
|
|
11797
12195
|
console.log();
|
|
11798
12196
|
console.log("Valid auth methods:");
|
|
11799
12197
|
if (authMethods) {
|
|
11800
12198
|
for (const [method, config] of Object.entries(authMethods)) {
|
|
11801
|
-
console.log(` ${
|
|
12199
|
+
console.log(` ${chalk60.cyan(method)} - ${config.label}`);
|
|
11802
12200
|
}
|
|
11803
12201
|
}
|
|
11804
12202
|
process.exit(1);
|
|
@@ -11808,7 +12206,7 @@ function validateAuthMethod(type, authMethodStr) {
|
|
|
11808
12206
|
function parseCredentials(type, authMethod, credentialArgs) {
|
|
11809
12207
|
const credentialsConfig = getCredentialsForAuthMethod(type, authMethod);
|
|
11810
12208
|
if (!credentialsConfig) {
|
|
11811
|
-
console.error(
|
|
12209
|
+
console.error(chalk60.red(`\u2717 Invalid auth method "${authMethod}"`));
|
|
11812
12210
|
process.exit(1);
|
|
11813
12211
|
}
|
|
11814
12212
|
const credentialNames = Object.keys(credentialsConfig);
|
|
@@ -11816,7 +12214,7 @@ function parseCredentials(type, authMethod, credentialArgs) {
|
|
|
11816
12214
|
if (credentialArgs.length === 1 && firstArg && !firstArg.includes("=")) {
|
|
11817
12215
|
if (credentialNames.length !== 1) {
|
|
11818
12216
|
console.error(
|
|
11819
|
-
|
|
12217
|
+
chalk60.red(
|
|
11820
12218
|
"\u2717 Must use KEY=VALUE format for multi-credential auth methods"
|
|
11821
12219
|
)
|
|
11822
12220
|
);
|
|
@@ -11824,13 +12222,13 @@ function parseCredentials(type, authMethod, credentialArgs) {
|
|
|
11824
12222
|
console.log("Required credentials:");
|
|
11825
12223
|
for (const [name, fieldConfig] of Object.entries(credentialsConfig)) {
|
|
11826
12224
|
const requiredNote = fieldConfig.required ? " (required)" : "";
|
|
11827
|
-
console.log(` ${
|
|
12225
|
+
console.log(` ${chalk60.cyan(name)}${requiredNote}`);
|
|
11828
12226
|
}
|
|
11829
12227
|
process.exit(1);
|
|
11830
12228
|
}
|
|
11831
12229
|
const firstCredentialName = credentialNames[0];
|
|
11832
12230
|
if (!firstCredentialName) {
|
|
11833
|
-
console.error(
|
|
12231
|
+
console.error(chalk60.red("\u2717 No credentials defined for this auth method"));
|
|
11834
12232
|
process.exit(1);
|
|
11835
12233
|
}
|
|
11836
12234
|
return { [firstCredentialName]: firstArg };
|
|
@@ -11839,7 +12237,7 @@ function parseCredentials(type, authMethod, credentialArgs) {
|
|
|
11839
12237
|
for (const arg of credentialArgs) {
|
|
11840
12238
|
const eqIndex = arg.indexOf("=");
|
|
11841
12239
|
if (eqIndex === -1) {
|
|
11842
|
-
console.error(
|
|
12240
|
+
console.error(chalk60.red(`\u2717 Invalid credential format "${arg}"`));
|
|
11843
12241
|
console.log();
|
|
11844
12242
|
console.log("Use KEY=VALUE format (e.g., AWS_REGION=us-east-1)");
|
|
11845
12243
|
process.exit(1);
|
|
@@ -11853,17 +12251,17 @@ function parseCredentials(type, authMethod, credentialArgs) {
|
|
|
11853
12251
|
function validateCredentials(type, authMethod, credentials) {
|
|
11854
12252
|
const credentialsConfig = getCredentialsForAuthMethod(type, authMethod);
|
|
11855
12253
|
if (!credentialsConfig) {
|
|
11856
|
-
console.error(
|
|
12254
|
+
console.error(chalk60.red(`\u2717 Invalid auth method "${authMethod}"`));
|
|
11857
12255
|
process.exit(1);
|
|
11858
12256
|
}
|
|
11859
12257
|
for (const [name, fieldConfig] of Object.entries(credentialsConfig)) {
|
|
11860
12258
|
if (fieldConfig.required && !credentials[name]) {
|
|
11861
|
-
console.error(
|
|
12259
|
+
console.error(chalk60.red(`\u2717 Missing required credential: ${name}`));
|
|
11862
12260
|
console.log();
|
|
11863
12261
|
console.log("Required credentials:");
|
|
11864
12262
|
for (const [n, fc] of Object.entries(credentialsConfig)) {
|
|
11865
12263
|
if (fc.required) {
|
|
11866
|
-
console.log(` ${
|
|
12264
|
+
console.log(` ${chalk60.cyan(n)} - ${fc.label}`);
|
|
11867
12265
|
}
|
|
11868
12266
|
}
|
|
11869
12267
|
process.exit(1);
|
|
@@ -11871,12 +12269,12 @@ function validateCredentials(type, authMethod, credentials) {
|
|
|
11871
12269
|
}
|
|
11872
12270
|
for (const name of Object.keys(credentials)) {
|
|
11873
12271
|
if (!(name in credentialsConfig)) {
|
|
11874
|
-
console.error(
|
|
12272
|
+
console.error(chalk60.red(`\u2717 Unknown credential: ${name}`));
|
|
11875
12273
|
console.log();
|
|
11876
12274
|
console.log("Valid credentials:");
|
|
11877
12275
|
for (const [n, fc] of Object.entries(credentialsConfig)) {
|
|
11878
12276
|
const requiredNote = fc.required ? " (required)" : " (optional)";
|
|
11879
|
-
console.log(` ${
|
|
12277
|
+
console.log(` ${chalk60.cyan(n)}${requiredNote}`);
|
|
11880
12278
|
}
|
|
11881
12279
|
process.exit(1);
|
|
11882
12280
|
}
|
|
@@ -11899,7 +12297,7 @@ function handleNonInteractiveMode(options) {
|
|
|
11899
12297
|
const defaultAuthMethod = getDefaultAuthMethod(type);
|
|
11900
12298
|
const authMethods = getAuthMethodsForType(type);
|
|
11901
12299
|
if (!defaultAuthMethod || !authMethods) {
|
|
11902
|
-
console.error(
|
|
12300
|
+
console.error(chalk60.red(`\u2717 Provider "${type}" requires --auth-method`));
|
|
11903
12301
|
process.exit(1);
|
|
11904
12302
|
}
|
|
11905
12303
|
const authMethodNames = Object.keys(authMethods);
|
|
@@ -11907,7 +12305,7 @@ function handleNonInteractiveMode(options) {
|
|
|
11907
12305
|
authMethod = authMethodNames[0];
|
|
11908
12306
|
} else {
|
|
11909
12307
|
console.error(
|
|
11910
|
-
|
|
12308
|
+
chalk60.red(
|
|
11911
12309
|
`\u2717 --auth-method is required for "${type}" (multiple auth methods available)`
|
|
11912
12310
|
)
|
|
11913
12311
|
);
|
|
@@ -11916,13 +12314,13 @@ function handleNonInteractiveMode(options) {
|
|
|
11916
12314
|
for (const [method, config] of Object.entries(authMethods)) {
|
|
11917
12315
|
const defaultNote = method === defaultAuthMethod ? " (default)" : "";
|
|
11918
12316
|
console.log(
|
|
11919
|
-
` ${
|
|
12317
|
+
` ${chalk60.cyan(method)} - ${config.label}${defaultNote}`
|
|
11920
12318
|
);
|
|
11921
12319
|
}
|
|
11922
12320
|
console.log();
|
|
11923
12321
|
console.log("Example:");
|
|
11924
12322
|
console.log(
|
|
11925
|
-
|
|
12323
|
+
chalk60.cyan(
|
|
11926
12324
|
` vm0 model-provider setup --type ${type} --auth-method ${authMethodNames[0]} --credential KEY=VALUE`
|
|
11927
12325
|
)
|
|
11928
12326
|
);
|
|
@@ -11942,7 +12340,7 @@ function handleNonInteractiveMode(options) {
|
|
|
11942
12340
|
const credentialArgs = options.credential;
|
|
11943
12341
|
const firstArg = credentialArgs[0];
|
|
11944
12342
|
if (!firstArg) {
|
|
11945
|
-
console.error(
|
|
12343
|
+
console.error(chalk60.red("\u2717 Credential is required"));
|
|
11946
12344
|
process.exit(1);
|
|
11947
12345
|
}
|
|
11948
12346
|
let credential;
|
|
@@ -11991,7 +12389,7 @@ async function promptForModelSelection(type) {
|
|
|
11991
12389
|
if (selected === "__custom__") {
|
|
11992
12390
|
const placeholder = getCustomModelPlaceholder(type);
|
|
11993
12391
|
if (placeholder) {
|
|
11994
|
-
console.log(
|
|
12392
|
+
console.log(chalk60.dim(`Example: ${placeholder}`));
|
|
11995
12393
|
}
|
|
11996
12394
|
const customResponse = await prompts2(
|
|
11997
12395
|
{
|
|
@@ -12036,13 +12434,13 @@ function isSecretCredential(name) {
|
|
|
12036
12434
|
async function promptForCredentials(type, authMethod) {
|
|
12037
12435
|
const credentialsConfig = getCredentialsForAuthMethod(type, authMethod);
|
|
12038
12436
|
if (!credentialsConfig) {
|
|
12039
|
-
console.error(
|
|
12437
|
+
console.error(chalk60.red(`\u2717 Invalid auth method "${authMethod}"`));
|
|
12040
12438
|
process.exit(1);
|
|
12041
12439
|
}
|
|
12042
12440
|
const credentials = {};
|
|
12043
12441
|
for (const [name, fieldConfig] of Object.entries(credentialsConfig)) {
|
|
12044
12442
|
if (fieldConfig.helpText) {
|
|
12045
|
-
console.log(
|
|
12443
|
+
console.log(chalk60.dim(fieldConfig.helpText));
|
|
12046
12444
|
}
|
|
12047
12445
|
const isSecret = isSecretCredential(name);
|
|
12048
12446
|
const placeholder = "placeholder" in fieldConfig ? fieldConfig.placeholder : "";
|
|
@@ -12077,11 +12475,11 @@ async function promptForCredentials(type, authMethod) {
|
|
|
12077
12475
|
}
|
|
12078
12476
|
async function handleInteractiveMode() {
|
|
12079
12477
|
if (!isInteractive()) {
|
|
12080
|
-
console.error(
|
|
12478
|
+
console.error(chalk60.red("\u2717 Interactive mode requires a TTY"));
|
|
12081
12479
|
console.log();
|
|
12082
12480
|
console.log("Use non-interactive mode:");
|
|
12083
12481
|
console.log(
|
|
12084
|
-
|
|
12482
|
+
chalk60.cyan(
|
|
12085
12483
|
' vm0 model-provider setup --type <type> --credential "<value>"'
|
|
12086
12484
|
)
|
|
12087
12485
|
);
|
|
@@ -12098,7 +12496,7 @@ async function handleInteractiveMode() {
|
|
|
12098
12496
|
title = `${title} \u2713`;
|
|
12099
12497
|
}
|
|
12100
12498
|
if (isExperimental) {
|
|
12101
|
-
title = `${title} ${
|
|
12499
|
+
title = `${title} ${chalk60.dim("(experimental)")}`;
|
|
12102
12500
|
}
|
|
12103
12501
|
return {
|
|
12104
12502
|
title,
|
|
@@ -12131,14 +12529,14 @@ async function handleInteractiveMode() {
|
|
|
12131
12529
|
const provider = await convertModelProviderCredential(type);
|
|
12132
12530
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
12133
12531
|
console.log(
|
|
12134
|
-
|
|
12532
|
+
chalk60.green(
|
|
12135
12533
|
`\u2713 Converted "${checkResult.credentialName}" to model provider${defaultNote}`
|
|
12136
12534
|
)
|
|
12137
12535
|
);
|
|
12138
12536
|
await promptSetAsDefault(type, provider.framework, provider.isDefault);
|
|
12139
12537
|
return null;
|
|
12140
12538
|
}
|
|
12141
|
-
console.log(
|
|
12539
|
+
console.log(chalk60.dim("Aborted"));
|
|
12142
12540
|
process.exit(0);
|
|
12143
12541
|
}
|
|
12144
12542
|
if (checkResult.exists && checkResult.currentType === "model-provider") {
|
|
@@ -12169,7 +12567,7 @@ async function handleInteractiveMode() {
|
|
|
12169
12567
|
}
|
|
12170
12568
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
12171
12569
|
console.log();
|
|
12172
|
-
console.log(
|
|
12570
|
+
console.log(chalk60.dim(config.helpText));
|
|
12173
12571
|
console.log();
|
|
12174
12572
|
if (hasAuthMethods(type)) {
|
|
12175
12573
|
const authMethod = await promptForAuthMethod(type);
|
|
@@ -12200,17 +12598,17 @@ async function handleInteractiveMode() {
|
|
|
12200
12598
|
function handleSetupError2(error) {
|
|
12201
12599
|
if (error instanceof Error) {
|
|
12202
12600
|
if (error.message.includes("already exists")) {
|
|
12203
|
-
console.error(
|
|
12601
|
+
console.error(chalk60.red(`\u2717 ${error.message}`));
|
|
12204
12602
|
console.log();
|
|
12205
12603
|
console.log("To convert the existing credential, run:");
|
|
12206
|
-
console.log(
|
|
12604
|
+
console.log(chalk60.cyan(" vm0 model-provider setup --convert"));
|
|
12207
12605
|
} else if (error.message.includes("Not authenticated")) {
|
|
12208
|
-
console.error(
|
|
12606
|
+
console.error(chalk60.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
12209
12607
|
} else {
|
|
12210
|
-
console.error(
|
|
12608
|
+
console.error(chalk60.red(`\u2717 ${error.message}`));
|
|
12211
12609
|
}
|
|
12212
12610
|
} else {
|
|
12213
|
-
console.error(
|
|
12611
|
+
console.error(chalk60.red("\u2717 An unexpected error occurred"));
|
|
12214
12612
|
}
|
|
12215
12613
|
process.exit(1);
|
|
12216
12614
|
}
|
|
@@ -12227,13 +12625,13 @@ async function promptSetAsDefault(type, framework, isDefault) {
|
|
|
12227
12625
|
);
|
|
12228
12626
|
if (response.setDefault) {
|
|
12229
12627
|
await setModelProviderDefault(type);
|
|
12230
|
-
console.log(
|
|
12628
|
+
console.log(chalk60.green(`\u2713 Default for ${framework} set to "${type}"`));
|
|
12231
12629
|
}
|
|
12232
12630
|
}
|
|
12233
12631
|
function collectCredentials(value, previous) {
|
|
12234
12632
|
return previous.concat([value]);
|
|
12235
12633
|
}
|
|
12236
|
-
var setupCommand2 = new
|
|
12634
|
+
var setupCommand2 = new Command62().name("setup").description("Configure a model provider").option("-t, --type <type>", "Provider type (for non-interactive mode)").option(
|
|
12237
12635
|
"-c, --credential <value>",
|
|
12238
12636
|
"Credential value (can be used multiple times, supports VALUE or KEY=VALUE format)",
|
|
12239
12637
|
collectCredentials,
|
|
@@ -12256,7 +12654,7 @@ var setupCommand2 = new Command57().name("setup").description("Configure a model
|
|
|
12256
12654
|
});
|
|
12257
12655
|
} else if (options.type || credentialArgs.length > 0) {
|
|
12258
12656
|
console.error(
|
|
12259
|
-
|
|
12657
|
+
chalk60.red("\u2717 Both --type and --credential are required")
|
|
12260
12658
|
);
|
|
12261
12659
|
process.exit(1);
|
|
12262
12660
|
} else {
|
|
@@ -12275,11 +12673,11 @@ var setupCommand2 = new Command57().name("setup").description("Configure a model
|
|
|
12275
12673
|
const modelNote2 = provider2.selectedModel ? ` with model: ${provider2.selectedModel}` : "";
|
|
12276
12674
|
if (!hasModelSelection(input.type)) {
|
|
12277
12675
|
console.log(
|
|
12278
|
-
|
|
12676
|
+
chalk60.green(`\u2713 Model provider "${input.type}" unchanged`)
|
|
12279
12677
|
);
|
|
12280
12678
|
} else {
|
|
12281
12679
|
console.log(
|
|
12282
|
-
|
|
12680
|
+
chalk60.green(
|
|
12283
12681
|
`\u2713 Model provider "${input.type}" updated${defaultNote2}${modelNote2}`
|
|
12284
12682
|
)
|
|
12285
12683
|
);
|
|
@@ -12305,7 +12703,7 @@ var setupCommand2 = new Command57().name("setup").description("Configure a model
|
|
|
12305
12703
|
const defaultNote = provider.isDefault ? ` (default for ${provider.framework})` : "";
|
|
12306
12704
|
const modelNote = provider.selectedModel ? ` with model: ${provider.selectedModel}` : "";
|
|
12307
12705
|
console.log(
|
|
12308
|
-
|
|
12706
|
+
chalk60.green(
|
|
12309
12707
|
`\u2713 Model provider "${input.type}" ${action}${defaultNote}${modelNote}`
|
|
12310
12708
|
)
|
|
12311
12709
|
);
|
|
@@ -12323,96 +12721,96 @@ var setupCommand2 = new Command57().name("setup").description("Configure a model
|
|
|
12323
12721
|
);
|
|
12324
12722
|
|
|
12325
12723
|
// src/commands/model-provider/delete.ts
|
|
12326
|
-
import { Command as
|
|
12327
|
-
import
|
|
12328
|
-
var deleteCommand4 = new
|
|
12724
|
+
import { Command as Command63 } from "commander";
|
|
12725
|
+
import chalk61 from "chalk";
|
|
12726
|
+
var deleteCommand4 = new Command63().name("delete").description("Delete a model provider").argument("<type>", "Model provider type to delete").action(async (type) => {
|
|
12329
12727
|
try {
|
|
12330
12728
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
12331
|
-
console.error(
|
|
12729
|
+
console.error(chalk61.red(`\u2717 Invalid type "${type}"`));
|
|
12332
12730
|
console.log();
|
|
12333
12731
|
console.log("Valid types:");
|
|
12334
12732
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
12335
|
-
console.log(` ${
|
|
12733
|
+
console.log(` ${chalk61.cyan(t)} - ${config.label}`);
|
|
12336
12734
|
}
|
|
12337
12735
|
process.exit(1);
|
|
12338
12736
|
}
|
|
12339
12737
|
await deleteModelProvider(type);
|
|
12340
|
-
console.log(
|
|
12738
|
+
console.log(chalk61.green(`\u2713 Model provider "${type}" deleted`));
|
|
12341
12739
|
} catch (error) {
|
|
12342
12740
|
if (error instanceof Error) {
|
|
12343
12741
|
if (error.message.includes("not found")) {
|
|
12344
|
-
console.error(
|
|
12742
|
+
console.error(chalk61.red(`\u2717 Model provider "${type}" not found`));
|
|
12345
12743
|
} else if (error.message.includes("Not authenticated")) {
|
|
12346
|
-
console.error(
|
|
12744
|
+
console.error(chalk61.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
12347
12745
|
} else {
|
|
12348
|
-
console.error(
|
|
12746
|
+
console.error(chalk61.red(`\u2717 ${error.message}`));
|
|
12349
12747
|
}
|
|
12350
12748
|
} else {
|
|
12351
|
-
console.error(
|
|
12749
|
+
console.error(chalk61.red("\u2717 An unexpected error occurred"));
|
|
12352
12750
|
}
|
|
12353
12751
|
process.exit(1);
|
|
12354
12752
|
}
|
|
12355
12753
|
});
|
|
12356
12754
|
|
|
12357
12755
|
// src/commands/model-provider/set-default.ts
|
|
12358
|
-
import { Command as
|
|
12359
|
-
import
|
|
12360
|
-
var setDefaultCommand = new
|
|
12756
|
+
import { Command as Command64 } from "commander";
|
|
12757
|
+
import chalk62 from "chalk";
|
|
12758
|
+
var setDefaultCommand = new Command64().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) => {
|
|
12361
12759
|
try {
|
|
12362
12760
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(type)) {
|
|
12363
|
-
console.error(
|
|
12761
|
+
console.error(chalk62.red(`\u2717 Invalid type "${type}"`));
|
|
12364
12762
|
console.log();
|
|
12365
12763
|
console.log("Valid types:");
|
|
12366
12764
|
for (const [t, config] of Object.entries(MODEL_PROVIDER_TYPES)) {
|
|
12367
|
-
console.log(` ${
|
|
12765
|
+
console.log(` ${chalk62.cyan(t)} - ${config.label}`);
|
|
12368
12766
|
}
|
|
12369
12767
|
process.exit(1);
|
|
12370
12768
|
}
|
|
12371
12769
|
const provider = await setModelProviderDefault(type);
|
|
12372
12770
|
console.log(
|
|
12373
|
-
|
|
12771
|
+
chalk62.green(
|
|
12374
12772
|
`\u2713 Default for ${provider.framework} set to "${provider.type}"`
|
|
12375
12773
|
)
|
|
12376
12774
|
);
|
|
12377
12775
|
} catch (error) {
|
|
12378
12776
|
if (error instanceof Error) {
|
|
12379
12777
|
if (error.message.includes("not found")) {
|
|
12380
|
-
console.error(
|
|
12778
|
+
console.error(chalk62.red(`\u2717 Model provider "${type}" not found`));
|
|
12381
12779
|
} else if (error.message.includes("Not authenticated")) {
|
|
12382
|
-
console.error(
|
|
12780
|
+
console.error(chalk62.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
12383
12781
|
} else {
|
|
12384
|
-
console.error(
|
|
12782
|
+
console.error(chalk62.red(`\u2717 ${error.message}`));
|
|
12385
12783
|
}
|
|
12386
12784
|
} else {
|
|
12387
|
-
console.error(
|
|
12785
|
+
console.error(chalk62.red("\u2717 An unexpected error occurred"));
|
|
12388
12786
|
}
|
|
12389
12787
|
process.exit(1);
|
|
12390
12788
|
}
|
|
12391
12789
|
});
|
|
12392
12790
|
|
|
12393
12791
|
// src/commands/model-provider/index.ts
|
|
12394
|
-
var modelProviderCommand = new
|
|
12792
|
+
var modelProviderCommand = new Command65().name("model-provider").description("Manage model providers for agent runs").addCommand(listCommand8).addCommand(setupCommand2).addCommand(deleteCommand4).addCommand(setDefaultCommand);
|
|
12395
12793
|
|
|
12396
12794
|
// src/commands/onboard/index.ts
|
|
12397
|
-
import { Command as
|
|
12398
|
-
import
|
|
12795
|
+
import { Command as Command66 } from "commander";
|
|
12796
|
+
import chalk66 from "chalk";
|
|
12399
12797
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
12400
12798
|
import { existsSync as existsSync11 } from "fs";
|
|
12401
12799
|
|
|
12402
12800
|
// src/lib/ui/welcome-box.ts
|
|
12403
|
-
import
|
|
12801
|
+
import chalk63 from "chalk";
|
|
12404
12802
|
var gradientColors = [
|
|
12405
|
-
|
|
12803
|
+
chalk63.hex("#FFAB5E"),
|
|
12406
12804
|
// Line 1 - lightest
|
|
12407
|
-
|
|
12805
|
+
chalk63.hex("#FF9642"),
|
|
12408
12806
|
// Line 2
|
|
12409
|
-
|
|
12807
|
+
chalk63.hex("#FF8228"),
|
|
12410
12808
|
// Line 3
|
|
12411
|
-
|
|
12809
|
+
chalk63.hex("#FF6D0A"),
|
|
12412
12810
|
// Line 4
|
|
12413
|
-
|
|
12811
|
+
chalk63.hex("#E85D00"),
|
|
12414
12812
|
// Line 5
|
|
12415
|
-
|
|
12813
|
+
chalk63.hex("#CC4E00")
|
|
12416
12814
|
// Line 6 - darkest
|
|
12417
12815
|
];
|
|
12418
12816
|
var vm0LogoLines = [
|
|
@@ -12434,15 +12832,15 @@ function renderVm0Banner() {
|
|
|
12434
12832
|
function renderOnboardWelcome() {
|
|
12435
12833
|
renderVm0Banner();
|
|
12436
12834
|
console.log(` Build agentic workflows using natural language.`);
|
|
12437
|
-
console.log(` ${
|
|
12835
|
+
console.log(` ${chalk63.dim("Currently in beta, enjoy it free.")}`);
|
|
12438
12836
|
console.log(
|
|
12439
|
-
` ${
|
|
12837
|
+
` ${chalk63.dim("Star us on GitHub: https://github.com/vm0-ai/vm0")}`
|
|
12440
12838
|
);
|
|
12441
12839
|
console.log();
|
|
12442
12840
|
}
|
|
12443
12841
|
|
|
12444
12842
|
// src/lib/ui/step-runner.ts
|
|
12445
|
-
import
|
|
12843
|
+
import chalk64 from "chalk";
|
|
12446
12844
|
function createStepRunner(options = true) {
|
|
12447
12845
|
const opts = typeof options === "boolean" ? { interactive: options } : options;
|
|
12448
12846
|
const interactive = opts.interactive ?? true;
|
|
@@ -12457,25 +12855,25 @@ function createStepRunner(options = true) {
|
|
|
12457
12855
|
}
|
|
12458
12856
|
for (const [i, step] of completedSteps.entries()) {
|
|
12459
12857
|
if (step.failed) {
|
|
12460
|
-
console.log(
|
|
12858
|
+
console.log(chalk64.red(`\u2717 ${step.label}`));
|
|
12461
12859
|
} else {
|
|
12462
|
-
console.log(
|
|
12860
|
+
console.log(chalk64.green(`\u25CF ${step.label}`));
|
|
12463
12861
|
}
|
|
12464
12862
|
const isLastStep = i === completedSteps.length - 1;
|
|
12465
12863
|
if (!isLastStep || !isFinal) {
|
|
12466
|
-
console.log(
|
|
12864
|
+
console.log(chalk64.dim("\u2502"));
|
|
12467
12865
|
}
|
|
12468
12866
|
}
|
|
12469
12867
|
}
|
|
12470
12868
|
async function executeStep(label, fn, isFinal) {
|
|
12471
12869
|
let stepFailed = false;
|
|
12472
|
-
console.log(
|
|
12870
|
+
console.log(chalk64.yellow(`\u25CB ${label}`));
|
|
12473
12871
|
const ctx = {
|
|
12474
12872
|
connector() {
|
|
12475
|
-
console.log(
|
|
12873
|
+
console.log(chalk64.dim("\u2502"));
|
|
12476
12874
|
},
|
|
12477
12875
|
detail(message) {
|
|
12478
|
-
console.log(`${
|
|
12876
|
+
console.log(`${chalk64.dim("\u2502")} ${message}`);
|
|
12479
12877
|
},
|
|
12480
12878
|
async prompt(promptFn) {
|
|
12481
12879
|
return await promptFn();
|
|
@@ -12492,12 +12890,12 @@ function createStepRunner(options = true) {
|
|
|
12492
12890
|
redrawCompletedSteps(isFinal);
|
|
12493
12891
|
} else {
|
|
12494
12892
|
if (stepFailed) {
|
|
12495
|
-
console.log(
|
|
12893
|
+
console.log(chalk64.red(`\u2717 ${label}`));
|
|
12496
12894
|
} else {
|
|
12497
|
-
console.log(
|
|
12895
|
+
console.log(chalk64.green(`\u25CF ${label}`));
|
|
12498
12896
|
}
|
|
12499
12897
|
if (!isFinal) {
|
|
12500
|
-
console.log(
|
|
12898
|
+
console.log(chalk64.dim("\u2502"));
|
|
12501
12899
|
}
|
|
12502
12900
|
}
|
|
12503
12901
|
}
|
|
@@ -12655,7 +13053,7 @@ async function setupModelProvider(type, credential, options) {
|
|
|
12655
13053
|
|
|
12656
13054
|
// src/lib/domain/onboard/claude-setup.ts
|
|
12657
13055
|
import { spawn as spawn3 } from "child_process";
|
|
12658
|
-
import
|
|
13056
|
+
import chalk65 from "chalk";
|
|
12659
13057
|
var MARKETPLACE_NAME = "vm0-skills";
|
|
12660
13058
|
var MARKETPLACE_REPO = "vm0-ai/vm0-skills";
|
|
12661
13059
|
var PLUGIN_ID = "vm0@vm0-skills";
|
|
@@ -12692,12 +13090,12 @@ async function runClaudeCommand(args, cwd) {
|
|
|
12692
13090
|
}
|
|
12693
13091
|
function handlePluginError(error, context) {
|
|
12694
13092
|
const displayContext = context ?? "Claude plugin";
|
|
12695
|
-
console.error(
|
|
13093
|
+
console.error(chalk65.red(`Failed to install ${displayContext}`));
|
|
12696
13094
|
if (error instanceof Error) {
|
|
12697
|
-
console.error(
|
|
13095
|
+
console.error(chalk65.red(error.message));
|
|
12698
13096
|
}
|
|
12699
13097
|
console.error(
|
|
12700
|
-
|
|
13098
|
+
chalk65.dim("Please ensure Claude CLI is installed and accessible.")
|
|
12701
13099
|
);
|
|
12702
13100
|
process.exit(1);
|
|
12703
13101
|
}
|
|
@@ -12740,7 +13138,7 @@ async function updateMarketplace() {
|
|
|
12740
13138
|
]);
|
|
12741
13139
|
if (!result.success) {
|
|
12742
13140
|
console.warn(
|
|
12743
|
-
|
|
13141
|
+
chalk65.yellow(
|
|
12744
13142
|
`Warning: Could not update marketplace: ${result.error ?? "unknown error"}`
|
|
12745
13143
|
)
|
|
12746
13144
|
);
|
|
@@ -12778,7 +13176,7 @@ async function handleAuthentication(ctx) {
|
|
|
12778
13176
|
return;
|
|
12779
13177
|
}
|
|
12780
13178
|
if (!ctx.interactive) {
|
|
12781
|
-
console.error(
|
|
13179
|
+
console.error(chalk66.red("Error: Not authenticated"));
|
|
12782
13180
|
console.error("Run 'vm0 auth login' first or set VM0_TOKEN");
|
|
12783
13181
|
process.exit(1);
|
|
12784
13182
|
}
|
|
@@ -12786,16 +13184,16 @@ async function handleAuthentication(ctx) {
|
|
|
12786
13184
|
onInitiating: () => {
|
|
12787
13185
|
},
|
|
12788
13186
|
onDeviceCodeReady: (url, code, expiresIn) => {
|
|
12789
|
-
step.detail(`Copy code: ${
|
|
12790
|
-
step.detail(`Open: ${
|
|
12791
|
-
step.detail(
|
|
13187
|
+
step.detail(`Copy code: ${chalk66.cyan.bold(code)}`);
|
|
13188
|
+
step.detail(`Open: ${chalk66.cyan(url)}`);
|
|
13189
|
+
step.detail(chalk66.dim(`Expires in ${expiresIn} minutes`));
|
|
12792
13190
|
},
|
|
12793
13191
|
onPolling: () => {
|
|
12794
13192
|
},
|
|
12795
13193
|
onSuccess: () => {
|
|
12796
13194
|
},
|
|
12797
13195
|
onError: (error) => {
|
|
12798
|
-
console.error(
|
|
13196
|
+
console.error(chalk66.red(`
|
|
12799
13197
|
${error.message}`));
|
|
12800
13198
|
process.exit(1);
|
|
12801
13199
|
}
|
|
@@ -12809,7 +13207,7 @@ async function handleModelProvider(ctx) {
|
|
|
12809
13207
|
return;
|
|
12810
13208
|
}
|
|
12811
13209
|
if (!ctx.interactive) {
|
|
12812
|
-
console.error(
|
|
13210
|
+
console.error(chalk66.red("Error: No model provider configured"));
|
|
12813
13211
|
console.error("Run 'vm0 model-provider setup' first");
|
|
12814
13212
|
process.exit(1);
|
|
12815
13213
|
}
|
|
@@ -12830,7 +13228,7 @@ async function handleModelProvider(ctx) {
|
|
|
12830
13228
|
const selectedChoice = choices.find((c23) => c23.type === providerType);
|
|
12831
13229
|
if (selectedChoice?.helpText) {
|
|
12832
13230
|
for (const line of selectedChoice.helpText.split("\n")) {
|
|
12833
|
-
step.detail(
|
|
13231
|
+
step.detail(chalk66.dim(line));
|
|
12834
13232
|
}
|
|
12835
13233
|
}
|
|
12836
13234
|
const credential = await step.prompt(
|
|
@@ -12839,7 +13237,7 @@ async function handleModelProvider(ctx) {
|
|
|
12839
13237
|
)
|
|
12840
13238
|
);
|
|
12841
13239
|
if (!credential) {
|
|
12842
|
-
console.log(
|
|
13240
|
+
console.log(chalk66.dim("Cancelled"));
|
|
12843
13241
|
process.exit(0);
|
|
12844
13242
|
}
|
|
12845
13243
|
let selectedModel;
|
|
@@ -12858,7 +13256,7 @@ async function handleModelProvider(ctx) {
|
|
|
12858
13256
|
() => promptSelect("Select model:", modelChoices)
|
|
12859
13257
|
);
|
|
12860
13258
|
if (modelSelection === void 0) {
|
|
12861
|
-
console.log(
|
|
13259
|
+
console.log(chalk66.dim("Cancelled"));
|
|
12862
13260
|
process.exit(0);
|
|
12863
13261
|
}
|
|
12864
13262
|
selectedModel = modelSelection === "" ? void 0 : modelSelection;
|
|
@@ -12868,7 +13266,7 @@ async function handleModelProvider(ctx) {
|
|
|
12868
13266
|
});
|
|
12869
13267
|
const modelNote = result.provider.selectedModel ? ` with model: ${result.provider.selectedModel}` : "";
|
|
12870
13268
|
step.detail(
|
|
12871
|
-
|
|
13269
|
+
chalk66.green(
|
|
12872
13270
|
`${providerType} ${result.created ? "created" : "updated"}${result.isDefault ? ` (default for ${result.framework})` : ""}${modelNote}`
|
|
12873
13271
|
)
|
|
12874
13272
|
);
|
|
@@ -12899,7 +13297,7 @@ async function handleAgentCreation(ctx) {
|
|
|
12899
13297
|
agentName = inputName;
|
|
12900
13298
|
if (existsSync11(agentName)) {
|
|
12901
13299
|
step.detail(
|
|
12902
|
-
|
|
13300
|
+
chalk66.yellow(`${agentName}/ already exists, choose another name`)
|
|
12903
13301
|
);
|
|
12904
13302
|
} else {
|
|
12905
13303
|
folderExists = false;
|
|
@@ -12908,22 +13306,22 @@ async function handleAgentCreation(ctx) {
|
|
|
12908
13306
|
} else {
|
|
12909
13307
|
if (!validateAgentName(agentName)) {
|
|
12910
13308
|
console.error(
|
|
12911
|
-
|
|
13309
|
+
chalk66.red(
|
|
12912
13310
|
"Invalid agent name: must be 3-64 chars, alphanumeric + hyphens"
|
|
12913
13311
|
)
|
|
12914
13312
|
);
|
|
12915
13313
|
process.exit(1);
|
|
12916
13314
|
}
|
|
12917
13315
|
if (existsSync11(agentName)) {
|
|
12918
|
-
console.error(
|
|
13316
|
+
console.error(chalk66.red(`${agentName}/ already exists`));
|
|
12919
13317
|
console.log();
|
|
12920
13318
|
console.log("Remove it first or choose a different name:");
|
|
12921
|
-
console.log(
|
|
13319
|
+
console.log(chalk66.cyan(` rm -rf ${agentName}`));
|
|
12922
13320
|
process.exit(1);
|
|
12923
13321
|
}
|
|
12924
13322
|
}
|
|
12925
13323
|
await mkdir8(agentName, { recursive: true });
|
|
12926
|
-
step.detail(
|
|
13324
|
+
step.detail(chalk66.green(`Created ${agentName}/`));
|
|
12927
13325
|
});
|
|
12928
13326
|
return agentName;
|
|
12929
13327
|
}
|
|
@@ -12939,7 +13337,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
12939
13337
|
shouldInstall = confirmed ?? true;
|
|
12940
13338
|
}
|
|
12941
13339
|
if (!shouldInstall) {
|
|
12942
|
-
step.detail(
|
|
13340
|
+
step.detail(chalk66.dim("Skipped"));
|
|
12943
13341
|
return;
|
|
12944
13342
|
}
|
|
12945
13343
|
const scope = "project";
|
|
@@ -12947,7 +13345,7 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
12947
13345
|
const agentDir = `${process.cwd()}/${agentName}`;
|
|
12948
13346
|
const result = await installVm0Plugin(scope, agentDir);
|
|
12949
13347
|
step.detail(
|
|
12950
|
-
|
|
13348
|
+
chalk66.green(`Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
12951
13349
|
);
|
|
12952
13350
|
pluginInstalled = true;
|
|
12953
13351
|
} catch (error) {
|
|
@@ -12958,18 +13356,18 @@ async function handlePluginInstallation(ctx, agentName) {
|
|
|
12958
13356
|
}
|
|
12959
13357
|
function printNextSteps(agentName, pluginInstalled) {
|
|
12960
13358
|
console.log();
|
|
12961
|
-
console.log(
|
|
13359
|
+
console.log(chalk66.bold("Next step:"));
|
|
12962
13360
|
console.log();
|
|
12963
13361
|
if (pluginInstalled) {
|
|
12964
13362
|
console.log(
|
|
12965
|
-
` ${
|
|
13363
|
+
` ${chalk66.cyan(`cd ${agentName} && claude "/${PRIMARY_SKILL_NAME} let's build an agent"`)}`
|
|
12966
13364
|
);
|
|
12967
13365
|
} else {
|
|
12968
|
-
console.log(` ${
|
|
13366
|
+
console.log(` ${chalk66.cyan(`cd ${agentName} && vm0 init`)}`);
|
|
12969
13367
|
}
|
|
12970
13368
|
console.log();
|
|
12971
13369
|
}
|
|
12972
|
-
var onboardCommand = new
|
|
13370
|
+
var onboardCommand = new Command66().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) => {
|
|
12973
13371
|
const interactive = isInteractive();
|
|
12974
13372
|
if (interactive) {
|
|
12975
13373
|
process.stdout.write("\x1B[2J\x1B[H");
|
|
@@ -12992,15 +13390,15 @@ var onboardCommand = new Command61().name("onboard").description("Guided setup f
|
|
|
12992
13390
|
});
|
|
12993
13391
|
|
|
12994
13392
|
// src/commands/setup-claude/index.ts
|
|
12995
|
-
import { Command as
|
|
12996
|
-
import
|
|
12997
|
-
var setupClaudeCommand = new
|
|
12998
|
-
console.log(
|
|
13393
|
+
import { Command as Command67 } from "commander";
|
|
13394
|
+
import chalk67 from "chalk";
|
|
13395
|
+
var setupClaudeCommand = new Command67().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) => {
|
|
13396
|
+
console.log(chalk67.dim("Installing VM0 Claude Plugin..."));
|
|
12999
13397
|
const scope = options.scope === "user" ? "user" : "project";
|
|
13000
13398
|
try {
|
|
13001
13399
|
const result = await installVm0Plugin(scope, options.agentDir);
|
|
13002
13400
|
console.log(
|
|
13003
|
-
|
|
13401
|
+
chalk67.green(`\u2713 Installed ${result.pluginId} (scope: ${result.scope})`)
|
|
13004
13402
|
);
|
|
13005
13403
|
} catch (error) {
|
|
13006
13404
|
handlePluginError(error);
|
|
@@ -13009,15 +13407,15 @@ var setupClaudeCommand = new Command62().name("setup-claude").description("Insta
|
|
|
13009
13407
|
console.log("Next step:");
|
|
13010
13408
|
const cdPrefix = options.agentDir ? `cd ${options.agentDir} && ` : "";
|
|
13011
13409
|
console.log(
|
|
13012
|
-
|
|
13410
|
+
chalk67.cyan(
|
|
13013
13411
|
` ${cdPrefix}claude "/${PRIMARY_SKILL_NAME} let's build a workflow"`
|
|
13014
13412
|
)
|
|
13015
13413
|
);
|
|
13016
13414
|
});
|
|
13017
13415
|
|
|
13018
13416
|
// src/index.ts
|
|
13019
|
-
var program = new
|
|
13020
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
13417
|
+
var program = new Command68();
|
|
13418
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.20.0");
|
|
13021
13419
|
program.addCommand(authCommand);
|
|
13022
13420
|
program.addCommand(infoCommand);
|
|
13023
13421
|
program.addCommand(composeCommand);
|