@vm0/cli 9.11.0 → 9.13.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 +718 -536
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -234,8 +234,8 @@ var infoCommand = new Command6().name("info").description("Display environment i
|
|
|
234
234
|
});
|
|
235
235
|
|
|
236
236
|
// src/commands/compose/index.ts
|
|
237
|
-
import { Command as Command7 } from "commander";
|
|
238
|
-
import
|
|
237
|
+
import { Command as Command7, Option } from "commander";
|
|
238
|
+
import chalk4 from "chalk";
|
|
239
239
|
import { readFile as readFile4 } from "fs/promises";
|
|
240
240
|
import { existsSync as existsSync3 } from "fs";
|
|
241
241
|
import { dirname as dirname2 } from "path";
|
|
@@ -1905,6 +1905,29 @@ var MODEL_PROVIDER_TYPES = {
|
|
|
1905
1905
|
credentialLabel: "API key",
|
|
1906
1906
|
helpText: "Get your API key at: https://console.anthropic.com/settings/keys"
|
|
1907
1907
|
},
|
|
1908
|
+
"openrouter-api-key": {
|
|
1909
|
+
framework: "claude-code",
|
|
1910
|
+
credentialName: "OPENROUTER_API_KEY",
|
|
1911
|
+
label: "OpenRouter API Key",
|
|
1912
|
+
credentialLabel: "API key",
|
|
1913
|
+
helpText: "Get your API key at: https://openrouter.ai/settings/keys",
|
|
1914
|
+
environmentMapping: {
|
|
1915
|
+
ANTHROPIC_AUTH_TOKEN: "$credential",
|
|
1916
|
+
ANTHROPIC_BASE_URL: "https://openrouter.ai/api",
|
|
1917
|
+
ANTHROPIC_API_KEY: "",
|
|
1918
|
+
ANTHROPIC_MODEL: "$model",
|
|
1919
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: "$model",
|
|
1920
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: "$model",
|
|
1921
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: "$model",
|
|
1922
|
+
CLAUDE_CODE_SUBAGENT_MODEL: "$model"
|
|
1923
|
+
},
|
|
1924
|
+
models: [
|
|
1925
|
+
"anthropic/claude-sonnet-4.5",
|
|
1926
|
+
"anthropic/claude-opus-4.5",
|
|
1927
|
+
"anthropic/claude-haiku-4.5"
|
|
1928
|
+
],
|
|
1929
|
+
defaultModel: ""
|
|
1930
|
+
},
|
|
1908
1931
|
"moonshot-api-key": {
|
|
1909
1932
|
framework: "claude-code",
|
|
1910
1933
|
credentialName: "MOONSHOT_API_KEY",
|
|
@@ -1926,12 +1949,34 @@ var MODEL_PROVIDER_TYPES = {
|
|
|
1926
1949
|
"kimi-k2-thinking"
|
|
1927
1950
|
],
|
|
1928
1951
|
defaultModel: "kimi-k2.5"
|
|
1952
|
+
},
|
|
1953
|
+
"minimax-api-key": {
|
|
1954
|
+
framework: "claude-code",
|
|
1955
|
+
credentialName: "MINIMAX_API_KEY",
|
|
1956
|
+
label: "MiniMax API Key",
|
|
1957
|
+
credentialLabel: "API key",
|
|
1958
|
+
helpText: "Get your API key at: https://platform.minimax.io/user-center/basic-information/interface-key",
|
|
1959
|
+
environmentMapping: {
|
|
1960
|
+
ANTHROPIC_AUTH_TOKEN: "$credential",
|
|
1961
|
+
ANTHROPIC_BASE_URL: "https://api.minimax.io/anthropic",
|
|
1962
|
+
ANTHROPIC_MODEL: "$model",
|
|
1963
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: "$model",
|
|
1964
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: "$model",
|
|
1965
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: "$model",
|
|
1966
|
+
CLAUDE_CODE_SUBAGENT_MODEL: "$model",
|
|
1967
|
+
API_TIMEOUT_MS: "3000000",
|
|
1968
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
|
1969
|
+
},
|
|
1970
|
+
models: ["MiniMax-M2.1"],
|
|
1971
|
+
defaultModel: "MiniMax-M2.1"
|
|
1929
1972
|
}
|
|
1930
1973
|
};
|
|
1931
1974
|
var modelProviderTypeSchema = z14.enum([
|
|
1932
1975
|
"claude-code-oauth-token",
|
|
1933
1976
|
"anthropic-api-key",
|
|
1934
|
-
"
|
|
1977
|
+
"openrouter-api-key",
|
|
1978
|
+
"moonshot-api-key",
|
|
1979
|
+
"minimax-api-key"
|
|
1935
1980
|
]);
|
|
1936
1981
|
var modelProviderFrameworkSchema = z14.enum(["claude-code", "codex"]);
|
|
1937
1982
|
function getModels(type) {
|
|
@@ -2072,6 +2117,27 @@ var modelProvidersSetDefaultContract = c11.router({
|
|
|
2072
2117
|
summary: "Set a model provider as default for its framework"
|
|
2073
2118
|
}
|
|
2074
2119
|
});
|
|
2120
|
+
var updateModelRequestSchema = z14.object({
|
|
2121
|
+
selectedModel: z14.string().optional()
|
|
2122
|
+
});
|
|
2123
|
+
var modelProvidersUpdateModelContract = c11.router({
|
|
2124
|
+
updateModel: {
|
|
2125
|
+
method: "PATCH",
|
|
2126
|
+
path: "/api/model-providers/:type/model",
|
|
2127
|
+
headers: authHeadersSchema,
|
|
2128
|
+
pathParams: z14.object({
|
|
2129
|
+
type: modelProviderTypeSchema
|
|
2130
|
+
}),
|
|
2131
|
+
body: updateModelRequestSchema,
|
|
2132
|
+
responses: {
|
|
2133
|
+
200: modelProviderResponseSchema,
|
|
2134
|
+
401: apiErrorSchema,
|
|
2135
|
+
404: apiErrorSchema,
|
|
2136
|
+
500: apiErrorSchema
|
|
2137
|
+
},
|
|
2138
|
+
summary: "Update model selection for an existing provider"
|
|
2139
|
+
}
|
|
2140
|
+
});
|
|
2075
2141
|
|
|
2076
2142
|
// ../../packages/core/src/contracts/sessions.ts
|
|
2077
2143
|
import { z as z15 } from "zod";
|
|
@@ -2507,7 +2573,10 @@ var platformLogStatusSchema = z19.enum([
|
|
|
2507
2573
|
"cancelled"
|
|
2508
2574
|
]);
|
|
2509
2575
|
var platformLogEntrySchema = z19.object({
|
|
2510
|
-
id: z19.string().uuid()
|
|
2576
|
+
id: z19.string().uuid(),
|
|
2577
|
+
agentName: z19.string(),
|
|
2578
|
+
status: platformLogStatusSchema,
|
|
2579
|
+
createdAt: z19.string()
|
|
2511
2580
|
});
|
|
2512
2581
|
var platformLogsListResponseSchema = z19.object({
|
|
2513
2582
|
data: z19.array(platformLogEntrySchema),
|
|
@@ -3685,6 +3754,18 @@ async function setModelProviderDefault(type) {
|
|
|
3685
3754
|
}
|
|
3686
3755
|
handleError(result, "Failed to set default model provider");
|
|
3687
3756
|
}
|
|
3757
|
+
async function updateModelProviderModel(type, selectedModel) {
|
|
3758
|
+
const config = await getClientConfig();
|
|
3759
|
+
const client = initClient8(modelProvidersUpdateModelContract, config);
|
|
3760
|
+
const result = await client.updateModel({
|
|
3761
|
+
params: { type },
|
|
3762
|
+
body: { selectedModel }
|
|
3763
|
+
});
|
|
3764
|
+
if (result.status === 200) {
|
|
3765
|
+
return result.body;
|
|
3766
|
+
}
|
|
3767
|
+
handleError(result, "Failed to update model provider");
|
|
3768
|
+
}
|
|
3688
3769
|
|
|
3689
3770
|
// src/lib/api/domains/usage.ts
|
|
3690
3771
|
async function getUsage(options) {
|
|
@@ -4411,6 +4492,188 @@ async function promptPassword(message) {
|
|
|
4411
4492
|
return response.value;
|
|
4412
4493
|
}
|
|
4413
4494
|
|
|
4495
|
+
// src/lib/utils/update-checker.ts
|
|
4496
|
+
import { spawn } from "child_process";
|
|
4497
|
+
import chalk3 from "chalk";
|
|
4498
|
+
var PACKAGE_NAME = "@vm0/cli";
|
|
4499
|
+
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
4500
|
+
var TIMEOUT_MS = 5e3;
|
|
4501
|
+
function detectPackageManager() {
|
|
4502
|
+
const execPath = process.argv[1] ?? "";
|
|
4503
|
+
if (execPath.includes("pnpm")) {
|
|
4504
|
+
return "pnpm";
|
|
4505
|
+
}
|
|
4506
|
+
if (execPath.includes("/.bun/") || execPath.includes("/bun/")) {
|
|
4507
|
+
return "bun";
|
|
4508
|
+
}
|
|
4509
|
+
if (execPath.includes("/.yarn/") || execPath.includes("/yarn/")) {
|
|
4510
|
+
return "yarn";
|
|
4511
|
+
}
|
|
4512
|
+
if (execPath.includes("/usr/local/") || execPath.includes("/.nvm/") || execPath.includes("/.fnm/") || execPath.includes("/.volta/") || execPath.includes("/.nodenv/") || execPath.includes("/.n/") || execPath.includes("/node_modules/") || execPath.includes("\\npm\\") || // Windows: AppData\Roaming\npm
|
|
4513
|
+
execPath.includes("\\nodejs\\")) {
|
|
4514
|
+
return "npm";
|
|
4515
|
+
}
|
|
4516
|
+
return "unknown";
|
|
4517
|
+
}
|
|
4518
|
+
function isAutoUpgradeSupported(pm) {
|
|
4519
|
+
return pm === "npm" || pm === "pnpm";
|
|
4520
|
+
}
|
|
4521
|
+
function getManualUpgradeCommand(pm) {
|
|
4522
|
+
switch (pm) {
|
|
4523
|
+
case "bun":
|
|
4524
|
+
return `bun add -g ${PACKAGE_NAME}@latest`;
|
|
4525
|
+
case "yarn":
|
|
4526
|
+
return `yarn global add ${PACKAGE_NAME}@latest`;
|
|
4527
|
+
case "pnpm":
|
|
4528
|
+
return `pnpm add -g ${PACKAGE_NAME}@latest`;
|
|
4529
|
+
case "npm":
|
|
4530
|
+
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
4531
|
+
case "unknown":
|
|
4532
|
+
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
4533
|
+
}
|
|
4534
|
+
}
|
|
4535
|
+
function escapeForShell(str) {
|
|
4536
|
+
return `"${str.replace(/"/g, '\\"')}"`;
|
|
4537
|
+
}
|
|
4538
|
+
function buildRerunCommand(prompt) {
|
|
4539
|
+
if (prompt) {
|
|
4540
|
+
return `vm0 cook ${escapeForShell(prompt)}`;
|
|
4541
|
+
}
|
|
4542
|
+
return "vm0 cook";
|
|
4543
|
+
}
|
|
4544
|
+
async function getLatestVersion() {
|
|
4545
|
+
try {
|
|
4546
|
+
const controller = new AbortController();
|
|
4547
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
4548
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
4549
|
+
signal: controller.signal
|
|
4550
|
+
});
|
|
4551
|
+
clearTimeout(timeoutId);
|
|
4552
|
+
if (!response.ok) {
|
|
4553
|
+
return null;
|
|
4554
|
+
}
|
|
4555
|
+
const json = await response.json();
|
|
4556
|
+
return json.version ?? null;
|
|
4557
|
+
} catch {
|
|
4558
|
+
return null;
|
|
4559
|
+
}
|
|
4560
|
+
}
|
|
4561
|
+
function performUpgrade(packageManager) {
|
|
4562
|
+
return new Promise((resolve) => {
|
|
4563
|
+
const isWindows = process.platform === "win32";
|
|
4564
|
+
const command = isWindows ? `${packageManager}.cmd` : packageManager;
|
|
4565
|
+
const args = packageManager === "pnpm" ? ["add", "-g", `${PACKAGE_NAME}@latest`] : ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
4566
|
+
const child = spawn(command, args, {
|
|
4567
|
+
stdio: "inherit",
|
|
4568
|
+
shell: isWindows
|
|
4569
|
+
});
|
|
4570
|
+
child.on("close", (code) => {
|
|
4571
|
+
resolve(code === 0);
|
|
4572
|
+
});
|
|
4573
|
+
child.on("error", () => {
|
|
4574
|
+
resolve(false);
|
|
4575
|
+
});
|
|
4576
|
+
});
|
|
4577
|
+
}
|
|
4578
|
+
async function checkAndUpgrade(currentVersion, prompt) {
|
|
4579
|
+
const latestVersion = await getLatestVersion();
|
|
4580
|
+
if (latestVersion === null) {
|
|
4581
|
+
console.log(chalk3.yellow("Warning: Could not check for updates"));
|
|
4582
|
+
console.log();
|
|
4583
|
+
return false;
|
|
4584
|
+
}
|
|
4585
|
+
if (latestVersion === currentVersion) {
|
|
4586
|
+
return false;
|
|
4587
|
+
}
|
|
4588
|
+
console.log(chalk3.yellow("vm0 is currently in beta."));
|
|
4589
|
+
console.log(
|
|
4590
|
+
chalk3.yellow(
|
|
4591
|
+
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
4592
|
+
)
|
|
4593
|
+
);
|
|
4594
|
+
console.log(
|
|
4595
|
+
chalk3.yellow(
|
|
4596
|
+
"Please always use the latest version for best compatibility."
|
|
4597
|
+
)
|
|
4598
|
+
);
|
|
4599
|
+
console.log();
|
|
4600
|
+
const packageManager = detectPackageManager();
|
|
4601
|
+
if (!isAutoUpgradeSupported(packageManager)) {
|
|
4602
|
+
if (packageManager === "unknown") {
|
|
4603
|
+
console.log(
|
|
4604
|
+
chalk3.yellow("Could not detect your package manager for auto-upgrade.")
|
|
4605
|
+
);
|
|
4606
|
+
} else {
|
|
4607
|
+
console.log(
|
|
4608
|
+
chalk3.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
|
|
4609
|
+
);
|
|
4610
|
+
}
|
|
4611
|
+
console.log(chalk3.yellow("Please upgrade manually:"));
|
|
4612
|
+
console.log(chalk3.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
4613
|
+
console.log();
|
|
4614
|
+
return false;
|
|
4615
|
+
}
|
|
4616
|
+
console.log(`Upgrading via ${packageManager}...`);
|
|
4617
|
+
const success = await performUpgrade(packageManager);
|
|
4618
|
+
if (success) {
|
|
4619
|
+
console.log(chalk3.green(`Upgraded to ${latestVersion}`));
|
|
4620
|
+
console.log();
|
|
4621
|
+
console.log("To continue, run:");
|
|
4622
|
+
console.log(chalk3.cyan(` ${buildRerunCommand(prompt)}`));
|
|
4623
|
+
return true;
|
|
4624
|
+
}
|
|
4625
|
+
console.log();
|
|
4626
|
+
console.log(chalk3.red("Upgrade failed. Please run manually:"));
|
|
4627
|
+
console.log(chalk3.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
4628
|
+
console.log();
|
|
4629
|
+
console.log("Then re-run:");
|
|
4630
|
+
console.log(chalk3.cyan(` ${buildRerunCommand(prompt)}`));
|
|
4631
|
+
return true;
|
|
4632
|
+
}
|
|
4633
|
+
async function silentUpgradeAfterCommand(currentVersion) {
|
|
4634
|
+
const latestVersion = await getLatestVersion();
|
|
4635
|
+
if (latestVersion === null || latestVersion === currentVersion) {
|
|
4636
|
+
return;
|
|
4637
|
+
}
|
|
4638
|
+
const packageManager = detectPackageManager();
|
|
4639
|
+
if (!isAutoUpgradeSupported(packageManager)) {
|
|
4640
|
+
return;
|
|
4641
|
+
}
|
|
4642
|
+
const isWindows = process.platform === "win32";
|
|
4643
|
+
const command = isWindows ? `${packageManager}.cmd` : packageManager;
|
|
4644
|
+
const args = packageManager === "pnpm" ? ["add", "-g", `${PACKAGE_NAME}@latest`] : ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
4645
|
+
const upgradeResult = await new Promise((resolve) => {
|
|
4646
|
+
const child = spawn(command, args, {
|
|
4647
|
+
stdio: "pipe",
|
|
4648
|
+
// Capture output instead of inheriting
|
|
4649
|
+
shell: isWindows,
|
|
4650
|
+
detached: !isWindows,
|
|
4651
|
+
// Detach on non-Windows
|
|
4652
|
+
windowsHide: true
|
|
4653
|
+
});
|
|
4654
|
+
const timeoutId = setTimeout(() => {
|
|
4655
|
+
child.kill();
|
|
4656
|
+
resolve(false);
|
|
4657
|
+
}, TIMEOUT_MS);
|
|
4658
|
+
child.on("close", (code) => {
|
|
4659
|
+
clearTimeout(timeoutId);
|
|
4660
|
+
resolve(code === 0);
|
|
4661
|
+
});
|
|
4662
|
+
child.on("error", () => {
|
|
4663
|
+
clearTimeout(timeoutId);
|
|
4664
|
+
resolve(false);
|
|
4665
|
+
});
|
|
4666
|
+
});
|
|
4667
|
+
if (!upgradeResult) {
|
|
4668
|
+
console.log(
|
|
4669
|
+
chalk3.yellow(
|
|
4670
|
+
`
|
|
4671
|
+
\u26A0 vm0 auto upgrade failed. Please run: ${getManualUpgradeCommand(packageManager)}`
|
|
4672
|
+
)
|
|
4673
|
+
);
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4414
4677
|
// src/commands/compose/index.ts
|
|
4415
4678
|
function getSecretsFromComposeContent(content) {
|
|
4416
4679
|
const refs = extractVariableReferences(content);
|
|
@@ -4419,7 +4682,7 @@ function getSecretsFromComposeContent(content) {
|
|
|
4419
4682
|
}
|
|
4420
4683
|
async function loadAndValidateConfig(configFile) {
|
|
4421
4684
|
if (!existsSync3(configFile)) {
|
|
4422
|
-
console.error(
|
|
4685
|
+
console.error(chalk4.red(`\u2717 Config file not found: ${configFile}`));
|
|
4423
4686
|
process.exit(1);
|
|
4424
4687
|
}
|
|
4425
4688
|
const content = await readFile4(configFile, "utf8");
|
|
@@ -4427,15 +4690,15 @@ async function loadAndValidateConfig(configFile) {
|
|
|
4427
4690
|
try {
|
|
4428
4691
|
config = parseYaml2(content);
|
|
4429
4692
|
} catch (error) {
|
|
4430
|
-
console.error(
|
|
4693
|
+
console.error(chalk4.red("\u2717 Invalid YAML format"));
|
|
4431
4694
|
if (error instanceof Error) {
|
|
4432
|
-
console.error(
|
|
4695
|
+
console.error(chalk4.dim(` ${error.message}`));
|
|
4433
4696
|
}
|
|
4434
4697
|
process.exit(1);
|
|
4435
4698
|
}
|
|
4436
4699
|
const validation = validateAgentCompose(config);
|
|
4437
4700
|
if (!validation.valid) {
|
|
4438
|
-
console.error(
|
|
4701
|
+
console.error(chalk4.red(`\u2717 ${validation.error}`));
|
|
4439
4702
|
process.exit(1);
|
|
4440
4703
|
}
|
|
4441
4704
|
const cfg = config;
|
|
@@ -4452,13 +4715,13 @@ function checkLegacyImageFormat(config) {
|
|
|
4452
4715
|
const image = agentConfig.image;
|
|
4453
4716
|
if (image) {
|
|
4454
4717
|
console.log(
|
|
4455
|
-
|
|
4718
|
+
chalk4.yellow(
|
|
4456
4719
|
`\u26A0 Agent "${name}": 'image' field is deprecated. Use 'apps' field for pre-installed tools.`
|
|
4457
4720
|
)
|
|
4458
4721
|
);
|
|
4459
4722
|
const warning = getLegacySystemTemplateWarning(image);
|
|
4460
4723
|
if (warning) {
|
|
4461
|
-
console.log(
|
|
4724
|
+
console.log(chalk4.yellow(` ${warning}`));
|
|
4462
4725
|
}
|
|
4463
4726
|
}
|
|
4464
4727
|
}
|
|
@@ -4473,7 +4736,7 @@ async function uploadAssets(agentName, agent, basePath) {
|
|
|
4473
4736
|
agent.framework
|
|
4474
4737
|
);
|
|
4475
4738
|
console.log(
|
|
4476
|
-
|
|
4739
|
+
chalk4.green(
|
|
4477
4740
|
`\u2713 Instructions ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
4478
4741
|
)
|
|
4479
4742
|
);
|
|
@@ -4482,11 +4745,11 @@ async function uploadAssets(agentName, agent, basePath) {
|
|
|
4482
4745
|
if (agent.skills && Array.isArray(agent.skills)) {
|
|
4483
4746
|
console.log(`Uploading ${agent.skills.length} skill(s)...`);
|
|
4484
4747
|
for (const skillUrl of agent.skills) {
|
|
4485
|
-
console.log(
|
|
4748
|
+
console.log(chalk4.dim(` Downloading: ${skillUrl}`));
|
|
4486
4749
|
const result = await uploadSkill(skillUrl);
|
|
4487
4750
|
skillResults.push(result);
|
|
4488
4751
|
console.log(
|
|
4489
|
-
|
|
4752
|
+
chalk4.green(
|
|
4490
4753
|
` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.skillName} (${result.versionId.slice(0, 8)})`
|
|
4491
4754
|
)
|
|
4492
4755
|
);
|
|
@@ -4537,19 +4800,19 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4537
4800
|
}
|
|
4538
4801
|
console.log();
|
|
4539
4802
|
console.log(
|
|
4540
|
-
|
|
4803
|
+
chalk4.bold("Skills require the following environment variables:")
|
|
4541
4804
|
);
|
|
4542
4805
|
console.log();
|
|
4543
4806
|
if (newSecrets.length > 0) {
|
|
4544
|
-
console.log(
|
|
4807
|
+
console.log(chalk4.cyan(" Secrets:"));
|
|
4545
4808
|
for (const [name, skills] of newSecrets) {
|
|
4546
4809
|
const isNew = trulyNewSecrets.includes(name);
|
|
4547
|
-
const newMarker = isNew ?
|
|
4810
|
+
const newMarker = isNew ? chalk4.yellow(" (new)") : "";
|
|
4548
4811
|
console.log(` ${name.padEnd(24)}${newMarker} <- ${skills.join(", ")}`);
|
|
4549
4812
|
}
|
|
4550
4813
|
}
|
|
4551
4814
|
if (newVars.length > 0) {
|
|
4552
|
-
console.log(
|
|
4815
|
+
console.log(chalk4.cyan(" Vars:"));
|
|
4553
4816
|
for (const [name, skills] of newVars) {
|
|
4554
4817
|
console.log(` ${name.padEnd(24)} <- ${skills.join(", ")}`);
|
|
4555
4818
|
}
|
|
@@ -4558,10 +4821,10 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4558
4821
|
if (trulyNewSecrets.length > 0 && !options.yes) {
|
|
4559
4822
|
if (!isInteractive()) {
|
|
4560
4823
|
console.error(
|
|
4561
|
-
|
|
4824
|
+
chalk4.red(`\u2717 New secrets detected: ${trulyNewSecrets.join(", ")}`)
|
|
4562
4825
|
);
|
|
4563
4826
|
console.error(
|
|
4564
|
-
|
|
4827
|
+
chalk4.dim(
|
|
4565
4828
|
" Use --yes flag to approve new secrets in non-interactive mode."
|
|
4566
4829
|
)
|
|
4567
4830
|
);
|
|
@@ -4572,7 +4835,7 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4572
4835
|
true
|
|
4573
4836
|
);
|
|
4574
4837
|
if (!confirmed) {
|
|
4575
|
-
console.log(
|
|
4838
|
+
console.log(chalk4.yellow("Compose cancelled"));
|
|
4576
4839
|
return false;
|
|
4577
4840
|
}
|
|
4578
4841
|
}
|
|
@@ -4594,64 +4857,71 @@ function mergeSkillVariables(agent, variables) {
|
|
|
4594
4857
|
agent.environment = environment;
|
|
4595
4858
|
}
|
|
4596
4859
|
}
|
|
4597
|
-
var composeCommand = new Command7().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument("<agent-yaml>", "Path to agent YAML file").option("-y, --yes", "Skip confirmation prompts for skill requirements").
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
console.log(chalk3.green(`\u2713 Compose version exists: ${displayName}`));
|
|
4622
|
-
}
|
|
4623
|
-
console.log(chalk3.dim(` Version: ${shortVersionId}`));
|
|
4624
|
-
console.log();
|
|
4625
|
-
console.log(" Run your agent:");
|
|
4626
|
-
console.log(
|
|
4627
|
-
chalk3.cyan(
|
|
4628
|
-
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
4629
|
-
)
|
|
4630
|
-
);
|
|
4631
|
-
} catch (error) {
|
|
4632
|
-
if (error instanceof Error) {
|
|
4633
|
-
if (error.message.includes("Not authenticated")) {
|
|
4634
|
-
console.error(chalk3.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
4860
|
+
var composeCommand = new Command7().name("compose").description("Create or update agent compose (e.g., vm0.yaml)").argument("<agent-yaml>", "Path to agent YAML file").option("-y, --yes", "Skip confirmation prompts for skill requirements").addOption(new Option("--no-auto-update").hideHelp()).action(
|
|
4861
|
+
async (configFile, options) => {
|
|
4862
|
+
try {
|
|
4863
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(configFile);
|
|
4864
|
+
checkLegacyImageFormat(config);
|
|
4865
|
+
const skillResults = await uploadAssets(agentName, agent, basePath);
|
|
4866
|
+
const environment = agent.environment || {};
|
|
4867
|
+
const variables = await collectSkillVariables(
|
|
4868
|
+
skillResults,
|
|
4869
|
+
environment,
|
|
4870
|
+
agentName
|
|
4871
|
+
);
|
|
4872
|
+
const confirmed = await displayAndConfirmVariables(variables, options);
|
|
4873
|
+
if (!confirmed) {
|
|
4874
|
+
process.exit(0);
|
|
4875
|
+
}
|
|
4876
|
+
mergeSkillVariables(agent, variables);
|
|
4877
|
+
console.log("Uploading compose...");
|
|
4878
|
+
const response = await createOrUpdateCompose({ content: config });
|
|
4879
|
+
const scopeResponse = await getScope();
|
|
4880
|
+
const shortVersionId = response.versionId.slice(0, 8);
|
|
4881
|
+
const displayName = `${scopeResponse.slug}/${response.name}`;
|
|
4882
|
+
if (response.action === "created") {
|
|
4883
|
+
console.log(chalk4.green(`\u2713 Compose created: ${displayName}`));
|
|
4635
4884
|
} else {
|
|
4636
|
-
console.
|
|
4637
|
-
console.error(chalk3.dim(` ${error.message}`));
|
|
4885
|
+
console.log(chalk4.green(`\u2713 Compose version exists: ${displayName}`));
|
|
4638
4886
|
}
|
|
4639
|
-
|
|
4640
|
-
console.
|
|
4887
|
+
console.log(chalk4.dim(` Version: ${shortVersionId}`));
|
|
4888
|
+
console.log();
|
|
4889
|
+
console.log(" Run your agent:");
|
|
4890
|
+
console.log(
|
|
4891
|
+
chalk4.cyan(
|
|
4892
|
+
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
4893
|
+
)
|
|
4894
|
+
);
|
|
4895
|
+
if (options.autoUpdate !== false) {
|
|
4896
|
+
await silentUpgradeAfterCommand("9.13.0");
|
|
4897
|
+
}
|
|
4898
|
+
} catch (error) {
|
|
4899
|
+
if (error instanceof Error) {
|
|
4900
|
+
if (error.message.includes("Not authenticated")) {
|
|
4901
|
+
console.error(
|
|
4902
|
+
chalk4.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
4903
|
+
);
|
|
4904
|
+
} else {
|
|
4905
|
+
console.error(chalk4.red("\u2717 Failed to create compose"));
|
|
4906
|
+
console.error(chalk4.dim(` ${error.message}`));
|
|
4907
|
+
}
|
|
4908
|
+
} else {
|
|
4909
|
+
console.error(chalk4.red("\u2717 An unexpected error occurred"));
|
|
4910
|
+
}
|
|
4911
|
+
process.exit(1);
|
|
4641
4912
|
}
|
|
4642
|
-
process.exit(1);
|
|
4643
4913
|
}
|
|
4644
|
-
|
|
4914
|
+
);
|
|
4645
4915
|
|
|
4646
4916
|
// src/commands/run/run.ts
|
|
4647
|
-
import { Command as Command8, Option } from "commander";
|
|
4648
|
-
import
|
|
4917
|
+
import { Command as Command8, Option as Option2 } from "commander";
|
|
4918
|
+
import chalk9 from "chalk";
|
|
4649
4919
|
|
|
4650
4920
|
// src/lib/events/event-renderer.ts
|
|
4651
|
-
import
|
|
4921
|
+
import chalk6 from "chalk";
|
|
4652
4922
|
|
|
4653
4923
|
// src/lib/events/tool-formatters.ts
|
|
4654
|
-
import
|
|
4924
|
+
import chalk5 from "chalk";
|
|
4655
4925
|
function pluralize(count, singular, plural) {
|
|
4656
4926
|
return count === 1 ? singular : plural;
|
|
4657
4927
|
}
|
|
@@ -4665,15 +4935,15 @@ function formatToolHeader(data) {
|
|
|
4665
4935
|
return [headline];
|
|
4666
4936
|
}
|
|
4667
4937
|
var toolHeadlineFormatters = {
|
|
4668
|
-
Read: (input) => `Read${
|
|
4669
|
-
Edit: (input) => `Edit${
|
|
4670
|
-
Write: (input) => `Write${
|
|
4671
|
-
Bash: (input) => `Bash${
|
|
4672
|
-
Glob: (input) => `Glob${
|
|
4673
|
-
Grep: (input) => `Grep${
|
|
4674
|
-
Task: (input) => `Task${
|
|
4675
|
-
WebFetch: (input) => `WebFetch${
|
|
4676
|
-
WebSearch: (input) => `WebSearch${
|
|
4938
|
+
Read: (input) => `Read${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4939
|
+
Edit: (input) => `Edit${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4940
|
+
Write: (input) => `Write${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4941
|
+
Bash: (input) => `Bash${chalk5.dim(`(${truncate(String(input.command || ""), 60)})`)}`,
|
|
4942
|
+
Glob: (input) => `Glob${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
4943
|
+
Grep: (input) => `Grep${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
4944
|
+
Task: (input) => `Task${chalk5.dim(`(${truncate(String(input.description || ""), 60)})`)}`,
|
|
4945
|
+
WebFetch: (input) => `WebFetch${chalk5.dim(`(${truncate(String(input.url || ""), 60)})`)}`,
|
|
4946
|
+
WebSearch: (input) => `WebSearch${chalk5.dim(`(${truncate(String(input.query || ""), 60)})`)}`,
|
|
4677
4947
|
TodoWrite: () => "TodoWrite"
|
|
4678
4948
|
};
|
|
4679
4949
|
function getToolHeadline(tool, input) {
|
|
@@ -4706,7 +4976,7 @@ function formatToolResult(toolUse, result, verbose) {
|
|
|
4706
4976
|
}
|
|
4707
4977
|
if (isError) {
|
|
4708
4978
|
const errorMsg = resultText ? truncate(resultText, 80) : "Error";
|
|
4709
|
-
lines.push(`\u2514 \u2717 ${
|
|
4979
|
+
lines.push(`\u2514 \u2717 ${chalk5.dim(errorMsg)}`);
|
|
4710
4980
|
return lines;
|
|
4711
4981
|
}
|
|
4712
4982
|
if (resultText) {
|
|
@@ -4714,23 +4984,23 @@ function formatToolResult(toolUse, result, verbose) {
|
|
|
4714
4984
|
if (verbose) {
|
|
4715
4985
|
for (let i = 0; i < resultLines.length; i++) {
|
|
4716
4986
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4717
|
-
lines.push(`${prefix}${
|
|
4987
|
+
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
4718
4988
|
}
|
|
4719
4989
|
} else if (resultLines.length > 0) {
|
|
4720
4990
|
const previewCount = Math.min(3, resultLines.length);
|
|
4721
4991
|
for (let i = 0; i < previewCount; i++) {
|
|
4722
4992
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4723
|
-
lines.push(`${prefix}${
|
|
4993
|
+
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
4724
4994
|
}
|
|
4725
4995
|
const remaining = resultLines.length - previewCount;
|
|
4726
4996
|
if (remaining > 0) {
|
|
4727
4997
|
lines.push(
|
|
4728
|
-
` ${
|
|
4998
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4729
4999
|
);
|
|
4730
5000
|
}
|
|
4731
5001
|
}
|
|
4732
5002
|
} else {
|
|
4733
|
-
lines.push(`\u2514 \u2713 ${
|
|
5003
|
+
lines.push(`\u2514 \u2713 ${chalk5.dim("Done")}`);
|
|
4734
5004
|
}
|
|
4735
5005
|
return lines;
|
|
4736
5006
|
}
|
|
@@ -4748,24 +5018,24 @@ function formatReadContent(resultText, verbose) {
|
|
|
4748
5018
|
const displayLines = contentLines.length > 0 ? contentLines : rawLines.filter((line) => line.trim().length > 0);
|
|
4749
5019
|
const totalLines = displayLines.length;
|
|
4750
5020
|
if (totalLines === 0) {
|
|
4751
|
-
lines.push(`\u2514 \u2713 ${
|
|
5021
|
+
lines.push(`\u2514 \u2713 ${chalk5.dim("(empty)")}`);
|
|
4752
5022
|
return lines;
|
|
4753
5023
|
}
|
|
4754
5024
|
if (verbose) {
|
|
4755
5025
|
for (let i = 0; i < displayLines.length; i++) {
|
|
4756
5026
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4757
|
-
lines.push(`${prefix}${
|
|
5027
|
+
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
4758
5028
|
}
|
|
4759
5029
|
} else {
|
|
4760
5030
|
const previewCount = Math.min(3, totalLines);
|
|
4761
5031
|
for (let i = 0; i < previewCount; i++) {
|
|
4762
5032
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4763
|
-
lines.push(`${prefix}${
|
|
5033
|
+
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
4764
5034
|
}
|
|
4765
5035
|
const remaining = totalLines - previewCount;
|
|
4766
5036
|
if (remaining > 0) {
|
|
4767
5037
|
lines.push(
|
|
4768
|
-
` ${
|
|
5038
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4769
5039
|
);
|
|
4770
5040
|
}
|
|
4771
5041
|
}
|
|
@@ -4779,18 +5049,18 @@ function formatWritePreview(input, verbose) {
|
|
|
4779
5049
|
if (verbose) {
|
|
4780
5050
|
for (let i = 0; i < contentLines.length; i++) {
|
|
4781
5051
|
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4782
|
-
lines.push(`${prefix}${
|
|
5052
|
+
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
4783
5053
|
}
|
|
4784
5054
|
} else {
|
|
4785
5055
|
const previewCount = Math.min(3, totalLines);
|
|
4786
5056
|
for (let i = 0; i < previewCount; i++) {
|
|
4787
5057
|
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4788
|
-
lines.push(`${prefix}${
|
|
5058
|
+
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
4789
5059
|
}
|
|
4790
5060
|
const remaining = totalLines - previewCount;
|
|
4791
5061
|
if (remaining > 0) {
|
|
4792
5062
|
lines.push(
|
|
4793
|
-
` ${
|
|
5063
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4794
5064
|
);
|
|
4795
5065
|
}
|
|
4796
5066
|
}
|
|
@@ -4805,34 +5075,34 @@ function formatEditDiff(input, verbose) {
|
|
|
4805
5075
|
const removed = oldLines.length;
|
|
4806
5076
|
const added = newLines.length;
|
|
4807
5077
|
const summary = `Added ${added} ${pluralize(added, "line", "lines")}, removed ${removed} ${pluralize(removed, "line", "lines")}`;
|
|
4808
|
-
lines.push(`\u23BF ${
|
|
5078
|
+
lines.push(`\u23BF ${chalk5.dim(summary)}`);
|
|
4809
5079
|
if (verbose) {
|
|
4810
5080
|
for (const line of oldLines) {
|
|
4811
|
-
lines.push(` - ${
|
|
5081
|
+
lines.push(` - ${chalk5.dim(line)}`);
|
|
4812
5082
|
}
|
|
4813
5083
|
for (const line of newLines) {
|
|
4814
|
-
lines.push(` + ${
|
|
5084
|
+
lines.push(` + ${chalk5.dim(line)}`);
|
|
4815
5085
|
}
|
|
4816
5086
|
} else {
|
|
4817
5087
|
const previewLimit = 3;
|
|
4818
5088
|
const showOld = Math.min(previewLimit, oldLines.length);
|
|
4819
5089
|
const showNew = Math.min(previewLimit, newLines.length);
|
|
4820
5090
|
for (let i = 0; i < showOld; i++) {
|
|
4821
|
-
lines.push(` - ${
|
|
5091
|
+
lines.push(` - ${chalk5.dim(truncate(oldLines[i] ?? "", 60))}`);
|
|
4822
5092
|
}
|
|
4823
5093
|
const remainingOld = oldLines.length - previewLimit;
|
|
4824
5094
|
if (remainingOld > 0) {
|
|
4825
5095
|
lines.push(
|
|
4826
|
-
` ${
|
|
5096
|
+
` ${chalk5.dim(`\u2026 +${remainingOld} ${pluralize(remainingOld, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4827
5097
|
);
|
|
4828
5098
|
}
|
|
4829
5099
|
for (let i = 0; i < showNew; i++) {
|
|
4830
|
-
lines.push(` + ${
|
|
5100
|
+
lines.push(` + ${chalk5.dim(truncate(newLines[i] ?? "", 60))}`);
|
|
4831
5101
|
}
|
|
4832
5102
|
const remainingNew = newLines.length - previewLimit;
|
|
4833
5103
|
if (remainingNew > 0) {
|
|
4834
5104
|
lines.push(
|
|
4835
|
-
` ${
|
|
5105
|
+
` ${chalk5.dim(`\u2026 +${remainingNew} ${pluralize(remainingNew, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4836
5106
|
);
|
|
4837
5107
|
}
|
|
4838
5108
|
}
|
|
@@ -4870,12 +5140,12 @@ function getTodoStatusIcon(status) {
|
|
|
4870
5140
|
function formatTodoContent(content, status) {
|
|
4871
5141
|
switch (status) {
|
|
4872
5142
|
case "completed":
|
|
4873
|
-
return
|
|
5143
|
+
return chalk5.dim.strikethrough(content);
|
|
4874
5144
|
case "in_progress":
|
|
4875
5145
|
return content;
|
|
4876
5146
|
case "pending":
|
|
4877
5147
|
default:
|
|
4878
|
-
return
|
|
5148
|
+
return chalk5.dim(content);
|
|
4879
5149
|
}
|
|
4880
5150
|
}
|
|
4881
5151
|
|
|
@@ -4893,12 +5163,12 @@ var EventRenderer = class _EventRenderer {
|
|
|
4893
5163
|
* Called immediately after run is created, before polling events
|
|
4894
5164
|
*/
|
|
4895
5165
|
static renderRunStarted(info) {
|
|
4896
|
-
console.log(
|
|
4897
|
-
console.log(` Run ID: ${
|
|
5166
|
+
console.log(chalk6.bold("\u25B6 Run started"));
|
|
5167
|
+
console.log(` Run ID: ${chalk6.dim(info.runId)}`);
|
|
4898
5168
|
if (info.sandboxId) {
|
|
4899
|
-
console.log(` Sandbox: ${
|
|
5169
|
+
console.log(` Sandbox: ${chalk6.dim(info.sandboxId)}`);
|
|
4900
5170
|
}
|
|
4901
|
-
console.log(
|
|
5171
|
+
console.log(chalk6.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
|
|
4902
5172
|
console.log();
|
|
4903
5173
|
}
|
|
4904
5174
|
/**
|
|
@@ -4936,16 +5206,16 @@ var EventRenderer = class _EventRenderer {
|
|
|
4936
5206
|
*/
|
|
4937
5207
|
static renderRunCompleted(result) {
|
|
4938
5208
|
console.log("");
|
|
4939
|
-
console.log(
|
|
5209
|
+
console.log(chalk6.green("\u2713 Run completed successfully"));
|
|
4940
5210
|
if (result) {
|
|
4941
|
-
console.log(` Checkpoint: ${
|
|
4942
|
-
console.log(` Session: ${
|
|
4943
|
-
console.log(` Conversation: ${
|
|
5211
|
+
console.log(` Checkpoint: ${chalk6.dim(result.checkpointId)}`);
|
|
5212
|
+
console.log(` Session: ${chalk6.dim(result.agentSessionId)}`);
|
|
5213
|
+
console.log(` Conversation: ${chalk6.dim(result.conversationId)}`);
|
|
4944
5214
|
if (result.artifact && Object.keys(result.artifact).length > 0) {
|
|
4945
5215
|
console.log(` Artifact:`);
|
|
4946
5216
|
for (const [name, version] of Object.entries(result.artifact)) {
|
|
4947
5217
|
console.log(
|
|
4948
|
-
` ${name}: ${
|
|
5218
|
+
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
4949
5219
|
);
|
|
4950
5220
|
}
|
|
4951
5221
|
}
|
|
@@ -4953,7 +5223,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
4953
5223
|
console.log(` Volumes:`);
|
|
4954
5224
|
for (const [name, version] of Object.entries(result.volumes)) {
|
|
4955
5225
|
console.log(
|
|
4956
|
-
` ${name}: ${
|
|
5226
|
+
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
4957
5227
|
);
|
|
4958
5228
|
}
|
|
4959
5229
|
}
|
|
@@ -4965,10 +5235,10 @@ var EventRenderer = class _EventRenderer {
|
|
|
4965
5235
|
*/
|
|
4966
5236
|
static renderRunFailed(error, runId) {
|
|
4967
5237
|
console.log("");
|
|
4968
|
-
console.log(
|
|
4969
|
-
console.log(` Error: ${
|
|
5238
|
+
console.log(chalk6.red("\u2717 Run failed"));
|
|
5239
|
+
console.log(` Error: ${chalk6.red(error || "Unknown error")}`);
|
|
4970
5240
|
console.log(
|
|
4971
|
-
|
|
5241
|
+
chalk6.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
4972
5242
|
);
|
|
4973
5243
|
}
|
|
4974
5244
|
/**
|
|
@@ -5052,13 +5322,13 @@ var EventRenderer = class _EventRenderer {
|
|
|
5052
5322
|
const frameworkStr = String(event.data.framework || "claude-code");
|
|
5053
5323
|
const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
|
|
5054
5324
|
this.frameworkDisplayName = displayName;
|
|
5055
|
-
console.log(prefix +
|
|
5056
|
-
console.log(` Session: ${
|
|
5325
|
+
console.log(prefix + chalk6.bold(`\u25B7 ${displayName} Started`));
|
|
5326
|
+
console.log(` Session: ${chalk6.dim(String(event.data.sessionId || ""))}`);
|
|
5057
5327
|
if (event.data.model) {
|
|
5058
|
-
console.log(` Model: ${
|
|
5328
|
+
console.log(` Model: ${chalk6.dim(String(event.data.model))}`);
|
|
5059
5329
|
}
|
|
5060
5330
|
console.log(
|
|
5061
|
-
` Tools: ${
|
|
5331
|
+
` Tools: ${chalk6.dim(
|
|
5062
5332
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
5063
5333
|
)}`
|
|
5064
5334
|
);
|
|
@@ -5075,18 +5345,16 @@ var EventRenderer = class _EventRenderer {
|
|
|
5075
5345
|
const success = Boolean(event.data.success);
|
|
5076
5346
|
if (success) {
|
|
5077
5347
|
console.log(
|
|
5078
|
-
prefix +
|
|
5348
|
+
prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Completed`)
|
|
5079
5349
|
);
|
|
5080
5350
|
} else {
|
|
5081
|
-
console.log(prefix +
|
|
5351
|
+
console.log(prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Failed`));
|
|
5082
5352
|
}
|
|
5083
5353
|
const durationMs = Number(event.data.durationMs || 0);
|
|
5084
5354
|
const durationSec = (durationMs / 1e3).toFixed(1);
|
|
5085
|
-
console.log(` Duration: ${
|
|
5086
|
-
const cost = Number(event.data.cost || 0);
|
|
5087
|
-
console.log(` Cost: ${chalk5.dim("$" + cost.toFixed(4))}`);
|
|
5355
|
+
console.log(` Duration: ${chalk6.dim(durationSec + "s")}`);
|
|
5088
5356
|
const numTurns = Number(event.data.numTurns || 0);
|
|
5089
|
-
console.log(` Turns: ${
|
|
5357
|
+
console.log(` Turns: ${chalk6.dim(String(numTurns))}`);
|
|
5090
5358
|
const usage = event.data.usage;
|
|
5091
5359
|
if (usage && typeof usage === "object") {
|
|
5092
5360
|
const inputTokens = Number(usage.input_tokens || 0);
|
|
@@ -5098,7 +5366,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
5098
5366
|
return String(count);
|
|
5099
5367
|
};
|
|
5100
5368
|
console.log(
|
|
5101
|
-
` Tokens: ${
|
|
5369
|
+
` Tokens: ${chalk6.dim(
|
|
5102
5370
|
`input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
|
|
5103
5371
|
)}`
|
|
5104
5372
|
);
|
|
@@ -5117,7 +5385,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
5117
5385
|
};
|
|
5118
5386
|
|
|
5119
5387
|
// src/commands/run/shared.ts
|
|
5120
|
-
import
|
|
5388
|
+
import chalk8 from "chalk";
|
|
5121
5389
|
import * as fs5 from "fs";
|
|
5122
5390
|
import { config as dotenvConfig } from "dotenv";
|
|
5123
5391
|
|
|
@@ -5443,7 +5711,7 @@ function parseEvent(rawEvent, framework) {
|
|
|
5443
5711
|
}
|
|
5444
5712
|
|
|
5445
5713
|
// src/lib/events/codex-event-renderer.ts
|
|
5446
|
-
import
|
|
5714
|
+
import chalk7 from "chalk";
|
|
5447
5715
|
var CodexEventRenderer = class {
|
|
5448
5716
|
/**
|
|
5449
5717
|
* Check if an event is a Codex event
|
|
@@ -5490,13 +5758,13 @@ var CodexEventRenderer = class {
|
|
|
5490
5758
|
const cached = event.usage.cached_input_tokens || 0;
|
|
5491
5759
|
const cachedStr = cached ? ` (${cached} cached)` : "";
|
|
5492
5760
|
console.log(
|
|
5493
|
-
"[turn.completed]" +
|
|
5761
|
+
"[turn.completed]" + chalk7.dim(` ${input} in / ${output} out${cachedStr}`)
|
|
5494
5762
|
);
|
|
5495
5763
|
}
|
|
5496
5764
|
}
|
|
5497
5765
|
static renderTurnFailed(event) {
|
|
5498
5766
|
console.log(
|
|
5499
|
-
|
|
5767
|
+
chalk7.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
|
|
5500
5768
|
);
|
|
5501
5769
|
}
|
|
5502
5770
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
@@ -5522,15 +5790,15 @@ var CodexEventRenderer = class {
|
|
|
5522
5790
|
if (output) {
|
|
5523
5791
|
const lines = output.split("\n").filter((l) => l.trim());
|
|
5524
5792
|
const preview = lines.slice(0, 3).join("\n ");
|
|
5525
|
-
const more = lines.length > 3 ?
|
|
5793
|
+
const more = lines.length > 3 ? chalk7.dim(` ... (${lines.length - 3} more lines)`) : "";
|
|
5526
5794
|
console.log(
|
|
5527
|
-
"[output]" + (exitCode !== 0 ?
|
|
5795
|
+
"[output]" + (exitCode !== 0 ? chalk7.red(` exit=${exitCode}`) : "")
|
|
5528
5796
|
);
|
|
5529
5797
|
if (preview) {
|
|
5530
5798
|
console.log(" " + preview + more);
|
|
5531
5799
|
}
|
|
5532
5800
|
} else if (exitCode !== 0) {
|
|
5533
|
-
console.log(
|
|
5801
|
+
console.log(chalk7.red("[output]") + chalk7.red(` exit=${exitCode}`));
|
|
5534
5802
|
}
|
|
5535
5803
|
}
|
|
5536
5804
|
return;
|
|
@@ -5540,7 +5808,7 @@ var CodexEventRenderer = class {
|
|
|
5540
5808
|
const icon = c20.kind === "add" ? "+" : c20.kind === "delete" ? "-" : "~";
|
|
5541
5809
|
return `${icon}${c20.path}`;
|
|
5542
5810
|
}).join(", ");
|
|
5543
|
-
console.log(
|
|
5811
|
+
console.log(chalk7.green("[files]") + ` ${summary}`);
|
|
5544
5812
|
return;
|
|
5545
5813
|
}
|
|
5546
5814
|
if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
|
|
@@ -5553,7 +5821,7 @@ var CodexEventRenderer = class {
|
|
|
5553
5821
|
}
|
|
5554
5822
|
static renderError(event) {
|
|
5555
5823
|
console.log(
|
|
5556
|
-
|
|
5824
|
+
chalk7.red("[error]") + ` ${event.message || event.error || "Unknown error"}`
|
|
5557
5825
|
);
|
|
5558
5826
|
}
|
|
5559
5827
|
};
|
|
@@ -6612,9 +6880,9 @@ async function streamRealtimeEvents(runId, options) {
|
|
|
6612
6880
|
EventRenderer.renderRunFailed(error, rid);
|
|
6613
6881
|
},
|
|
6614
6882
|
onTimeout: (rid) => {
|
|
6615
|
-
console.error(
|
|
6883
|
+
console.error(chalk8.red("\n\u2717 Run timed out"));
|
|
6616
6884
|
console.error(
|
|
6617
|
-
|
|
6885
|
+
chalk8.dim(` (use "vm0 logs ${rid} --system" to view system logs)`)
|
|
6618
6886
|
);
|
|
6619
6887
|
}
|
|
6620
6888
|
});
|
|
@@ -6657,9 +6925,9 @@ async function pollEvents(runId, options) {
|
|
|
6657
6925
|
result = { succeeded: false, runId };
|
|
6658
6926
|
} else if (runStatus === "timeout") {
|
|
6659
6927
|
complete = true;
|
|
6660
|
-
console.error(
|
|
6928
|
+
console.error(chalk8.red("\n\u2717 Run timed out"));
|
|
6661
6929
|
console.error(
|
|
6662
|
-
|
|
6930
|
+
chalk8.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
6663
6931
|
);
|
|
6664
6932
|
result = { succeeded: false, runId };
|
|
6665
6933
|
}
|
|
@@ -6673,11 +6941,11 @@ function showNextSteps(result) {
|
|
|
6673
6941
|
const { runId, sessionId, checkpointId } = result;
|
|
6674
6942
|
console.log();
|
|
6675
6943
|
console.log(" View agent logs:");
|
|
6676
|
-
console.log(
|
|
6944
|
+
console.log(chalk8.cyan(` vm0 logs ${runId}`));
|
|
6677
6945
|
if (sessionId) {
|
|
6678
6946
|
console.log(" Continue with session (latest conversation and artifact):");
|
|
6679
6947
|
console.log(
|
|
6680
|
-
|
|
6948
|
+
chalk8.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
6681
6949
|
);
|
|
6682
6950
|
}
|
|
6683
6951
|
if (checkpointId) {
|
|
@@ -6685,40 +6953,66 @@ function showNextSteps(result) {
|
|
|
6685
6953
|
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
6686
6954
|
);
|
|
6687
6955
|
console.log(
|
|
6688
|
-
|
|
6956
|
+
chalk8.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
6689
6957
|
);
|
|
6690
6958
|
}
|
|
6691
6959
|
}
|
|
6692
6960
|
function handleGenericRunError(error, commandLabel) {
|
|
6693
6961
|
if (error instanceof ApiRequestError && error.code === "concurrent_run_limit_exceeded") {
|
|
6694
|
-
console.error(
|
|
6962
|
+
console.error(chalk8.red(`\u2717 ${commandLabel} failed`));
|
|
6695
6963
|
console.error(
|
|
6696
|
-
|
|
6964
|
+
chalk8.dim(
|
|
6697
6965
|
` ${error.message} Use 'vm0 run list' to view runs, 'vm0 run kill <id>' to cancel.`
|
|
6698
6966
|
)
|
|
6699
6967
|
);
|
|
6700
6968
|
} else {
|
|
6701
|
-
console.error(
|
|
6702
|
-
console.error(
|
|
6969
|
+
console.error(chalk8.red(`\u2717 ${commandLabel} failed`));
|
|
6970
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6971
|
+
}
|
|
6972
|
+
}
|
|
6973
|
+
function handleRunError(error, identifier) {
|
|
6974
|
+
if (error instanceof Error) {
|
|
6975
|
+
if (error.message.includes("Not authenticated")) {
|
|
6976
|
+
console.error(chalk8.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
6977
|
+
} else if (error.message.includes("Realtime connection failed")) {
|
|
6978
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6979
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6980
|
+
console.error(chalk8.dim(" Try running without --experimental-realtime"));
|
|
6981
|
+
} else if (error.message.startsWith("Version not found:")) {
|
|
6982
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6983
|
+
console.error(chalk8.dim(" Make sure the version hash is correct"));
|
|
6984
|
+
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6985
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6986
|
+
} else if (error.message.includes("not found")) {
|
|
6987
|
+
console.error(chalk8.red(`\u2717 Agent not found: ${identifier}`));
|
|
6988
|
+
console.error(
|
|
6989
|
+
chalk8.dim(" Make sure you've composed the agent with: vm0 compose")
|
|
6990
|
+
);
|
|
6991
|
+
} else {
|
|
6992
|
+
handleGenericRunError(error, "Run");
|
|
6993
|
+
}
|
|
6994
|
+
} else {
|
|
6995
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6703
6996
|
}
|
|
6997
|
+
process.exit(1);
|
|
6704
6998
|
}
|
|
6705
6999
|
function handleResumeOrContinueError(error, commandLabel, resourceId, resourceLabel) {
|
|
6706
7000
|
if (error instanceof Error) {
|
|
6707
7001
|
if (error.message.includes("Not authenticated")) {
|
|
6708
|
-
console.error(
|
|
7002
|
+
console.error(chalk8.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
6709
7003
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6710
|
-
console.error(
|
|
6711
|
-
console.error(
|
|
6712
|
-
console.error(
|
|
7004
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
7005
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
7006
|
+
console.error(chalk8.dim(" Try running without --experimental-realtime"));
|
|
6713
7007
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6714
|
-
console.error(
|
|
7008
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6715
7009
|
} else if (error.message.includes("not found")) {
|
|
6716
|
-
console.error(
|
|
7010
|
+
console.error(chalk8.red(`\u2717 ${resourceLabel} not found: ${resourceId}`));
|
|
6717
7011
|
} else {
|
|
6718
7012
|
handleGenericRunError(error, commandLabel);
|
|
6719
7013
|
}
|
|
6720
7014
|
} else {
|
|
6721
|
-
console.error(
|
|
7015
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6722
7016
|
}
|
|
6723
7017
|
process.exit(1);
|
|
6724
7018
|
}
|
|
@@ -6757,7 +7051,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6757
7051
|
).option(
|
|
6758
7052
|
"--model-provider <type>",
|
|
6759
7053
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6760
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
7054
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option2("--debug-no-mock-claude").hideHelp()).addOption(new Option2("--no-auto-update").hideHelp()).action(
|
|
6761
7055
|
async (identifier, prompt, options) => {
|
|
6762
7056
|
try {
|
|
6763
7057
|
const { scope, name, version } = parseIdentifier(identifier);
|
|
@@ -6770,9 +7064,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6770
7064
|
} else {
|
|
6771
7065
|
const compose = await getComposeByName(name, scope);
|
|
6772
7066
|
if (!compose) {
|
|
6773
|
-
console.error(
|
|
7067
|
+
console.error(chalk9.red(`\u2717 Agent not found: ${identifier}`));
|
|
6774
7068
|
console.error(
|
|
6775
|
-
|
|
7069
|
+
chalk9.dim(
|
|
6776
7070
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6777
7071
|
)
|
|
6778
7072
|
);
|
|
@@ -6812,9 +7106,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6812
7106
|
debugNoMockClaude: options.debugNoMockClaude || void 0
|
|
6813
7107
|
});
|
|
6814
7108
|
if (response.status === "failed") {
|
|
6815
|
-
console.error(
|
|
7109
|
+
console.error(chalk9.red("\u2717 Run preparation failed"));
|
|
6816
7110
|
if (response.error) {
|
|
6817
|
-
console.error(
|
|
7111
|
+
console.error(chalk9.dim(` ${response.error}`));
|
|
6818
7112
|
}
|
|
6819
7113
|
process.exit(1);
|
|
6820
7114
|
}
|
|
@@ -6829,44 +7123,18 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6829
7123
|
process.exit(1);
|
|
6830
7124
|
}
|
|
6831
7125
|
showNextSteps(result);
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
if (error.message.includes("Not authenticated")) {
|
|
6835
|
-
console.error(
|
|
6836
|
-
chalk8.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
6837
|
-
);
|
|
6838
|
-
} else if (error.message.includes("Realtime connection failed")) {
|
|
6839
|
-
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6840
|
-
console.error(chalk8.dim(` ${error.message}`));
|
|
6841
|
-
console.error(
|
|
6842
|
-
chalk8.dim(" Try running without --experimental-realtime")
|
|
6843
|
-
);
|
|
6844
|
-
} else if (error.message.startsWith("Version not found:")) {
|
|
6845
|
-
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6846
|
-
console.error(chalk8.dim(" Make sure the version hash is correct"));
|
|
6847
|
-
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6848
|
-
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6849
|
-
} else if (error.message.includes("not found")) {
|
|
6850
|
-
console.error(chalk8.red(`\u2717 Agent not found: ${identifier}`));
|
|
6851
|
-
console.error(
|
|
6852
|
-
chalk8.dim(
|
|
6853
|
-
" Make sure you've composed the agent with: vm0 compose"
|
|
6854
|
-
)
|
|
6855
|
-
);
|
|
6856
|
-
} else {
|
|
6857
|
-
handleGenericRunError(error, "Run");
|
|
6858
|
-
}
|
|
6859
|
-
} else {
|
|
6860
|
-
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
7126
|
+
if (options.autoUpdate !== false) {
|
|
7127
|
+
await silentUpgradeAfterCommand("9.13.0");
|
|
6861
7128
|
}
|
|
6862
|
-
|
|
7129
|
+
} catch (error) {
|
|
7130
|
+
handleRunError(error, identifier);
|
|
6863
7131
|
}
|
|
6864
7132
|
}
|
|
6865
7133
|
);
|
|
6866
7134
|
|
|
6867
7135
|
// src/commands/run/resume.ts
|
|
6868
|
-
import { Command as Command9, Option as
|
|
6869
|
-
import
|
|
7136
|
+
import { Command as Command9, Option as Option3 } from "commander";
|
|
7137
|
+
import chalk10 from "chalk";
|
|
6870
7138
|
var resumeCommand = new Command9().name("resume").description("Resume an agent run from a checkpoint (uses all snapshot data)").argument("<checkpointId>", "Checkpoint ID to resume from").argument("<prompt>", "Prompt for the resumed agent").option(
|
|
6871
7139
|
"--env-file <path>",
|
|
6872
7140
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
@@ -6891,7 +7159,7 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6891
7159
|
).option(
|
|
6892
7160
|
"--model-provider <type>",
|
|
6893
7161
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6894
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
7162
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option3("--debug-no-mock-claude").hideHelp()).action(
|
|
6895
7163
|
async (checkpointId, prompt, options, command) => {
|
|
6896
7164
|
const allOpts = command.optsWithGlobals();
|
|
6897
7165
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6899,9 +7167,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6899
7167
|
try {
|
|
6900
7168
|
if (!isUUID(checkpointId)) {
|
|
6901
7169
|
console.error(
|
|
6902
|
-
|
|
7170
|
+
chalk10.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
6903
7171
|
);
|
|
6904
|
-
console.error(
|
|
7172
|
+
console.error(chalk10.dim(" Checkpoint ID must be a valid UUID"));
|
|
6905
7173
|
process.exit(1);
|
|
6906
7174
|
}
|
|
6907
7175
|
const checkpointInfo = await getCheckpoint(checkpointId);
|
|
@@ -6918,9 +7186,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6918
7186
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6919
7187
|
});
|
|
6920
7188
|
if (response.status === "failed") {
|
|
6921
|
-
console.error(
|
|
7189
|
+
console.error(chalk10.red("\u2717 Run preparation failed"));
|
|
6922
7190
|
if (response.error) {
|
|
6923
|
-
console.error(
|
|
7191
|
+
console.error(chalk10.dim(` ${response.error}`));
|
|
6924
7192
|
}
|
|
6925
7193
|
process.exit(1);
|
|
6926
7194
|
}
|
|
@@ -6947,8 +7215,8 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6947
7215
|
);
|
|
6948
7216
|
|
|
6949
7217
|
// src/commands/run/continue.ts
|
|
6950
|
-
import { Command as Command10, Option as
|
|
6951
|
-
import
|
|
7218
|
+
import { Command as Command10, Option as Option4 } from "commander";
|
|
7219
|
+
import chalk11 from "chalk";
|
|
6952
7220
|
var continueCommand = new Command10().name("continue").description(
|
|
6953
7221
|
"Continue an agent run from a session (uses latest artifact version)"
|
|
6954
7222
|
).argument("<agentSessionId>", "Agent session ID to continue from").argument("<prompt>", "Prompt for the continued agent").option(
|
|
@@ -6975,7 +7243,7 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6975
7243
|
).option(
|
|
6976
7244
|
"--model-provider <type>",
|
|
6977
7245
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6978
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
7246
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option4("--debug-no-mock-claude").hideHelp()).action(
|
|
6979
7247
|
async (agentSessionId, prompt, options, command) => {
|
|
6980
7248
|
const allOpts = command.optsWithGlobals();
|
|
6981
7249
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6983,9 +7251,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6983
7251
|
try {
|
|
6984
7252
|
if (!isUUID(agentSessionId)) {
|
|
6985
7253
|
console.error(
|
|
6986
|
-
|
|
7254
|
+
chalk11.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
6987
7255
|
);
|
|
6988
|
-
console.error(
|
|
7256
|
+
console.error(chalk11.dim(" Agent session ID must be a valid UUID"));
|
|
6989
7257
|
process.exit(1);
|
|
6990
7258
|
}
|
|
6991
7259
|
const sessionInfo = await getSession(agentSessionId);
|
|
@@ -7002,9 +7270,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
7002
7270
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
7003
7271
|
});
|
|
7004
7272
|
if (response.status === "failed") {
|
|
7005
|
-
console.error(
|
|
7273
|
+
console.error(chalk11.red("\u2717 Run preparation failed"));
|
|
7006
7274
|
if (response.error) {
|
|
7007
|
-
console.error(
|
|
7275
|
+
console.error(chalk11.dim(` ${response.error}`));
|
|
7008
7276
|
}
|
|
7009
7277
|
process.exit(1);
|
|
7010
7278
|
}
|
|
@@ -7032,20 +7300,20 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
7032
7300
|
|
|
7033
7301
|
// src/commands/run/list.ts
|
|
7034
7302
|
import { Command as Command11 } from "commander";
|
|
7035
|
-
import
|
|
7303
|
+
import chalk12 from "chalk";
|
|
7036
7304
|
var UUID_LENGTH = 36;
|
|
7037
7305
|
function formatRunStatus(status, width) {
|
|
7038
7306
|
const paddedStatus = width ? status.padEnd(width) : status;
|
|
7039
7307
|
switch (status) {
|
|
7040
7308
|
case "running":
|
|
7041
|
-
return
|
|
7309
|
+
return chalk12.green(paddedStatus);
|
|
7042
7310
|
case "pending":
|
|
7043
|
-
return
|
|
7311
|
+
return chalk12.yellow(paddedStatus);
|
|
7044
7312
|
case "completed":
|
|
7045
|
-
return
|
|
7313
|
+
return chalk12.blue(paddedStatus);
|
|
7046
7314
|
case "failed":
|
|
7047
7315
|
case "timeout":
|
|
7048
|
-
return
|
|
7316
|
+
return chalk12.red(paddedStatus);
|
|
7049
7317
|
default:
|
|
7050
7318
|
return paddedStatus;
|
|
7051
7319
|
}
|
|
@@ -7055,7 +7323,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7055
7323
|
const response = await listRuns({ limit: 100 });
|
|
7056
7324
|
const activeRuns = response.runs;
|
|
7057
7325
|
if (activeRuns.length === 0) {
|
|
7058
|
-
console.log(
|
|
7326
|
+
console.log(chalk12.dim("No active runs"));
|
|
7059
7327
|
return;
|
|
7060
7328
|
}
|
|
7061
7329
|
const agentWidth = Math.max(
|
|
@@ -7069,7 +7337,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7069
7337
|
"STATUS".padEnd(statusWidth),
|
|
7070
7338
|
"CREATED"
|
|
7071
7339
|
].join(" ");
|
|
7072
|
-
console.log(
|
|
7340
|
+
console.log(chalk12.dim(header));
|
|
7073
7341
|
for (const run of activeRuns) {
|
|
7074
7342
|
const row = [
|
|
7075
7343
|
run.id.padEnd(UUID_LENGTH),
|
|
@@ -7080,12 +7348,12 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7080
7348
|
console.log(row);
|
|
7081
7349
|
}
|
|
7082
7350
|
} catch (error) {
|
|
7083
|
-
console.error(
|
|
7351
|
+
console.error(chalk12.red("\u2717 Failed to list runs"));
|
|
7084
7352
|
if (error instanceof Error) {
|
|
7085
7353
|
if (error.message.includes("Not authenticated")) {
|
|
7086
|
-
console.error(
|
|
7354
|
+
console.error(chalk12.dim(" Run: vm0 auth login"));
|
|
7087
7355
|
} else {
|
|
7088
|
-
console.error(
|
|
7356
|
+
console.error(chalk12.dim(` ${error.message}`));
|
|
7089
7357
|
}
|
|
7090
7358
|
}
|
|
7091
7359
|
process.exit(1);
|
|
@@ -7094,22 +7362,22 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7094
7362
|
|
|
7095
7363
|
// src/commands/run/kill.ts
|
|
7096
7364
|
import { Command as Command12 } from "commander";
|
|
7097
|
-
import
|
|
7365
|
+
import chalk13 from "chalk";
|
|
7098
7366
|
var killCommand = new Command12().name("kill").description("Kill (cancel) a pending or running run").argument("<run-id>", "Run ID to kill").action(async (runId) => {
|
|
7099
7367
|
try {
|
|
7100
7368
|
await cancelRun(runId);
|
|
7101
|
-
console.log(
|
|
7369
|
+
console.log(chalk13.green(`\u2713 Run ${runId} cancelled`));
|
|
7102
7370
|
} catch (error) {
|
|
7103
|
-
console.error(
|
|
7371
|
+
console.error(chalk13.red("\u2717 Failed to kill run"));
|
|
7104
7372
|
if (error instanceof Error) {
|
|
7105
7373
|
if (error.message.includes("Not authenticated")) {
|
|
7106
|
-
console.error(
|
|
7374
|
+
console.error(chalk13.dim(" Run: vm0 auth login"));
|
|
7107
7375
|
} else if (error.message.includes("not found") || error.message.includes("No such run")) {
|
|
7108
|
-
console.error(
|
|
7376
|
+
console.error(chalk13.dim(` Run not found: ${runId}`));
|
|
7109
7377
|
} else if (error.message.includes("cannot be cancelled")) {
|
|
7110
|
-
console.error(
|
|
7378
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
7111
7379
|
} else {
|
|
7112
|
-
console.error(
|
|
7380
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
7113
7381
|
}
|
|
7114
7382
|
}
|
|
7115
7383
|
process.exit(1);
|
|
@@ -7128,7 +7396,7 @@ import { Command as Command19 } from "commander";
|
|
|
7128
7396
|
|
|
7129
7397
|
// src/commands/volume/init.ts
|
|
7130
7398
|
import { Command as Command13 } from "commander";
|
|
7131
|
-
import
|
|
7399
|
+
import chalk14 from "chalk";
|
|
7132
7400
|
import path6 from "path";
|
|
7133
7401
|
|
|
7134
7402
|
// src/lib/storage/storage-utils.ts
|
|
@@ -7186,10 +7454,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7186
7454
|
const existingConfig = await readStorageConfig(cwd);
|
|
7187
7455
|
if (existingConfig) {
|
|
7188
7456
|
console.log(
|
|
7189
|
-
|
|
7457
|
+
chalk14.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
7190
7458
|
);
|
|
7191
7459
|
console.log(
|
|
7192
|
-
|
|
7460
|
+
chalk14.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7193
7461
|
);
|
|
7194
7462
|
return;
|
|
7195
7463
|
}
|
|
@@ -7198,10 +7466,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7198
7466
|
volumeName = options.name;
|
|
7199
7467
|
} else if (!isInteractive()) {
|
|
7200
7468
|
console.error(
|
|
7201
|
-
|
|
7469
|
+
chalk14.red("\u2717 --name flag is required in non-interactive mode")
|
|
7202
7470
|
);
|
|
7203
7471
|
console.error(
|
|
7204
|
-
|
|
7472
|
+
chalk14.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
7205
7473
|
);
|
|
7206
7474
|
process.exit(1);
|
|
7207
7475
|
} else {
|
|
@@ -7217,34 +7485,34 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7217
7485
|
}
|
|
7218
7486
|
);
|
|
7219
7487
|
if (name === void 0) {
|
|
7220
|
-
console.log(
|
|
7488
|
+
console.log(chalk14.dim("Cancelled"));
|
|
7221
7489
|
return;
|
|
7222
7490
|
}
|
|
7223
7491
|
volumeName = name;
|
|
7224
7492
|
}
|
|
7225
7493
|
if (!isValidStorageName(volumeName)) {
|
|
7226
|
-
console.error(
|
|
7494
|
+
console.error(chalk14.red(`\u2717 Invalid volume name: "${volumeName}"`));
|
|
7227
7495
|
console.error(
|
|
7228
|
-
|
|
7496
|
+
chalk14.dim(
|
|
7229
7497
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7230
7498
|
)
|
|
7231
7499
|
);
|
|
7232
7500
|
console.error(
|
|
7233
|
-
|
|
7501
|
+
chalk14.dim(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
7234
7502
|
);
|
|
7235
7503
|
process.exit(1);
|
|
7236
7504
|
}
|
|
7237
7505
|
await writeStorageConfig(volumeName, cwd);
|
|
7238
|
-
console.log(
|
|
7506
|
+
console.log(chalk14.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
7239
7507
|
console.log(
|
|
7240
|
-
|
|
7508
|
+
chalk14.dim(
|
|
7241
7509
|
` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
|
|
7242
7510
|
)
|
|
7243
7511
|
);
|
|
7244
7512
|
} catch (error) {
|
|
7245
|
-
console.error(
|
|
7513
|
+
console.error(chalk14.red("\u2717 Failed to initialize volume"));
|
|
7246
7514
|
if (error instanceof Error) {
|
|
7247
|
-
console.error(
|
|
7515
|
+
console.error(chalk14.dim(` ${error.message}`));
|
|
7248
7516
|
}
|
|
7249
7517
|
process.exit(1);
|
|
7250
7518
|
}
|
|
@@ -7252,7 +7520,7 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7252
7520
|
|
|
7253
7521
|
// src/commands/volume/push.ts
|
|
7254
7522
|
import { Command as Command14 } from "commander";
|
|
7255
|
-
import
|
|
7523
|
+
import chalk15 from "chalk";
|
|
7256
7524
|
var pushCommand = new Command14().name("push").description("Push local files to cloud volume").option(
|
|
7257
7525
|
"-f, --force",
|
|
7258
7526
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7261,35 +7529,35 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
7261
7529
|
const cwd = process.cwd();
|
|
7262
7530
|
const config = await readStorageConfig(cwd);
|
|
7263
7531
|
if (!config) {
|
|
7264
|
-
console.error(
|
|
7265
|
-
console.error(
|
|
7532
|
+
console.error(chalk15.red("\u2717 No volume initialized in this directory"));
|
|
7533
|
+
console.error(chalk15.dim(" Run: vm0 volume init"));
|
|
7266
7534
|
process.exit(1);
|
|
7267
7535
|
}
|
|
7268
7536
|
console.log(`Pushing volume: ${config.name}`);
|
|
7269
7537
|
const result = await directUpload(config.name, "volume", cwd, {
|
|
7270
7538
|
onProgress: (message) => {
|
|
7271
|
-
console.log(
|
|
7539
|
+
console.log(chalk15.dim(message));
|
|
7272
7540
|
},
|
|
7273
7541
|
force: options.force
|
|
7274
7542
|
});
|
|
7275
7543
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7276
7544
|
if (result.empty) {
|
|
7277
|
-
console.log(
|
|
7545
|
+
console.log(chalk15.dim("No files found (empty volume)"));
|
|
7278
7546
|
} else if (result.deduplicated) {
|
|
7279
|
-
console.log(
|
|
7547
|
+
console.log(chalk15.green("\u2713 Content unchanged (deduplicated)"));
|
|
7280
7548
|
} else {
|
|
7281
|
-
console.log(
|
|
7549
|
+
console.log(chalk15.green("\u2713 Upload complete"));
|
|
7282
7550
|
}
|
|
7283
|
-
console.log(
|
|
7284
|
-
console.log(
|
|
7285
|
-
console.log(
|
|
7551
|
+
console.log(chalk15.dim(` Version: ${shortVersion}`));
|
|
7552
|
+
console.log(chalk15.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7553
|
+
console.log(chalk15.dim(` Size: ${formatBytes(result.size)}`));
|
|
7286
7554
|
} catch (error) {
|
|
7287
|
-
console.error(
|
|
7555
|
+
console.error(chalk15.red("\u2717 Push failed"));
|
|
7288
7556
|
if (error instanceof Error) {
|
|
7289
7557
|
if (error.message.includes("Not authenticated")) {
|
|
7290
|
-
console.error(
|
|
7558
|
+
console.error(chalk15.dim(" Run: vm0 auth login"));
|
|
7291
7559
|
} else {
|
|
7292
|
-
console.error(
|
|
7560
|
+
console.error(chalk15.dim(` ${error.message}`));
|
|
7293
7561
|
}
|
|
7294
7562
|
}
|
|
7295
7563
|
process.exit(1);
|
|
@@ -7298,21 +7566,21 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
7298
7566
|
|
|
7299
7567
|
// src/commands/volume/pull.ts
|
|
7300
7568
|
import { Command as Command15 } from "commander";
|
|
7301
|
-
import
|
|
7569
|
+
import chalk17 from "chalk";
|
|
7302
7570
|
import path7 from "path";
|
|
7303
7571
|
import * as fs6 from "fs";
|
|
7304
7572
|
import * as os4 from "os";
|
|
7305
7573
|
import * as tar3 from "tar";
|
|
7306
7574
|
|
|
7307
7575
|
// src/lib/storage/pull-utils.ts
|
|
7308
|
-
import
|
|
7576
|
+
import chalk16 from "chalk";
|
|
7309
7577
|
async function handleEmptyStorageResponse(cwd) {
|
|
7310
|
-
console.log(
|
|
7578
|
+
console.log(chalk16.dim("Syncing local files..."));
|
|
7311
7579
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
7312
7580
|
if (removedCount > 0) {
|
|
7313
|
-
console.log(
|
|
7581
|
+
console.log(chalk16.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
7314
7582
|
}
|
|
7315
|
-
console.log(
|
|
7583
|
+
console.log(chalk16.green("\u2713 Synced (0 files)"));
|
|
7316
7584
|
return { removedCount };
|
|
7317
7585
|
}
|
|
7318
7586
|
|
|
@@ -7322,8 +7590,8 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7322
7590
|
const cwd = process.cwd();
|
|
7323
7591
|
const config = await readStorageConfig(cwd);
|
|
7324
7592
|
if (!config) {
|
|
7325
|
-
console.error(
|
|
7326
|
-
console.error(
|
|
7593
|
+
console.error(chalk17.red("\u2717 No volume initialized in this directory"));
|
|
7594
|
+
console.error(chalk17.dim(" Run: vm0 volume init"));
|
|
7327
7595
|
process.exit(1);
|
|
7328
7596
|
}
|
|
7329
7597
|
if (versionId) {
|
|
@@ -7331,7 +7599,7 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7331
7599
|
} else {
|
|
7332
7600
|
console.log(`Pulling volume: ${config.name}`);
|
|
7333
7601
|
}
|
|
7334
|
-
console.log(
|
|
7602
|
+
console.log(chalk17.dim("Getting download URL..."));
|
|
7335
7603
|
const downloadInfo = await getStorageDownload({
|
|
7336
7604
|
name: config.name,
|
|
7337
7605
|
type: "volume",
|
|
@@ -7345,18 +7613,18 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7345
7613
|
if (!downloadUrl) {
|
|
7346
7614
|
throw new Error("No download URL returned");
|
|
7347
7615
|
}
|
|
7348
|
-
console.log(
|
|
7616
|
+
console.log(chalk17.dim("Downloading from S3..."));
|
|
7349
7617
|
const s3Response = await fetch(downloadUrl);
|
|
7350
7618
|
if (!s3Response.ok) {
|
|
7351
7619
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7352
7620
|
}
|
|
7353
7621
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7354
7622
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7355
|
-
console.log(
|
|
7623
|
+
console.log(chalk17.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7356
7624
|
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
|
|
7357
7625
|
const tarPath = path7.join(tmpDir, "volume.tar.gz");
|
|
7358
7626
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
7359
|
-
console.log(
|
|
7627
|
+
console.log(chalk17.dim("Syncing local files..."));
|
|
7360
7628
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7361
7629
|
const remoteFilesSet = new Set(
|
|
7362
7630
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7364,10 +7632,10 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7364
7632
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7365
7633
|
if (removedCount > 0) {
|
|
7366
7634
|
console.log(
|
|
7367
|
-
|
|
7635
|
+
chalk17.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7368
7636
|
);
|
|
7369
7637
|
}
|
|
7370
|
-
console.log(
|
|
7638
|
+
console.log(chalk17.dim("Extracting files..."));
|
|
7371
7639
|
await tar3.extract({
|
|
7372
7640
|
file: tarPath,
|
|
7373
7641
|
cwd,
|
|
@@ -7375,14 +7643,14 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7375
7643
|
});
|
|
7376
7644
|
await fs6.promises.unlink(tarPath);
|
|
7377
7645
|
await fs6.promises.rmdir(tmpDir);
|
|
7378
|
-
console.log(
|
|
7646
|
+
console.log(chalk17.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7379
7647
|
} catch (error) {
|
|
7380
|
-
console.error(
|
|
7648
|
+
console.error(chalk17.red("\u2717 Pull failed"));
|
|
7381
7649
|
if (error instanceof Error) {
|
|
7382
7650
|
if (error.message.includes("Not authenticated")) {
|
|
7383
|
-
console.error(
|
|
7651
|
+
console.error(chalk17.dim(" Run: vm0 auth login"));
|
|
7384
7652
|
} else {
|
|
7385
|
-
console.error(
|
|
7653
|
+
console.error(chalk17.dim(` ${error.message}`));
|
|
7386
7654
|
}
|
|
7387
7655
|
}
|
|
7388
7656
|
process.exit(1);
|
|
@@ -7391,23 +7659,23 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7391
7659
|
|
|
7392
7660
|
// src/commands/volume/status.ts
|
|
7393
7661
|
import { Command as Command16 } from "commander";
|
|
7394
|
-
import
|
|
7662
|
+
import chalk18 from "chalk";
|
|
7395
7663
|
var statusCommand2 = new Command16().name("status").description("Show status of cloud volume").action(async () => {
|
|
7396
7664
|
try {
|
|
7397
7665
|
const cwd = process.cwd();
|
|
7398
7666
|
const config = await readStorageConfig(cwd);
|
|
7399
7667
|
if (!config) {
|
|
7400
|
-
console.error(
|
|
7401
|
-
console.error(
|
|
7668
|
+
console.error(chalk18.red("\u2717 No volume initialized in this directory"));
|
|
7669
|
+
console.error(chalk18.dim(" Run: vm0 volume init"));
|
|
7402
7670
|
process.exit(1);
|
|
7403
7671
|
}
|
|
7404
7672
|
if (config.type !== "volume") {
|
|
7405
7673
|
console.error(
|
|
7406
|
-
|
|
7674
|
+
chalk18.red(
|
|
7407
7675
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
7408
7676
|
)
|
|
7409
7677
|
);
|
|
7410
|
-
console.error(
|
|
7678
|
+
console.error(chalk18.dim(" Use: vm0 artifact status"));
|
|
7411
7679
|
process.exit(1);
|
|
7412
7680
|
}
|
|
7413
7681
|
console.log(`Checking volume: ${config.name}`);
|
|
@@ -7417,25 +7685,25 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7417
7685
|
});
|
|
7418
7686
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7419
7687
|
if ("empty" in info) {
|
|
7420
|
-
console.log(
|
|
7421
|
-
console.log(
|
|
7688
|
+
console.log(chalk18.green("\u2713 Found (empty)"));
|
|
7689
|
+
console.log(chalk18.dim(` Version: ${shortVersion}`));
|
|
7422
7690
|
} else {
|
|
7423
|
-
console.log(
|
|
7424
|
-
console.log(
|
|
7425
|
-
console.log(
|
|
7426
|
-
console.log(
|
|
7691
|
+
console.log(chalk18.green("\u2713 Found"));
|
|
7692
|
+
console.log(chalk18.dim(` Version: ${shortVersion}`));
|
|
7693
|
+
console.log(chalk18.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7694
|
+
console.log(chalk18.dim(` Size: ${formatBytes(info.size)}`));
|
|
7427
7695
|
}
|
|
7428
7696
|
} catch (error) {
|
|
7429
7697
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7430
|
-
console.error(
|
|
7431
|
-
console.error(
|
|
7698
|
+
console.error(chalk18.red("\u2717 Not found on remote"));
|
|
7699
|
+
console.error(chalk18.dim(" Run: vm0 volume push"));
|
|
7432
7700
|
} else {
|
|
7433
|
-
console.error(
|
|
7701
|
+
console.error(chalk18.red("\u2717 Status check failed"));
|
|
7434
7702
|
if (error instanceof Error) {
|
|
7435
7703
|
if (error.message.includes("Not authenticated")) {
|
|
7436
|
-
console.error(
|
|
7704
|
+
console.error(chalk18.dim(" Run: vm0 auth login"));
|
|
7437
7705
|
} else {
|
|
7438
|
-
console.error(
|
|
7706
|
+
console.error(chalk18.dim(` ${error.message}`));
|
|
7439
7707
|
}
|
|
7440
7708
|
}
|
|
7441
7709
|
}
|
|
@@ -7445,14 +7713,14 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7445
7713
|
|
|
7446
7714
|
// src/commands/volume/list.ts
|
|
7447
7715
|
import { Command as Command17 } from "commander";
|
|
7448
|
-
import
|
|
7716
|
+
import chalk19 from "chalk";
|
|
7449
7717
|
var listCommand2 = new Command17().name("list").alias("ls").description("List all remote volumes").action(async () => {
|
|
7450
7718
|
try {
|
|
7451
7719
|
const items = await listStorages({ type: "volume" });
|
|
7452
7720
|
if (items.length === 0) {
|
|
7453
|
-
console.log(
|
|
7721
|
+
console.log(chalk19.dim("No volumes found"));
|
|
7454
7722
|
console.log(
|
|
7455
|
-
|
|
7723
|
+
chalk19.dim(" Create one with: vm0 volume init && vm0 volume push")
|
|
7456
7724
|
);
|
|
7457
7725
|
return;
|
|
7458
7726
|
}
|
|
@@ -7471,7 +7739,7 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7471
7739
|
"FILES".padStart(filesWidth),
|
|
7472
7740
|
"UPDATED"
|
|
7473
7741
|
].join(" ");
|
|
7474
|
-
console.log(
|
|
7742
|
+
console.log(chalk19.dim(header));
|
|
7475
7743
|
for (const item of items) {
|
|
7476
7744
|
const row = [
|
|
7477
7745
|
item.name.padEnd(nameWidth),
|
|
@@ -7482,12 +7750,12 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7482
7750
|
console.log(row);
|
|
7483
7751
|
}
|
|
7484
7752
|
} catch (error) {
|
|
7485
|
-
console.error(
|
|
7753
|
+
console.error(chalk19.red("\u2717 Failed to list volumes"));
|
|
7486
7754
|
if (error instanceof Error) {
|
|
7487
7755
|
if (error.message.includes("Not authenticated")) {
|
|
7488
|
-
console.error(
|
|
7756
|
+
console.error(chalk19.dim(" Run: vm0 auth login"));
|
|
7489
7757
|
} else {
|
|
7490
|
-
console.error(
|
|
7758
|
+
console.error(chalk19.dim(` ${error.message}`));
|
|
7491
7759
|
}
|
|
7492
7760
|
}
|
|
7493
7761
|
process.exit(1);
|
|
@@ -7496,10 +7764,10 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7496
7764
|
|
|
7497
7765
|
// src/commands/volume/clone.ts
|
|
7498
7766
|
import { Command as Command18 } from "commander";
|
|
7499
|
-
import
|
|
7767
|
+
import chalk21 from "chalk";
|
|
7500
7768
|
|
|
7501
7769
|
// src/lib/storage/clone-utils.ts
|
|
7502
|
-
import
|
|
7770
|
+
import chalk20 from "chalk";
|
|
7503
7771
|
import path8 from "path";
|
|
7504
7772
|
import * as fs7 from "fs";
|
|
7505
7773
|
import * as os5 from "os";
|
|
@@ -7509,18 +7777,18 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7509
7777
|
if (fs7.existsSync(destination)) {
|
|
7510
7778
|
throw new Error(`Directory "${destination}" already exists`);
|
|
7511
7779
|
}
|
|
7512
|
-
console.log(
|
|
7780
|
+
console.log(chalk20.dim(`Checking remote ${typeLabel}...`));
|
|
7513
7781
|
const downloadInfo = await getStorageDownload({
|
|
7514
7782
|
name,
|
|
7515
7783
|
type,
|
|
7516
7784
|
version: options.version
|
|
7517
7785
|
});
|
|
7518
|
-
console.log(
|
|
7786
|
+
console.log(chalk20.dim(`Creating directory: ${destination}/`));
|
|
7519
7787
|
await fs7.promises.mkdir(destination, { recursive: true });
|
|
7520
7788
|
if ("empty" in downloadInfo) {
|
|
7521
7789
|
await writeStorageConfig(name, destination, type);
|
|
7522
|
-
console.log(
|
|
7523
|
-
console.log(
|
|
7790
|
+
console.log(chalk20.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
|
|
7791
|
+
console.log(chalk20.dim(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7524
7792
|
return {
|
|
7525
7793
|
success: true,
|
|
7526
7794
|
fileCount: 0,
|
|
@@ -7532,7 +7800,7 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7532
7800
|
if (!downloadUrl) {
|
|
7533
7801
|
throw new Error("No download URL returned");
|
|
7534
7802
|
}
|
|
7535
|
-
console.log(
|
|
7803
|
+
console.log(chalk20.dim("Downloading from S3..."));
|
|
7536
7804
|
const s3Response = await fetch(downloadUrl);
|
|
7537
7805
|
if (!s3Response.ok) {
|
|
7538
7806
|
await fs7.promises.rm(destination, { recursive: true, force: true });
|
|
@@ -7540,12 +7808,12 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7540
7808
|
}
|
|
7541
7809
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7542
7810
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7543
|
-
console.log(
|
|
7811
|
+
console.log(chalk20.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7544
7812
|
const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-clone-"));
|
|
7545
7813
|
const tarPath = path8.join(tmpDir, "archive.tar.gz");
|
|
7546
7814
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
7547
7815
|
const files = await listTarFiles(tarPath);
|
|
7548
|
-
console.log(
|
|
7816
|
+
console.log(chalk20.dim("Extracting files..."));
|
|
7549
7817
|
await tar4.extract({
|
|
7550
7818
|
file: tarPath,
|
|
7551
7819
|
cwd: destination,
|
|
@@ -7553,9 +7821,9 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7553
7821
|
});
|
|
7554
7822
|
await fs7.promises.unlink(tarPath);
|
|
7555
7823
|
await fs7.promises.rmdir(tmpDir);
|
|
7556
|
-
console.log(
|
|
7824
|
+
console.log(chalk20.green(`\u2713 Extracted ${files.length} files`));
|
|
7557
7825
|
await writeStorageConfig(name, destination, type);
|
|
7558
|
-
console.log(
|
|
7826
|
+
console.log(chalk20.green(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7559
7827
|
return {
|
|
7560
7828
|
success: true,
|
|
7561
7829
|
fileCount: downloadInfo.fileCount,
|
|
@@ -7570,17 +7838,17 @@ var cloneCommand = new Command18().name("clone").description("Clone a remote vol
|
|
|
7570
7838
|
const targetDir = destination || name;
|
|
7571
7839
|
console.log(`Cloning volume: ${name}`);
|
|
7572
7840
|
const result = await cloneStorage(name, "volume", targetDir);
|
|
7573
|
-
console.log(
|
|
7841
|
+
console.log(chalk21.green(`
|
|
7574
7842
|
\u2713 Successfully cloned volume: ${name}`));
|
|
7575
|
-
console.log(
|
|
7576
|
-
console.log(
|
|
7843
|
+
console.log(chalk21.dim(` Location: ${targetDir}/`));
|
|
7844
|
+
console.log(chalk21.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7577
7845
|
} catch (error) {
|
|
7578
|
-
console.error(
|
|
7846
|
+
console.error(chalk21.red("\u2717 Clone failed"));
|
|
7579
7847
|
if (error instanceof Error) {
|
|
7580
7848
|
if (error.message.includes("Not authenticated")) {
|
|
7581
|
-
console.error(
|
|
7849
|
+
console.error(chalk21.dim(" Run: vm0 auth login"));
|
|
7582
7850
|
} else {
|
|
7583
|
-
console.error(
|
|
7851
|
+
console.error(chalk21.dim(` ${error.message}`));
|
|
7584
7852
|
}
|
|
7585
7853
|
}
|
|
7586
7854
|
process.exit(1);
|
|
@@ -7595,7 +7863,7 @@ import { Command as Command26 } from "commander";
|
|
|
7595
7863
|
|
|
7596
7864
|
// src/commands/artifact/init.ts
|
|
7597
7865
|
import { Command as Command20 } from "commander";
|
|
7598
|
-
import
|
|
7866
|
+
import chalk22 from "chalk";
|
|
7599
7867
|
import path9 from "path";
|
|
7600
7868
|
var initCommand2 = new Command20().name("init").description("Initialize an artifact in the current directory").option(
|
|
7601
7869
|
"-n, --name <name>",
|
|
@@ -7608,24 +7876,24 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7608
7876
|
if (existingConfig) {
|
|
7609
7877
|
if (existingConfig.type === "artifact") {
|
|
7610
7878
|
console.log(
|
|
7611
|
-
|
|
7879
|
+
chalk22.yellow(
|
|
7612
7880
|
`Artifact already initialized: ${existingConfig.name}`
|
|
7613
7881
|
)
|
|
7614
7882
|
);
|
|
7615
7883
|
} else {
|
|
7616
7884
|
console.log(
|
|
7617
|
-
|
|
7885
|
+
chalk22.yellow(
|
|
7618
7886
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
7619
7887
|
)
|
|
7620
7888
|
);
|
|
7621
7889
|
console.log(
|
|
7622
|
-
|
|
7890
|
+
chalk22.dim(
|
|
7623
7891
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
7624
7892
|
)
|
|
7625
7893
|
);
|
|
7626
7894
|
}
|
|
7627
7895
|
console.log(
|
|
7628
|
-
|
|
7896
|
+
chalk22.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7629
7897
|
);
|
|
7630
7898
|
return;
|
|
7631
7899
|
}
|
|
@@ -7634,10 +7902,10 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7634
7902
|
artifactName = options.name;
|
|
7635
7903
|
} else if (!isInteractive()) {
|
|
7636
7904
|
console.error(
|
|
7637
|
-
|
|
7905
|
+
chalk22.red("\u2717 --name flag is required in non-interactive mode")
|
|
7638
7906
|
);
|
|
7639
7907
|
console.error(
|
|
7640
|
-
|
|
7908
|
+
chalk22.dim(" Usage: vm0 artifact init --name <artifact-name>")
|
|
7641
7909
|
);
|
|
7642
7910
|
process.exit(1);
|
|
7643
7911
|
} else {
|
|
@@ -7653,34 +7921,34 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7653
7921
|
}
|
|
7654
7922
|
);
|
|
7655
7923
|
if (name === void 0) {
|
|
7656
|
-
console.log(
|
|
7924
|
+
console.log(chalk22.dim("Cancelled"));
|
|
7657
7925
|
return;
|
|
7658
7926
|
}
|
|
7659
7927
|
artifactName = name;
|
|
7660
7928
|
}
|
|
7661
7929
|
if (!isValidStorageName(artifactName)) {
|
|
7662
|
-
console.error(
|
|
7930
|
+
console.error(chalk22.red(`\u2717 Invalid artifact name: "${artifactName}"`));
|
|
7663
7931
|
console.error(
|
|
7664
|
-
|
|
7932
|
+
chalk22.dim(
|
|
7665
7933
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7666
7934
|
)
|
|
7667
7935
|
);
|
|
7668
7936
|
console.error(
|
|
7669
|
-
|
|
7937
|
+
chalk22.dim(" Example: my-project, user-workspace, code-artifact")
|
|
7670
7938
|
);
|
|
7671
7939
|
process.exit(1);
|
|
7672
7940
|
}
|
|
7673
7941
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
7674
|
-
console.log(
|
|
7942
|
+
console.log(chalk22.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
7675
7943
|
console.log(
|
|
7676
|
-
|
|
7944
|
+
chalk22.dim(
|
|
7677
7945
|
` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
7678
7946
|
)
|
|
7679
7947
|
);
|
|
7680
7948
|
} catch (error) {
|
|
7681
|
-
console.error(
|
|
7949
|
+
console.error(chalk22.red("\u2717 Failed to initialize artifact"));
|
|
7682
7950
|
if (error instanceof Error) {
|
|
7683
|
-
console.error(
|
|
7951
|
+
console.error(chalk22.dim(` ${error.message}`));
|
|
7684
7952
|
}
|
|
7685
7953
|
process.exit(1);
|
|
7686
7954
|
}
|
|
@@ -7688,7 +7956,7 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7688
7956
|
|
|
7689
7957
|
// src/commands/artifact/push.ts
|
|
7690
7958
|
import { Command as Command21 } from "commander";
|
|
7691
|
-
import
|
|
7959
|
+
import chalk23 from "chalk";
|
|
7692
7960
|
var pushCommand2 = new Command21().name("push").description("Push local files to cloud artifact").option(
|
|
7693
7961
|
"-f, --force",
|
|
7694
7962
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7697,41 +7965,41 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7697
7965
|
const cwd = process.cwd();
|
|
7698
7966
|
const config = await readStorageConfig(cwd);
|
|
7699
7967
|
if (!config) {
|
|
7700
|
-
console.error(
|
|
7701
|
-
console.error(
|
|
7968
|
+
console.error(chalk23.red("\u2717 No artifact initialized in this directory"));
|
|
7969
|
+
console.error(chalk23.dim(" Run: vm0 artifact init"));
|
|
7702
7970
|
process.exit(1);
|
|
7703
7971
|
}
|
|
7704
7972
|
if (config.type !== "artifact") {
|
|
7705
7973
|
console.error(
|
|
7706
|
-
|
|
7974
|
+
chalk23.red(
|
|
7707
7975
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7708
7976
|
)
|
|
7709
7977
|
);
|
|
7710
|
-
console.error(
|
|
7978
|
+
console.error(chalk23.dim(" Use: vm0 volume push"));
|
|
7711
7979
|
process.exit(1);
|
|
7712
7980
|
}
|
|
7713
7981
|
console.log(`Pushing artifact: ${config.name}`);
|
|
7714
7982
|
const result = await directUpload(config.name, "artifact", cwd, {
|
|
7715
7983
|
onProgress: (message) => {
|
|
7716
|
-
console.log(
|
|
7984
|
+
console.log(chalk23.dim(message));
|
|
7717
7985
|
},
|
|
7718
7986
|
force: options.force
|
|
7719
7987
|
});
|
|
7720
7988
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7721
7989
|
if (result.empty) {
|
|
7722
|
-
console.log(
|
|
7990
|
+
console.log(chalk23.dim("No files found (empty artifact)"));
|
|
7723
7991
|
} else if (result.deduplicated) {
|
|
7724
|
-
console.log(
|
|
7992
|
+
console.log(chalk23.green("\u2713 Content unchanged (deduplicated)"));
|
|
7725
7993
|
} else {
|
|
7726
|
-
console.log(
|
|
7994
|
+
console.log(chalk23.green("\u2713 Upload complete"));
|
|
7727
7995
|
}
|
|
7728
|
-
console.log(
|
|
7729
|
-
console.log(
|
|
7730
|
-
console.log(
|
|
7996
|
+
console.log(chalk23.dim(` Version: ${shortVersion}`));
|
|
7997
|
+
console.log(chalk23.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7998
|
+
console.log(chalk23.dim(` Size: ${formatBytes(result.size)}`));
|
|
7731
7999
|
} catch (error) {
|
|
7732
|
-
console.error(
|
|
8000
|
+
console.error(chalk23.red("\u2717 Push failed"));
|
|
7733
8001
|
if (error instanceof Error) {
|
|
7734
|
-
console.error(
|
|
8002
|
+
console.error(chalk23.dim(` ${error.message}`));
|
|
7735
8003
|
}
|
|
7736
8004
|
process.exit(1);
|
|
7737
8005
|
}
|
|
@@ -7739,7 +8007,7 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7739
8007
|
|
|
7740
8008
|
// src/commands/artifact/pull.ts
|
|
7741
8009
|
import { Command as Command22 } from "commander";
|
|
7742
|
-
import
|
|
8010
|
+
import chalk24 from "chalk";
|
|
7743
8011
|
import path10 from "path";
|
|
7744
8012
|
import * as fs8 from "fs";
|
|
7745
8013
|
import * as os6 from "os";
|
|
@@ -7749,17 +8017,17 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7749
8017
|
const cwd = process.cwd();
|
|
7750
8018
|
const config = await readStorageConfig(cwd);
|
|
7751
8019
|
if (!config) {
|
|
7752
|
-
console.error(
|
|
7753
|
-
console.error(
|
|
8020
|
+
console.error(chalk24.red("\u2717 No artifact initialized in this directory"));
|
|
8021
|
+
console.error(chalk24.dim(" Run: vm0 artifact init"));
|
|
7754
8022
|
process.exit(1);
|
|
7755
8023
|
}
|
|
7756
8024
|
if (config.type !== "artifact") {
|
|
7757
8025
|
console.error(
|
|
7758
|
-
|
|
8026
|
+
chalk24.red(
|
|
7759
8027
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7760
8028
|
)
|
|
7761
8029
|
);
|
|
7762
|
-
console.error(
|
|
8030
|
+
console.error(chalk24.dim(" Use: vm0 volume pull"));
|
|
7763
8031
|
process.exit(1);
|
|
7764
8032
|
}
|
|
7765
8033
|
if (versionId) {
|
|
@@ -7767,7 +8035,7 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7767
8035
|
} else {
|
|
7768
8036
|
console.log(`Pulling artifact: ${config.name}`);
|
|
7769
8037
|
}
|
|
7770
|
-
console.log(
|
|
8038
|
+
console.log(chalk24.dim("Getting download URL..."));
|
|
7771
8039
|
const downloadInfo = await getStorageDownload({
|
|
7772
8040
|
name: config.name,
|
|
7773
8041
|
type: "artifact",
|
|
@@ -7781,18 +8049,18 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7781
8049
|
if (!downloadUrl) {
|
|
7782
8050
|
throw new Error("No download URL returned");
|
|
7783
8051
|
}
|
|
7784
|
-
console.log(
|
|
8052
|
+
console.log(chalk24.dim("Downloading from S3..."));
|
|
7785
8053
|
const s3Response = await fetch(downloadUrl);
|
|
7786
8054
|
if (!s3Response.ok) {
|
|
7787
8055
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7788
8056
|
}
|
|
7789
8057
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7790
8058
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7791
|
-
console.log(
|
|
8059
|
+
console.log(chalk24.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7792
8060
|
const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
|
|
7793
8061
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
7794
8062
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
7795
|
-
console.log(
|
|
8063
|
+
console.log(chalk24.dim("Syncing local files..."));
|
|
7796
8064
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7797
8065
|
const remoteFilesSet = new Set(
|
|
7798
8066
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7800,10 +8068,10 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7800
8068
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7801
8069
|
if (removedCount > 0) {
|
|
7802
8070
|
console.log(
|
|
7803
|
-
|
|
8071
|
+
chalk24.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7804
8072
|
);
|
|
7805
8073
|
}
|
|
7806
|
-
console.log(
|
|
8074
|
+
console.log(chalk24.dim("Extracting files..."));
|
|
7807
8075
|
await tar5.extract({
|
|
7808
8076
|
file: tarPath,
|
|
7809
8077
|
cwd,
|
|
@@ -7811,11 +8079,11 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7811
8079
|
});
|
|
7812
8080
|
await fs8.promises.unlink(tarPath);
|
|
7813
8081
|
await fs8.promises.rmdir(tmpDir);
|
|
7814
|
-
console.log(
|
|
8082
|
+
console.log(chalk24.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7815
8083
|
} catch (error) {
|
|
7816
|
-
console.error(
|
|
8084
|
+
console.error(chalk24.red("\u2717 Pull failed"));
|
|
7817
8085
|
if (error instanceof Error) {
|
|
7818
|
-
console.error(
|
|
8086
|
+
console.error(chalk24.dim(` ${error.message}`));
|
|
7819
8087
|
}
|
|
7820
8088
|
process.exit(1);
|
|
7821
8089
|
}
|
|
@@ -7823,23 +8091,23 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7823
8091
|
|
|
7824
8092
|
// src/commands/artifact/status.ts
|
|
7825
8093
|
import { Command as Command23 } from "commander";
|
|
7826
|
-
import
|
|
8094
|
+
import chalk25 from "chalk";
|
|
7827
8095
|
var statusCommand3 = new Command23().name("status").description("Show status of cloud artifact").action(async () => {
|
|
7828
8096
|
try {
|
|
7829
8097
|
const cwd = process.cwd();
|
|
7830
8098
|
const config = await readStorageConfig(cwd);
|
|
7831
8099
|
if (!config) {
|
|
7832
|
-
console.error(
|
|
7833
|
-
console.error(
|
|
8100
|
+
console.error(chalk25.red("\u2717 No artifact initialized in this directory"));
|
|
8101
|
+
console.error(chalk25.dim(" Run: vm0 artifact init"));
|
|
7834
8102
|
process.exit(1);
|
|
7835
8103
|
}
|
|
7836
8104
|
if (config.type !== "artifact") {
|
|
7837
8105
|
console.error(
|
|
7838
|
-
|
|
8106
|
+
chalk25.red(
|
|
7839
8107
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
7840
8108
|
)
|
|
7841
8109
|
);
|
|
7842
|
-
console.error(
|
|
8110
|
+
console.error(chalk25.dim(" Use: vm0 volume status"));
|
|
7843
8111
|
process.exit(1);
|
|
7844
8112
|
}
|
|
7845
8113
|
console.log(`Checking artifact: ${config.name}`);
|
|
@@ -7849,22 +8117,22 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7849
8117
|
});
|
|
7850
8118
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7851
8119
|
if ("empty" in info) {
|
|
7852
|
-
console.log(
|
|
7853
|
-
console.log(
|
|
8120
|
+
console.log(chalk25.green("\u2713 Found (empty)"));
|
|
8121
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
7854
8122
|
} else {
|
|
7855
|
-
console.log(
|
|
7856
|
-
console.log(
|
|
7857
|
-
console.log(
|
|
7858
|
-
console.log(
|
|
8123
|
+
console.log(chalk25.green("\u2713 Found"));
|
|
8124
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
8125
|
+
console.log(chalk25.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
8126
|
+
console.log(chalk25.dim(` Size: ${formatBytes(info.size)}`));
|
|
7859
8127
|
}
|
|
7860
8128
|
} catch (error) {
|
|
7861
8129
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7862
|
-
console.error(
|
|
7863
|
-
console.error(
|
|
8130
|
+
console.error(chalk25.red("\u2717 Not found on remote"));
|
|
8131
|
+
console.error(chalk25.dim(" Run: vm0 artifact push"));
|
|
7864
8132
|
} else {
|
|
7865
|
-
console.error(
|
|
8133
|
+
console.error(chalk25.red("\u2717 Status check failed"));
|
|
7866
8134
|
if (error instanceof Error) {
|
|
7867
|
-
console.error(
|
|
8135
|
+
console.error(chalk25.dim(` ${error.message}`));
|
|
7868
8136
|
}
|
|
7869
8137
|
}
|
|
7870
8138
|
process.exit(1);
|
|
@@ -7873,14 +8141,14 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7873
8141
|
|
|
7874
8142
|
// src/commands/artifact/list.ts
|
|
7875
8143
|
import { Command as Command24 } from "commander";
|
|
7876
|
-
import
|
|
8144
|
+
import chalk26 from "chalk";
|
|
7877
8145
|
var listCommand3 = new Command24().name("list").alias("ls").description("List all remote artifacts").action(async () => {
|
|
7878
8146
|
try {
|
|
7879
8147
|
const items = await listStorages({ type: "artifact" });
|
|
7880
8148
|
if (items.length === 0) {
|
|
7881
|
-
console.log(
|
|
8149
|
+
console.log(chalk26.dim("No artifacts found"));
|
|
7882
8150
|
console.log(
|
|
7883
|
-
|
|
8151
|
+
chalk26.dim(
|
|
7884
8152
|
" Create one with: vm0 artifact init && vm0 artifact push"
|
|
7885
8153
|
)
|
|
7886
8154
|
);
|
|
@@ -7901,7 +8169,7 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7901
8169
|
"FILES".padStart(filesWidth),
|
|
7902
8170
|
"UPDATED"
|
|
7903
8171
|
].join(" ");
|
|
7904
|
-
console.log(
|
|
8172
|
+
console.log(chalk26.dim(header));
|
|
7905
8173
|
for (const item of items) {
|
|
7906
8174
|
const row = [
|
|
7907
8175
|
item.name.padEnd(nameWidth),
|
|
@@ -7912,12 +8180,12 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7912
8180
|
console.log(row);
|
|
7913
8181
|
}
|
|
7914
8182
|
} catch (error) {
|
|
7915
|
-
console.error(
|
|
8183
|
+
console.error(chalk26.red("\u2717 Failed to list artifacts"));
|
|
7916
8184
|
if (error instanceof Error) {
|
|
7917
8185
|
if (error.message.includes("Not authenticated")) {
|
|
7918
|
-
console.error(
|
|
8186
|
+
console.error(chalk26.dim(" Run: vm0 auth login"));
|
|
7919
8187
|
} else {
|
|
7920
|
-
console.error(
|
|
8188
|
+
console.error(chalk26.dim(` ${error.message}`));
|
|
7921
8189
|
}
|
|
7922
8190
|
}
|
|
7923
8191
|
process.exit(1);
|
|
@@ -7926,23 +8194,23 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7926
8194
|
|
|
7927
8195
|
// src/commands/artifact/clone.ts
|
|
7928
8196
|
import { Command as Command25 } from "commander";
|
|
7929
|
-
import
|
|
8197
|
+
import chalk27 from "chalk";
|
|
7930
8198
|
var cloneCommand2 = new Command25().name("clone").description("Clone a remote artifact to local directory (latest version)").argument("<name>", "Artifact name to clone").argument("[destination]", "Destination directory (default: artifact name)").action(async (name, destination) => {
|
|
7931
8199
|
try {
|
|
7932
8200
|
const targetDir = destination || name;
|
|
7933
8201
|
console.log(`Cloning artifact: ${name}`);
|
|
7934
8202
|
const result = await cloneStorage(name, "artifact", targetDir);
|
|
7935
|
-
console.log(
|
|
8203
|
+
console.log(chalk27.green(`
|
|
7936
8204
|
\u2713 Successfully cloned artifact: ${name}`));
|
|
7937
|
-
console.log(
|
|
7938
|
-
console.log(
|
|
8205
|
+
console.log(chalk27.dim(` Location: ${targetDir}/`));
|
|
8206
|
+
console.log(chalk27.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7939
8207
|
} catch (error) {
|
|
7940
|
-
console.error(
|
|
8208
|
+
console.error(chalk27.red("\u2717 Clone failed"));
|
|
7941
8209
|
if (error instanceof Error) {
|
|
7942
8210
|
if (error.message.includes("Not authenticated")) {
|
|
7943
|
-
console.error(
|
|
8211
|
+
console.error(chalk27.dim(" Run: vm0 auth login"));
|
|
7944
8212
|
} else {
|
|
7945
|
-
console.error(
|
|
8213
|
+
console.error(chalk27.dim(` ${error.message}`));
|
|
7946
8214
|
}
|
|
7947
8215
|
}
|
|
7948
8216
|
process.exit(1);
|
|
@@ -7953,7 +8221,7 @@ var cloneCommand2 = new Command25().name("clone").description("Clone a remote ar
|
|
|
7953
8221
|
var artifactCommand = new Command26().name("artifact").description("Manage artifacts (specified at run, versioned after run)").addCommand(initCommand2).addCommand(pushCommand2).addCommand(pullCommand2).addCommand(statusCommand3).addCommand(listCommand3).addCommand(cloneCommand2);
|
|
7954
8222
|
|
|
7955
8223
|
// src/commands/cook/cook.ts
|
|
7956
|
-
import { Command as Command27, Option as
|
|
8224
|
+
import { Command as Command27, Option as Option5 } from "commander";
|
|
7957
8225
|
import chalk29 from "chalk";
|
|
7958
8226
|
import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
|
|
7959
8227
|
import { existsSync as existsSync9 } from "fs";
|
|
@@ -7961,145 +8229,6 @@ import path11 from "path";
|
|
|
7961
8229
|
import { parse as parseYaml4 } from "yaml";
|
|
7962
8230
|
import { config as dotenvConfig2 } from "dotenv";
|
|
7963
8231
|
|
|
7964
|
-
// src/lib/utils/update-checker.ts
|
|
7965
|
-
import { spawn } from "child_process";
|
|
7966
|
-
import chalk27 from "chalk";
|
|
7967
|
-
var PACKAGE_NAME = "@vm0/cli";
|
|
7968
|
-
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
7969
|
-
var TIMEOUT_MS = 5e3;
|
|
7970
|
-
function detectPackageManager() {
|
|
7971
|
-
const execPath = process.argv[1] ?? "";
|
|
7972
|
-
if (execPath.includes("pnpm")) {
|
|
7973
|
-
return "pnpm";
|
|
7974
|
-
}
|
|
7975
|
-
if (execPath.includes("/.bun/") || execPath.includes("/bun/")) {
|
|
7976
|
-
return "bun";
|
|
7977
|
-
}
|
|
7978
|
-
if (execPath.includes("/.yarn/") || execPath.includes("/yarn/")) {
|
|
7979
|
-
return "yarn";
|
|
7980
|
-
}
|
|
7981
|
-
if (execPath.includes("/usr/local/") || execPath.includes("/.nvm/") || execPath.includes("/.fnm/") || execPath.includes("/.volta/") || execPath.includes("/.nodenv/") || execPath.includes("/.n/") || execPath.includes("/node_modules/") || execPath.includes("\\npm\\") || // Windows: AppData\Roaming\npm
|
|
7982
|
-
execPath.includes("\\nodejs\\")) {
|
|
7983
|
-
return "npm";
|
|
7984
|
-
}
|
|
7985
|
-
return "unknown";
|
|
7986
|
-
}
|
|
7987
|
-
function isAutoUpgradeSupported(pm) {
|
|
7988
|
-
return pm === "npm" || pm === "pnpm";
|
|
7989
|
-
}
|
|
7990
|
-
function getManualUpgradeCommand(pm) {
|
|
7991
|
-
switch (pm) {
|
|
7992
|
-
case "bun":
|
|
7993
|
-
return `bun add -g ${PACKAGE_NAME}@latest`;
|
|
7994
|
-
case "yarn":
|
|
7995
|
-
return `yarn global add ${PACKAGE_NAME}@latest`;
|
|
7996
|
-
case "pnpm":
|
|
7997
|
-
return `pnpm add -g ${PACKAGE_NAME}@latest`;
|
|
7998
|
-
case "npm":
|
|
7999
|
-
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
8000
|
-
case "unknown":
|
|
8001
|
-
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
8002
|
-
}
|
|
8003
|
-
}
|
|
8004
|
-
function escapeForShell(str) {
|
|
8005
|
-
return `"${str.replace(/"/g, '\\"')}"`;
|
|
8006
|
-
}
|
|
8007
|
-
function buildRerunCommand(prompt) {
|
|
8008
|
-
if (prompt) {
|
|
8009
|
-
return `vm0 cook ${escapeForShell(prompt)}`;
|
|
8010
|
-
}
|
|
8011
|
-
return "vm0 cook";
|
|
8012
|
-
}
|
|
8013
|
-
async function getLatestVersion() {
|
|
8014
|
-
try {
|
|
8015
|
-
const controller = new AbortController();
|
|
8016
|
-
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
8017
|
-
const response = await fetch(NPM_REGISTRY_URL, {
|
|
8018
|
-
signal: controller.signal
|
|
8019
|
-
});
|
|
8020
|
-
clearTimeout(timeoutId);
|
|
8021
|
-
if (!response.ok) {
|
|
8022
|
-
return null;
|
|
8023
|
-
}
|
|
8024
|
-
const json = await response.json();
|
|
8025
|
-
return json.version ?? null;
|
|
8026
|
-
} catch {
|
|
8027
|
-
return null;
|
|
8028
|
-
}
|
|
8029
|
-
}
|
|
8030
|
-
function performUpgrade(packageManager) {
|
|
8031
|
-
return new Promise((resolve) => {
|
|
8032
|
-
const isWindows = process.platform === "win32";
|
|
8033
|
-
const command = isWindows ? `${packageManager}.cmd` : packageManager;
|
|
8034
|
-
const args = packageManager === "pnpm" ? ["add", "-g", `${PACKAGE_NAME}@latest`] : ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
8035
|
-
const child = spawn(command, args, {
|
|
8036
|
-
stdio: "inherit",
|
|
8037
|
-
shell: isWindows
|
|
8038
|
-
});
|
|
8039
|
-
child.on("close", (code) => {
|
|
8040
|
-
resolve(code === 0);
|
|
8041
|
-
});
|
|
8042
|
-
child.on("error", () => {
|
|
8043
|
-
resolve(false);
|
|
8044
|
-
});
|
|
8045
|
-
});
|
|
8046
|
-
}
|
|
8047
|
-
async function checkAndUpgrade(currentVersion, prompt) {
|
|
8048
|
-
const latestVersion = await getLatestVersion();
|
|
8049
|
-
if (latestVersion === null) {
|
|
8050
|
-
console.log(chalk27.yellow("Warning: Could not check for updates"));
|
|
8051
|
-
console.log();
|
|
8052
|
-
return false;
|
|
8053
|
-
}
|
|
8054
|
-
if (latestVersion === currentVersion) {
|
|
8055
|
-
return false;
|
|
8056
|
-
}
|
|
8057
|
-
console.log(chalk27.yellow("vm0 is currently in Early Access (EA)."));
|
|
8058
|
-
console.log(
|
|
8059
|
-
chalk27.yellow(
|
|
8060
|
-
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
8061
|
-
)
|
|
8062
|
-
);
|
|
8063
|
-
console.log(
|
|
8064
|
-
chalk27.yellow(
|
|
8065
|
-
"Please always use the latest version for best compatibility."
|
|
8066
|
-
)
|
|
8067
|
-
);
|
|
8068
|
-
console.log();
|
|
8069
|
-
const packageManager = detectPackageManager();
|
|
8070
|
-
if (!isAutoUpgradeSupported(packageManager)) {
|
|
8071
|
-
if (packageManager === "unknown") {
|
|
8072
|
-
console.log(
|
|
8073
|
-
chalk27.yellow("Could not detect your package manager for auto-upgrade.")
|
|
8074
|
-
);
|
|
8075
|
-
} else {
|
|
8076
|
-
console.log(
|
|
8077
|
-
chalk27.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
|
|
8078
|
-
);
|
|
8079
|
-
}
|
|
8080
|
-
console.log(chalk27.yellow("Please upgrade manually:"));
|
|
8081
|
-
console.log(chalk27.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
8082
|
-
console.log();
|
|
8083
|
-
return false;
|
|
8084
|
-
}
|
|
8085
|
-
console.log(`Upgrading via ${packageManager}...`);
|
|
8086
|
-
const success = await performUpgrade(packageManager);
|
|
8087
|
-
if (success) {
|
|
8088
|
-
console.log(chalk27.green(`Upgraded to ${latestVersion}`));
|
|
8089
|
-
console.log();
|
|
8090
|
-
console.log("To continue, run:");
|
|
8091
|
-
console.log(chalk27.cyan(` ${buildRerunCommand(prompt)}`));
|
|
8092
|
-
return true;
|
|
8093
|
-
}
|
|
8094
|
-
console.log();
|
|
8095
|
-
console.log(chalk27.red("Upgrade failed. Please run manually:"));
|
|
8096
|
-
console.log(chalk27.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
8097
|
-
console.log();
|
|
8098
|
-
console.log("Then re-run:");
|
|
8099
|
-
console.log(chalk27.cyan(` ${buildRerunCommand(prompt)}`));
|
|
8100
|
-
return true;
|
|
8101
|
-
}
|
|
8102
|
-
|
|
8103
8232
|
// src/lib/domain/cook-state.ts
|
|
8104
8233
|
import { homedir as homedir2 } from "os";
|
|
8105
8234
|
import { join as join6 } from "path";
|
|
@@ -8498,10 +8627,10 @@ async function runAgent(agentName, artifactDir, prompt, cwd, options) {
|
|
|
8498
8627
|
var cookAction = new Command27().name("cook").description("Quick start: prepare, compose and run agent from vm0.yaml").argument("[prompt]", "Prompt for the agent").option(
|
|
8499
8628
|
"--env-file <path>",
|
|
8500
8629
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8501
|
-
).option("-y, --yes", "Skip confirmation prompts").option("-v, --verbose", "Show full tool inputs and outputs").addOption(new
|
|
8630
|
+
).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(
|
|
8502
8631
|
async (prompt, options) => {
|
|
8503
8632
|
if (!options.noAutoUpdate) {
|
|
8504
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
8633
|
+
const shouldExit = await checkAndUpgrade("9.13.0", prompt);
|
|
8505
8634
|
if (shouldExit) {
|
|
8506
8635
|
process.exit(0);
|
|
8507
8636
|
}
|
|
@@ -8577,7 +8706,7 @@ var logsCommand = new Command28().name("logs").description("View logs from the l
|
|
|
8577
8706
|
);
|
|
8578
8707
|
|
|
8579
8708
|
// src/commands/cook/continue.ts
|
|
8580
|
-
import { Command as Command29, Option as
|
|
8709
|
+
import { Command as Command29, Option as Option6 } from "commander";
|
|
8581
8710
|
import chalk31 from "chalk";
|
|
8582
8711
|
import path12 from "path";
|
|
8583
8712
|
var continueCommand2 = new Command29().name("continue").description(
|
|
@@ -8585,7 +8714,7 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8585
8714
|
).argument("<prompt>", "Prompt for the continued agent").option(
|
|
8586
8715
|
"--env-file <path>",
|
|
8587
8716
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8588
|
-
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new
|
|
8717
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option6("--debug-no-mock-claude").hideHelp()).action(
|
|
8589
8718
|
async (prompt, options) => {
|
|
8590
8719
|
const state = await loadCookState();
|
|
8591
8720
|
if (!state.lastSessionId) {
|
|
@@ -8630,7 +8759,7 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8630
8759
|
);
|
|
8631
8760
|
|
|
8632
8761
|
// src/commands/cook/resume.ts
|
|
8633
|
-
import { Command as Command30, Option as
|
|
8762
|
+
import { Command as Command30, Option as Option7 } from "commander";
|
|
8634
8763
|
import chalk32 from "chalk";
|
|
8635
8764
|
import path13 from "path";
|
|
8636
8765
|
var resumeCommand2 = new Command30().name("resume").description(
|
|
@@ -8638,7 +8767,7 @@ var resumeCommand2 = new Command30().name("resume").description(
|
|
|
8638
8767
|
).argument("<prompt>", "Prompt for the resumed agent").option(
|
|
8639
8768
|
"--env-file <path>",
|
|
8640
8769
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8641
|
-
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new
|
|
8770
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option7("--debug-no-mock-claude").hideHelp()).action(
|
|
8642
8771
|
async (prompt, options) => {
|
|
8643
8772
|
const state = await loadCookState();
|
|
8644
8773
|
if (!state.lastCheckpointId) {
|
|
@@ -10910,12 +11039,6 @@ var listCommand7 = new Command51().name("list").alias("ls").description("List al
|
|
|
10910
11039
|
import { Command as Command52 } from "commander";
|
|
10911
11040
|
import chalk51 from "chalk";
|
|
10912
11041
|
import prompts2 from "prompts";
|
|
10913
|
-
var providerChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
10914
|
-
([type, config]) => ({
|
|
10915
|
-
title: config.label,
|
|
10916
|
-
value: type
|
|
10917
|
-
})
|
|
10918
|
-
);
|
|
10919
11042
|
function validateProviderType(typeStr) {
|
|
10920
11043
|
if (!Object.keys(MODEL_PROVIDER_TYPES).includes(typeStr)) {
|
|
10921
11044
|
console.error(chalk51.red(`\u2717 Invalid type "${typeStr}"`));
|
|
@@ -10947,7 +11070,8 @@ function handleNonInteractiveMode(options) {
|
|
|
10947
11070
|
if (options.model) {
|
|
10948
11071
|
selectedModel = validateModel(type, options.model);
|
|
10949
11072
|
} else if (hasModelSelection(type)) {
|
|
10950
|
-
|
|
11073
|
+
const defaultModel = getDefaultModel(type);
|
|
11074
|
+
selectedModel = defaultModel || void 0;
|
|
10951
11075
|
}
|
|
10952
11076
|
return { type, credential: options.credential, selectedModel };
|
|
10953
11077
|
}
|
|
@@ -10957,7 +11081,10 @@ async function promptForModelSelection(type) {
|
|
|
10957
11081
|
}
|
|
10958
11082
|
const models = getModels(type) ?? [];
|
|
10959
11083
|
const defaultModel = getDefaultModel(type);
|
|
10960
|
-
const modelChoices =
|
|
11084
|
+
const modelChoices = defaultModel === "" ? [
|
|
11085
|
+
{ title: "auto (Recommended)", value: "" },
|
|
11086
|
+
...models.map((model) => ({ title: model, value: model }))
|
|
11087
|
+
] : models.map((model) => ({
|
|
10961
11088
|
title: model === defaultModel ? `${model} (Recommended)` : model,
|
|
10962
11089
|
value: model
|
|
10963
11090
|
}));
|
|
@@ -10970,7 +11097,8 @@ async function promptForModelSelection(type) {
|
|
|
10970
11097
|
},
|
|
10971
11098
|
{ onCancel: () => process.exit(0) }
|
|
10972
11099
|
);
|
|
10973
|
-
|
|
11100
|
+
const selected = modelResponse.model;
|
|
11101
|
+
return selected === "" ? void 0 : selected;
|
|
10974
11102
|
}
|
|
10975
11103
|
async function handleInteractiveMode() {
|
|
10976
11104
|
if (!isInteractive()) {
|
|
@@ -10984,12 +11112,20 @@ async function handleInteractiveMode() {
|
|
|
10984
11112
|
);
|
|
10985
11113
|
process.exit(1);
|
|
10986
11114
|
}
|
|
11115
|
+
const { modelProviders: configuredProviders } = await listModelProviders();
|
|
11116
|
+
const configuredTypes = new Set(configuredProviders.map((p) => p.type));
|
|
11117
|
+
const annotatedChoices = Object.entries(MODEL_PROVIDER_TYPES).map(
|
|
11118
|
+
([type2, config2]) => ({
|
|
11119
|
+
title: configuredTypes.has(type2) ? `${config2.label} \u2713` : config2.label,
|
|
11120
|
+
value: type2
|
|
11121
|
+
})
|
|
11122
|
+
);
|
|
10987
11123
|
const typeResponse = await prompts2(
|
|
10988
11124
|
{
|
|
10989
11125
|
type: "select",
|
|
10990
11126
|
name: "type",
|
|
10991
11127
|
message: "Select provider type:",
|
|
10992
|
-
choices:
|
|
11128
|
+
choices: annotatedChoices
|
|
10993
11129
|
},
|
|
10994
11130
|
{ onCancel: () => process.exit(0) }
|
|
10995
11131
|
);
|
|
@@ -11018,6 +11154,27 @@ async function handleInteractiveMode() {
|
|
|
11018
11154
|
console.log(chalk51.dim("Aborted"));
|
|
11019
11155
|
process.exit(0);
|
|
11020
11156
|
}
|
|
11157
|
+
if (checkResult.exists && checkResult.currentType === "model-provider") {
|
|
11158
|
+
console.log();
|
|
11159
|
+
console.log(`"${type}" is already configured.`);
|
|
11160
|
+
console.log();
|
|
11161
|
+
const actionResponse = await prompts2(
|
|
11162
|
+
{
|
|
11163
|
+
type: "select",
|
|
11164
|
+
name: "action",
|
|
11165
|
+
message: "",
|
|
11166
|
+
choices: [
|
|
11167
|
+
{ title: "Keep existing credential", value: "keep" },
|
|
11168
|
+
{ title: "Update credential", value: "update" }
|
|
11169
|
+
]
|
|
11170
|
+
},
|
|
11171
|
+
{ onCancel: () => process.exit(0) }
|
|
11172
|
+
);
|
|
11173
|
+
if (actionResponse.action === "keep") {
|
|
11174
|
+
const selectedModel2 = await promptForModelSelection(type);
|
|
11175
|
+
return { type, keepExistingCredential: true, selectedModel: selectedModel2 };
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11021
11178
|
const config = MODEL_PROVIDER_TYPES[type];
|
|
11022
11179
|
console.log();
|
|
11023
11180
|
console.log(chalk51.dim(config.helpText));
|
|
@@ -11078,6 +11235,26 @@ var setupCommand2 = new Command52().name("setup").description("Configure a model
|
|
|
11078
11235
|
}
|
|
11079
11236
|
input = result;
|
|
11080
11237
|
}
|
|
11238
|
+
if (input.keepExistingCredential) {
|
|
11239
|
+
const provider2 = await updateModelProviderModel(
|
|
11240
|
+
input.type,
|
|
11241
|
+
input.selectedModel
|
|
11242
|
+
);
|
|
11243
|
+
const defaultNote2 = provider2.isDefault ? ` (default for ${provider2.framework})` : "";
|
|
11244
|
+
const modelNote2 = provider2.selectedModel ? ` with model: ${provider2.selectedModel}` : "";
|
|
11245
|
+
if (!hasModelSelection(input.type)) {
|
|
11246
|
+
console.log(
|
|
11247
|
+
chalk51.green(`\u2713 Model provider "${input.type}" unchanged`)
|
|
11248
|
+
);
|
|
11249
|
+
} else {
|
|
11250
|
+
console.log(
|
|
11251
|
+
chalk51.green(
|
|
11252
|
+
`\u2713 Model provider "${input.type}" updated${defaultNote2}${modelNote2}`
|
|
11253
|
+
)
|
|
11254
|
+
);
|
|
11255
|
+
}
|
|
11256
|
+
return;
|
|
11257
|
+
}
|
|
11081
11258
|
const { provider, created } = await upsertModelProvider({
|
|
11082
11259
|
type: input.type,
|
|
11083
11260
|
credential: input.credential,
|
|
@@ -11612,19 +11789,24 @@ async function handleModelProvider(ctx) {
|
|
|
11612
11789
|
}
|
|
11613
11790
|
let selectedModel;
|
|
11614
11791
|
if (selectedChoice?.models && selectedChoice.models.length > 0) {
|
|
11615
|
-
|
|
11616
|
-
()
|
|
11617
|
-
|
|
11618
|
-
|
|
11619
|
-
|
|
11620
|
-
|
|
11621
|
-
|
|
11622
|
-
)
|
|
11792
|
+
const modelChoices = selectedChoice.defaultModel === "" ? [
|
|
11793
|
+
{ title: "auto (Recommended)", value: "" },
|
|
11794
|
+
...selectedChoice.models.map((model) => ({
|
|
11795
|
+
title: model,
|
|
11796
|
+
value: model
|
|
11797
|
+
}))
|
|
11798
|
+
] : selectedChoice.models.map((model) => ({
|
|
11799
|
+
title: model === selectedChoice.defaultModel ? `${model} (Recommended)` : model,
|
|
11800
|
+
value: model
|
|
11801
|
+
}));
|
|
11802
|
+
const modelSelection = await step.prompt(
|
|
11803
|
+
() => promptSelect("Select model:", modelChoices)
|
|
11623
11804
|
);
|
|
11624
|
-
if (
|
|
11805
|
+
if (modelSelection === void 0) {
|
|
11625
11806
|
console.log(chalk57.dim("Cancelled"));
|
|
11626
11807
|
process.exit(0);
|
|
11627
11808
|
}
|
|
11809
|
+
selectedModel = modelSelection === "" ? void 0 : modelSelection;
|
|
11628
11810
|
}
|
|
11629
11811
|
const result = await setupModelProvider(providerType, credential, {
|
|
11630
11812
|
selectedModel
|
|
@@ -11780,7 +11962,7 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11780
11962
|
|
|
11781
11963
|
// src/index.ts
|
|
11782
11964
|
var program = new Command58();
|
|
11783
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
11965
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.13.0");
|
|
11784
11966
|
program.addCommand(authCommand);
|
|
11785
11967
|
program.addCommand(infoCommand);
|
|
11786
11968
|
program.addCommand(composeCommand);
|