@vm0/cli 9.21.0 → 9.22.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 +238 -122
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -3,13 +3,7 @@
|
|
|
3
3
|
// src/instrument.ts
|
|
4
4
|
import * as Sentry from "@sentry/node";
|
|
5
5
|
import * as os from "os";
|
|
6
|
-
var
|
|
7
|
-
var IS_CI = Boolean(process.env.CI || process.env.GITHUB_ACTIONS);
|
|
8
|
-
var IS_DEV = process.env.NODE_ENV === "development";
|
|
9
|
-
var PRODUCTION_API_URL = "https://www.vm0.ai";
|
|
10
|
-
var API_URL = process.env.VM0_API_URL ?? "";
|
|
11
|
-
var IS_PRODUCTION_API = API_URL === "" || API_URL === PRODUCTION_API_URL;
|
|
12
|
-
var DSN = "https://268d9b4cd051531805af76a5b3934dca@o4510583739777024.ingest.us.sentry.io/4510832047947776";
|
|
6
|
+
var DSN = process.env.SENTRY_DSN ?? "https://268d9b4cd051531805af76a5b3934dca@o4510583739777024.ingest.us.sentry.io/4510832047947776";
|
|
13
7
|
var OPERATIONAL_ERROR_PATTERNS = [
|
|
14
8
|
// Authentication errors (user needs to login)
|
|
15
9
|
/not authenticated/i,
|
|
@@ -46,7 +40,7 @@ function isOperationalError(error) {
|
|
|
46
40
|
const message = error.message;
|
|
47
41
|
return OPERATIONAL_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
48
42
|
}
|
|
49
|
-
if (
|
|
43
|
+
if (DSN) {
|
|
50
44
|
Sentry.init({
|
|
51
45
|
dsn: DSN,
|
|
52
46
|
sendDefaultPii: false,
|
|
@@ -67,7 +61,7 @@ if (!TELEMETRY_DISABLED && !IS_CI && !IS_DEV && IS_PRODUCTION_API) {
|
|
|
67
61
|
}
|
|
68
62
|
});
|
|
69
63
|
Sentry.setContext("cli", {
|
|
70
|
-
version: "9.
|
|
64
|
+
version: "9.22.0",
|
|
71
65
|
command: process.argv.slice(2).join(" ")
|
|
72
66
|
});
|
|
73
67
|
Sentry.setContext("runtime", {
|
|
@@ -2323,7 +2317,7 @@ var MODEL_PROVIDER_TYPES = {
|
|
|
2323
2317
|
"aws-bedrock": {
|
|
2324
2318
|
framework: "claude-code",
|
|
2325
2319
|
label: "AWS Bedrock",
|
|
2326
|
-
helpText: "Run Claude on AWS Bedrock.\nSetup guide: https://
|
|
2320
|
+
helpText: "Run Claude on AWS Bedrock.\nSetup guide: https://code.claude.com/docs/en/amazon-bedrock",
|
|
2327
2321
|
authMethods: {
|
|
2328
2322
|
"api-key": {
|
|
2329
2323
|
label: "Bedrock API Key",
|
|
@@ -5362,9 +5356,15 @@ function getSecretsFromComposeContent(content) {
|
|
|
5362
5356
|
const grouped = groupVariablesBySource(refs);
|
|
5363
5357
|
return new Set(grouped.secrets.map((r) => r.name));
|
|
5364
5358
|
}
|
|
5365
|
-
async function loadAndValidateConfig(configFile) {
|
|
5359
|
+
async function loadAndValidateConfig(configFile, porcelainMode) {
|
|
5366
5360
|
if (!existsSync4(configFile)) {
|
|
5367
|
-
|
|
5361
|
+
if (porcelainMode) {
|
|
5362
|
+
console.log(
|
|
5363
|
+
JSON.stringify({ error: `Config file not found: ${configFile}` })
|
|
5364
|
+
);
|
|
5365
|
+
} else {
|
|
5366
|
+
console.error(chalk4.red(`\u2717 Config file not found: ${configFile}`));
|
|
5367
|
+
}
|
|
5368
5368
|
process.exit(1);
|
|
5369
5369
|
}
|
|
5370
5370
|
const content = await readFile4(configFile, "utf8");
|
|
@@ -5372,15 +5372,22 @@ async function loadAndValidateConfig(configFile) {
|
|
|
5372
5372
|
try {
|
|
5373
5373
|
config = parseYaml2(content);
|
|
5374
5374
|
} catch (error) {
|
|
5375
|
-
|
|
5376
|
-
if (
|
|
5377
|
-
console.
|
|
5375
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
5376
|
+
if (porcelainMode) {
|
|
5377
|
+
console.log(JSON.stringify({ error: `Invalid YAML format: ${message}` }));
|
|
5378
|
+
} else {
|
|
5379
|
+
console.error(chalk4.red("\u2717 Invalid YAML format"));
|
|
5380
|
+
console.error(chalk4.dim(` ${message}`));
|
|
5378
5381
|
}
|
|
5379
5382
|
process.exit(1);
|
|
5380
5383
|
}
|
|
5381
5384
|
const validation = validateAgentCompose(config);
|
|
5382
5385
|
if (!validation.valid) {
|
|
5383
|
-
|
|
5386
|
+
if (porcelainMode) {
|
|
5387
|
+
console.log(JSON.stringify({ error: validation.error }));
|
|
5388
|
+
} else {
|
|
5389
|
+
console.error(chalk4.red(`\u2717 ${validation.error}`));
|
|
5390
|
+
}
|
|
5384
5391
|
process.exit(1);
|
|
5385
5392
|
}
|
|
5386
5393
|
const cfg = config;
|
|
@@ -5416,33 +5423,43 @@ function checkLegacyImageFormat(config) {
|
|
|
5416
5423
|
}
|
|
5417
5424
|
}
|
|
5418
5425
|
}
|
|
5419
|
-
async function uploadAssets(agentName, agent, basePath) {
|
|
5426
|
+
async function uploadAssets(agentName, agent, basePath, porcelainMode) {
|
|
5420
5427
|
if (agent.instructions) {
|
|
5421
|
-
|
|
5428
|
+
if (!porcelainMode) {
|
|
5429
|
+
console.log(`Uploading instructions: ${agent.instructions}`);
|
|
5430
|
+
}
|
|
5422
5431
|
const result = await uploadInstructions(
|
|
5423
5432
|
agentName,
|
|
5424
5433
|
agent.instructions,
|
|
5425
5434
|
basePath,
|
|
5426
5435
|
agent.framework
|
|
5427
5436
|
);
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5437
|
+
if (!porcelainMode) {
|
|
5438
|
+
console.log(
|
|
5439
|
+
chalk4.green(
|
|
5440
|
+
`\u2713 Instructions ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
5441
|
+
)
|
|
5442
|
+
);
|
|
5443
|
+
}
|
|
5433
5444
|
}
|
|
5434
5445
|
const skillResults = [];
|
|
5435
5446
|
if (agent.skills && Array.isArray(agent.skills)) {
|
|
5436
|
-
|
|
5447
|
+
if (!porcelainMode) {
|
|
5448
|
+
console.log(`Uploading ${agent.skills.length} skill(s)...`);
|
|
5449
|
+
}
|
|
5437
5450
|
for (const skillUrl of agent.skills) {
|
|
5438
|
-
|
|
5451
|
+
if (!porcelainMode) {
|
|
5452
|
+
console.log(chalk4.dim(` Downloading: ${skillUrl}`));
|
|
5453
|
+
}
|
|
5439
5454
|
const result = await uploadSkill(skillUrl);
|
|
5440
5455
|
skillResults.push(result);
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5456
|
+
if (!porcelainMode) {
|
|
5457
|
+
console.log(
|
|
5458
|
+
chalk4.green(
|
|
5459
|
+
` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.skillName} (${result.versionId.slice(0, 8)})`
|
|
5460
|
+
)
|
|
5461
|
+
);
|
|
5462
|
+
}
|
|
5446
5463
|
}
|
|
5447
5464
|
}
|
|
5448
5465
|
return skillResults;
|
|
@@ -5488,36 +5505,48 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
5488
5505
|
if (newSecrets.length === 0 && newVars.length === 0) {
|
|
5489
5506
|
return true;
|
|
5490
5507
|
}
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5499
|
-
const
|
|
5500
|
-
|
|
5501
|
-
|
|
5508
|
+
if (!options.porcelain) {
|
|
5509
|
+
console.log();
|
|
5510
|
+
console.log(
|
|
5511
|
+
chalk4.bold("Skills require the following environment variables:")
|
|
5512
|
+
);
|
|
5513
|
+
console.log();
|
|
5514
|
+
if (newSecrets.length > 0) {
|
|
5515
|
+
console.log(chalk4.cyan(" Secrets:"));
|
|
5516
|
+
for (const [name, skills] of newSecrets) {
|
|
5517
|
+
const isNew = trulyNewSecrets.includes(name);
|
|
5518
|
+
const newMarker = isNew ? chalk4.yellow(" (new)") : "";
|
|
5519
|
+
console.log(
|
|
5520
|
+
` ${name.padEnd(24)}${newMarker} <- ${skills.join(", ")}`
|
|
5521
|
+
);
|
|
5522
|
+
}
|
|
5502
5523
|
}
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5524
|
+
if (newVars.length > 0) {
|
|
5525
|
+
console.log(chalk4.cyan(" Vars:"));
|
|
5526
|
+
for (const [name, skills] of newVars) {
|
|
5527
|
+
console.log(` ${name.padEnd(24)} <- ${skills.join(", ")}`);
|
|
5528
|
+
}
|
|
5508
5529
|
}
|
|
5530
|
+
console.log();
|
|
5509
5531
|
}
|
|
5510
|
-
console.log();
|
|
5511
5532
|
if (trulyNewSecrets.length > 0 && !options.yes) {
|
|
5512
5533
|
if (!isInteractive()) {
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5534
|
+
if (options.porcelain) {
|
|
5535
|
+
console.log(
|
|
5536
|
+
JSON.stringify({
|
|
5537
|
+
error: `New secrets detected: ${trulyNewSecrets.join(", ")}. Use --yes flag to approve.`
|
|
5538
|
+
})
|
|
5539
|
+
);
|
|
5540
|
+
} else {
|
|
5541
|
+
console.error(
|
|
5542
|
+
chalk4.red(`\u2717 New secrets detected: ${trulyNewSecrets.join(", ")}`)
|
|
5543
|
+
);
|
|
5544
|
+
console.error(
|
|
5545
|
+
chalk4.dim(
|
|
5546
|
+
" Use --yes flag to approve new secrets in non-interactive mode."
|
|
5547
|
+
)
|
|
5548
|
+
);
|
|
5549
|
+
}
|
|
5521
5550
|
process.exit(1);
|
|
5522
5551
|
}
|
|
5523
5552
|
const confirmed = await promptConfirm(
|
|
@@ -5525,7 +5554,9 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
5525
5554
|
true
|
|
5526
5555
|
);
|
|
5527
5556
|
if (!confirmed) {
|
|
5528
|
-
|
|
5557
|
+
if (!options.porcelain) {
|
|
5558
|
+
console.log(chalk4.yellow("Compose cancelled"));
|
|
5559
|
+
}
|
|
5529
5560
|
return false;
|
|
5530
5561
|
}
|
|
5531
5562
|
}
|
|
@@ -5553,57 +5584,94 @@ async function finalizeCompose(config, agent, variables, options) {
|
|
|
5553
5584
|
process.exit(0);
|
|
5554
5585
|
}
|
|
5555
5586
|
mergeSkillVariables(agent, variables);
|
|
5556
|
-
|
|
5587
|
+
if (!options.porcelain) {
|
|
5588
|
+
console.log("Uploading compose...");
|
|
5589
|
+
}
|
|
5557
5590
|
const response = await createOrUpdateCompose({ content: config });
|
|
5558
5591
|
const scopeResponse = await getScope();
|
|
5559
5592
|
const shortVersionId = response.versionId.slice(0, 8);
|
|
5560
5593
|
const displayName = `${scopeResponse.slug}/${response.name}`;
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5594
|
+
const result = {
|
|
5595
|
+
composeId: response.composeId,
|
|
5596
|
+
composeName: response.name,
|
|
5597
|
+
versionId: response.versionId,
|
|
5598
|
+
action: response.action,
|
|
5599
|
+
displayName
|
|
5600
|
+
};
|
|
5601
|
+
if (!options.porcelain) {
|
|
5602
|
+
if (response.action === "created") {
|
|
5603
|
+
console.log(chalk4.green(`\u2713 Compose created: ${displayName}`));
|
|
5604
|
+
} else {
|
|
5605
|
+
console.log(chalk4.green(`\u2713 Compose version exists: ${displayName}`));
|
|
5606
|
+
}
|
|
5607
|
+
console.log(chalk4.dim(` Version: ${shortVersionId}`));
|
|
5608
|
+
console.log();
|
|
5609
|
+
console.log(" Run your agent:");
|
|
5610
|
+
console.log(
|
|
5611
|
+
chalk4.cyan(
|
|
5612
|
+
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
5613
|
+
)
|
|
5614
|
+
);
|
|
5565
5615
|
}
|
|
5566
|
-
console.log(chalk4.dim(` Version: ${shortVersionId}`));
|
|
5567
|
-
console.log();
|
|
5568
|
-
console.log(" Run your agent:");
|
|
5569
|
-
console.log(
|
|
5570
|
-
chalk4.cyan(
|
|
5571
|
-
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
5572
|
-
)
|
|
5573
|
-
);
|
|
5574
5616
|
if (options.autoUpdate !== false) {
|
|
5575
|
-
await silentUpgradeAfterCommand("9.
|
|
5617
|
+
await silentUpgradeAfterCommand("9.22.0");
|
|
5576
5618
|
}
|
|
5619
|
+
return result;
|
|
5577
5620
|
}
|
|
5578
5621
|
async function handleGitHubCompose(url, options) {
|
|
5579
|
-
|
|
5622
|
+
if (!options.porcelain) {
|
|
5623
|
+
console.log(`Downloading from GitHub: ${url}`);
|
|
5624
|
+
}
|
|
5580
5625
|
const { dir: downloadedDir, tempRoot } = await downloadGitHubDirectory(url);
|
|
5581
5626
|
const configFile = join6(downloadedDir, "vm0.yaml");
|
|
5582
5627
|
try {
|
|
5583
5628
|
if (!existsSync4(configFile)) {
|
|
5584
|
-
|
|
5585
|
-
|
|
5629
|
+
if (options.porcelain) {
|
|
5630
|
+
console.log(
|
|
5631
|
+
JSON.stringify({
|
|
5632
|
+
error: "vm0.yaml not found in the GitHub directory"
|
|
5633
|
+
})
|
|
5634
|
+
);
|
|
5635
|
+
} else {
|
|
5636
|
+
console.error(
|
|
5637
|
+
chalk4.red(`\u2717 vm0.yaml not found in the GitHub directory`)
|
|
5638
|
+
);
|
|
5639
|
+
console.error(chalk4.dim(` URL: ${url}`));
|
|
5640
|
+
}
|
|
5586
5641
|
process.exit(1);
|
|
5587
5642
|
}
|
|
5588
|
-
const { config, agentName, agent, basePath } = await loadAndValidateConfig(
|
|
5643
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(
|
|
5644
|
+
configFile,
|
|
5645
|
+
options.porcelain
|
|
5646
|
+
);
|
|
5589
5647
|
const existingCompose = await getComposeByName(agentName);
|
|
5590
5648
|
if (existingCompose) {
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5649
|
+
if (!options.porcelain) {
|
|
5650
|
+
console.log();
|
|
5651
|
+
console.log(
|
|
5652
|
+
chalk4.yellow(`\u26A0 An agent named "${agentName}" already exists.`)
|
|
5653
|
+
);
|
|
5654
|
+
}
|
|
5595
5655
|
if (!isInteractive()) {
|
|
5596
5656
|
if (!options.yes) {
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5657
|
+
if (options.porcelain) {
|
|
5658
|
+
console.log(
|
|
5659
|
+
JSON.stringify({
|
|
5660
|
+
error: "Cannot overwrite existing agent in non-interactive mode"
|
|
5661
|
+
})
|
|
5662
|
+
);
|
|
5663
|
+
} else {
|
|
5664
|
+
console.error(
|
|
5665
|
+
chalk4.red(
|
|
5666
|
+
`\u2717 Cannot overwrite existing agent in non-interactive mode`
|
|
5667
|
+
)
|
|
5668
|
+
);
|
|
5669
|
+
console.error(
|
|
5670
|
+
chalk4.dim(
|
|
5671
|
+
` Use --yes flag to confirm overwriting the existing agent.`
|
|
5672
|
+
)
|
|
5673
|
+
);
|
|
5674
|
+
}
|
|
5607
5675
|
process.exit(1);
|
|
5608
5676
|
}
|
|
5609
5677
|
} else {
|
|
@@ -5612,31 +5680,48 @@ async function handleGitHubCompose(url, options) {
|
|
|
5612
5680
|
false
|
|
5613
5681
|
);
|
|
5614
5682
|
if (!confirmed) {
|
|
5615
|
-
|
|
5683
|
+
if (!options.porcelain) {
|
|
5684
|
+
console.log(chalk4.yellow("Compose cancelled."));
|
|
5685
|
+
}
|
|
5616
5686
|
process.exit(0);
|
|
5617
5687
|
}
|
|
5618
5688
|
}
|
|
5619
5689
|
}
|
|
5620
5690
|
if (hasVolumes(config)) {
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5691
|
+
if (options.porcelain) {
|
|
5692
|
+
console.log(
|
|
5693
|
+
JSON.stringify({
|
|
5694
|
+
error: "Volumes are not supported for GitHub URL compose"
|
|
5695
|
+
})
|
|
5696
|
+
);
|
|
5697
|
+
} else {
|
|
5698
|
+
console.error(
|
|
5699
|
+
chalk4.red(`\u2717 Volumes are not supported for GitHub URL compose`)
|
|
5700
|
+
);
|
|
5701
|
+
console.error(
|
|
5702
|
+
chalk4.dim(
|
|
5703
|
+
` Clone the repository locally and run: vm0 compose ./path/to/vm0.yaml`
|
|
5704
|
+
)
|
|
5705
|
+
);
|
|
5706
|
+
}
|
|
5629
5707
|
process.exit(1);
|
|
5630
5708
|
}
|
|
5631
|
-
|
|
5632
|
-
|
|
5709
|
+
if (!options.porcelain) {
|
|
5710
|
+
checkLegacyImageFormat(config);
|
|
5711
|
+
}
|
|
5712
|
+
const skillResults = await uploadAssets(
|
|
5713
|
+
agentName,
|
|
5714
|
+
agent,
|
|
5715
|
+
basePath,
|
|
5716
|
+
options.porcelain
|
|
5717
|
+
);
|
|
5633
5718
|
const environment = agent.environment || {};
|
|
5634
5719
|
const variables = await collectSkillVariables(
|
|
5635
5720
|
skillResults,
|
|
5636
5721
|
environment,
|
|
5637
5722
|
agentName
|
|
5638
5723
|
);
|
|
5639
|
-
await finalizeCompose(config, agent, variables, options);
|
|
5724
|
+
return await finalizeCompose(config, agent, variables, options);
|
|
5640
5725
|
} finally {
|
|
5641
5726
|
await rm3(tempRoot, { recursive: true, force: true });
|
|
5642
5727
|
}
|
|
@@ -5647,42 +5732,73 @@ var composeCommand = new Command7().name("compose").description("Create or updat
|
|
|
5647
5732
|
).option("-y, --yes", "Skip confirmation prompts for skill requirements").option(
|
|
5648
5733
|
"--experimental-shared-compose",
|
|
5649
5734
|
"Enable GitHub URL compose (experimental)"
|
|
5735
|
+
).option(
|
|
5736
|
+
"--porcelain",
|
|
5737
|
+
"Output stable JSON for scripts (suppresses interactive output)"
|
|
5650
5738
|
).addOption(new Option("--no-auto-update").hideHelp()).action(
|
|
5651
5739
|
async (configFile, options) => {
|
|
5652
5740
|
const resolvedConfigFile = configFile ?? DEFAULT_CONFIG_FILE;
|
|
5741
|
+
if (options.porcelain) {
|
|
5742
|
+
options.yes = true;
|
|
5743
|
+
options.autoUpdate = false;
|
|
5744
|
+
}
|
|
5653
5745
|
try {
|
|
5746
|
+
let result;
|
|
5654
5747
|
if (isGitHubUrl(resolvedConfigFile)) {
|
|
5655
5748
|
if (!options.experimentalSharedCompose) {
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5749
|
+
if (options.porcelain) {
|
|
5750
|
+
console.log(
|
|
5751
|
+
JSON.stringify({
|
|
5752
|
+
error: "Composing shared agents requires --experimental-shared-compose flag"
|
|
5753
|
+
})
|
|
5754
|
+
);
|
|
5755
|
+
} else {
|
|
5756
|
+
console.error(
|
|
5757
|
+
chalk4.red(
|
|
5758
|
+
"\u2717 Composing shared agents requires --experimental-shared-compose flag"
|
|
5759
|
+
)
|
|
5760
|
+
);
|
|
5761
|
+
console.error();
|
|
5762
|
+
console.error(
|
|
5763
|
+
chalk4.dim(
|
|
5764
|
+
" Composing agents from other users carries security risks."
|
|
5765
|
+
)
|
|
5766
|
+
);
|
|
5767
|
+
console.error(
|
|
5768
|
+
chalk4.dim(" Only compose agents from users you trust.")
|
|
5769
|
+
);
|
|
5770
|
+
}
|
|
5670
5771
|
process.exit(1);
|
|
5671
5772
|
}
|
|
5672
|
-
await handleGitHubCompose(resolvedConfigFile, options);
|
|
5773
|
+
result = await handleGitHubCompose(resolvedConfigFile, options);
|
|
5673
5774
|
} else {
|
|
5674
|
-
const { config, agentName, agent, basePath } = await loadAndValidateConfig(resolvedConfigFile);
|
|
5675
|
-
|
|
5676
|
-
|
|
5775
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(resolvedConfigFile, options.porcelain);
|
|
5776
|
+
if (!options.porcelain) {
|
|
5777
|
+
checkLegacyImageFormat(config);
|
|
5778
|
+
}
|
|
5779
|
+
const skillResults = await uploadAssets(
|
|
5780
|
+
agentName,
|
|
5781
|
+
agent,
|
|
5782
|
+
basePath,
|
|
5783
|
+
options.porcelain
|
|
5784
|
+
);
|
|
5677
5785
|
const environment = agent.environment || {};
|
|
5678
5786
|
const variables = await collectSkillVariables(
|
|
5679
5787
|
skillResults,
|
|
5680
5788
|
environment,
|
|
5681
5789
|
agentName
|
|
5682
5790
|
);
|
|
5683
|
-
await finalizeCompose(config, agent, variables, options);
|
|
5791
|
+
result = await finalizeCompose(config, agent, variables, options);
|
|
5792
|
+
}
|
|
5793
|
+
if (options.porcelain) {
|
|
5794
|
+
console.log(JSON.stringify(result));
|
|
5684
5795
|
}
|
|
5685
5796
|
} catch (error) {
|
|
5797
|
+
if (options.porcelain) {
|
|
5798
|
+
const message = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
5799
|
+
console.log(JSON.stringify({ error: message }));
|
|
5800
|
+
process.exit(1);
|
|
5801
|
+
}
|
|
5686
5802
|
if (error instanceof Error) {
|
|
5687
5803
|
if (error.message.includes("Not authenticated")) {
|
|
5688
5804
|
console.error(
|
|
@@ -7940,7 +8056,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
7940
8056
|
}
|
|
7941
8057
|
showNextSteps(result);
|
|
7942
8058
|
if (options.autoUpdate !== false) {
|
|
7943
|
-
await silentUpgradeAfterCommand("9.
|
|
8059
|
+
await silentUpgradeAfterCommand("9.22.0");
|
|
7944
8060
|
}
|
|
7945
8061
|
} catch (error) {
|
|
7946
8062
|
handleRunError(error, identifier);
|
|
@@ -9447,7 +9563,7 @@ var cookAction = new Command27().name("cook").description("Quick start: prepare,
|
|
|
9447
9563
|
).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(
|
|
9448
9564
|
async (prompt, options) => {
|
|
9449
9565
|
if (options.autoUpdate !== false) {
|
|
9450
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
9566
|
+
const shouldExit = await checkAndUpgrade("9.22.0", prompt);
|
|
9451
9567
|
if (shouldExit) {
|
|
9452
9568
|
process.exit(0);
|
|
9453
9569
|
}
|
|
@@ -13545,7 +13661,7 @@ var setupClaudeCommand = new Command67().name("setup-claude").description("Insta
|
|
|
13545
13661
|
|
|
13546
13662
|
// src/index.ts
|
|
13547
13663
|
var program = new Command68();
|
|
13548
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
13664
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.22.0");
|
|
13549
13665
|
program.addCommand(authCommand);
|
|
13550
13666
|
program.addCommand(infoCommand);
|
|
13551
13667
|
program.addCommand(composeCommand);
|