@vm0/cli 9.11.0 → 9.12.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 +564 -514
- 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";
|
|
@@ -4411,6 +4411,188 @@ async function promptPassword(message) {
|
|
|
4411
4411
|
return response.value;
|
|
4412
4412
|
}
|
|
4413
4413
|
|
|
4414
|
+
// src/lib/utils/update-checker.ts
|
|
4415
|
+
import { spawn } from "child_process";
|
|
4416
|
+
import chalk3 from "chalk";
|
|
4417
|
+
var PACKAGE_NAME = "@vm0/cli";
|
|
4418
|
+
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
4419
|
+
var TIMEOUT_MS = 5e3;
|
|
4420
|
+
function detectPackageManager() {
|
|
4421
|
+
const execPath = process.argv[1] ?? "";
|
|
4422
|
+
if (execPath.includes("pnpm")) {
|
|
4423
|
+
return "pnpm";
|
|
4424
|
+
}
|
|
4425
|
+
if (execPath.includes("/.bun/") || execPath.includes("/bun/")) {
|
|
4426
|
+
return "bun";
|
|
4427
|
+
}
|
|
4428
|
+
if (execPath.includes("/.yarn/") || execPath.includes("/yarn/")) {
|
|
4429
|
+
return "yarn";
|
|
4430
|
+
}
|
|
4431
|
+
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
|
|
4432
|
+
execPath.includes("\\nodejs\\")) {
|
|
4433
|
+
return "npm";
|
|
4434
|
+
}
|
|
4435
|
+
return "unknown";
|
|
4436
|
+
}
|
|
4437
|
+
function isAutoUpgradeSupported(pm) {
|
|
4438
|
+
return pm === "npm" || pm === "pnpm";
|
|
4439
|
+
}
|
|
4440
|
+
function getManualUpgradeCommand(pm) {
|
|
4441
|
+
switch (pm) {
|
|
4442
|
+
case "bun":
|
|
4443
|
+
return `bun add -g ${PACKAGE_NAME}@latest`;
|
|
4444
|
+
case "yarn":
|
|
4445
|
+
return `yarn global add ${PACKAGE_NAME}@latest`;
|
|
4446
|
+
case "pnpm":
|
|
4447
|
+
return `pnpm add -g ${PACKAGE_NAME}@latest`;
|
|
4448
|
+
case "npm":
|
|
4449
|
+
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
4450
|
+
case "unknown":
|
|
4451
|
+
return `npm install -g ${PACKAGE_NAME}@latest`;
|
|
4452
|
+
}
|
|
4453
|
+
}
|
|
4454
|
+
function escapeForShell(str) {
|
|
4455
|
+
return `"${str.replace(/"/g, '\\"')}"`;
|
|
4456
|
+
}
|
|
4457
|
+
function buildRerunCommand(prompt) {
|
|
4458
|
+
if (prompt) {
|
|
4459
|
+
return `vm0 cook ${escapeForShell(prompt)}`;
|
|
4460
|
+
}
|
|
4461
|
+
return "vm0 cook";
|
|
4462
|
+
}
|
|
4463
|
+
async function getLatestVersion() {
|
|
4464
|
+
try {
|
|
4465
|
+
const controller = new AbortController();
|
|
4466
|
+
const timeoutId = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
4467
|
+
const response = await fetch(NPM_REGISTRY_URL, {
|
|
4468
|
+
signal: controller.signal
|
|
4469
|
+
});
|
|
4470
|
+
clearTimeout(timeoutId);
|
|
4471
|
+
if (!response.ok) {
|
|
4472
|
+
return null;
|
|
4473
|
+
}
|
|
4474
|
+
const json = await response.json();
|
|
4475
|
+
return json.version ?? null;
|
|
4476
|
+
} catch {
|
|
4477
|
+
return null;
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
function performUpgrade(packageManager) {
|
|
4481
|
+
return new Promise((resolve) => {
|
|
4482
|
+
const isWindows = process.platform === "win32";
|
|
4483
|
+
const command = isWindows ? `${packageManager}.cmd` : packageManager;
|
|
4484
|
+
const args = packageManager === "pnpm" ? ["add", "-g", `${PACKAGE_NAME}@latest`] : ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
4485
|
+
const child = spawn(command, args, {
|
|
4486
|
+
stdio: "inherit",
|
|
4487
|
+
shell: isWindows
|
|
4488
|
+
});
|
|
4489
|
+
child.on("close", (code) => {
|
|
4490
|
+
resolve(code === 0);
|
|
4491
|
+
});
|
|
4492
|
+
child.on("error", () => {
|
|
4493
|
+
resolve(false);
|
|
4494
|
+
});
|
|
4495
|
+
});
|
|
4496
|
+
}
|
|
4497
|
+
async function checkAndUpgrade(currentVersion, prompt) {
|
|
4498
|
+
const latestVersion = await getLatestVersion();
|
|
4499
|
+
if (latestVersion === null) {
|
|
4500
|
+
console.log(chalk3.yellow("Warning: Could not check for updates"));
|
|
4501
|
+
console.log();
|
|
4502
|
+
return false;
|
|
4503
|
+
}
|
|
4504
|
+
if (latestVersion === currentVersion) {
|
|
4505
|
+
return false;
|
|
4506
|
+
}
|
|
4507
|
+
console.log(chalk3.yellow("vm0 is currently in beta."));
|
|
4508
|
+
console.log(
|
|
4509
|
+
chalk3.yellow(
|
|
4510
|
+
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
4511
|
+
)
|
|
4512
|
+
);
|
|
4513
|
+
console.log(
|
|
4514
|
+
chalk3.yellow(
|
|
4515
|
+
"Please always use the latest version for best compatibility."
|
|
4516
|
+
)
|
|
4517
|
+
);
|
|
4518
|
+
console.log();
|
|
4519
|
+
const packageManager = detectPackageManager();
|
|
4520
|
+
if (!isAutoUpgradeSupported(packageManager)) {
|
|
4521
|
+
if (packageManager === "unknown") {
|
|
4522
|
+
console.log(
|
|
4523
|
+
chalk3.yellow("Could not detect your package manager for auto-upgrade.")
|
|
4524
|
+
);
|
|
4525
|
+
} else {
|
|
4526
|
+
console.log(
|
|
4527
|
+
chalk3.yellow(`Auto-upgrade is not supported for ${packageManager}.`)
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4530
|
+
console.log(chalk3.yellow("Please upgrade manually:"));
|
|
4531
|
+
console.log(chalk3.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
4532
|
+
console.log();
|
|
4533
|
+
return false;
|
|
4534
|
+
}
|
|
4535
|
+
console.log(`Upgrading via ${packageManager}...`);
|
|
4536
|
+
const success = await performUpgrade(packageManager);
|
|
4537
|
+
if (success) {
|
|
4538
|
+
console.log(chalk3.green(`Upgraded to ${latestVersion}`));
|
|
4539
|
+
console.log();
|
|
4540
|
+
console.log("To continue, run:");
|
|
4541
|
+
console.log(chalk3.cyan(` ${buildRerunCommand(prompt)}`));
|
|
4542
|
+
return true;
|
|
4543
|
+
}
|
|
4544
|
+
console.log();
|
|
4545
|
+
console.log(chalk3.red("Upgrade failed. Please run manually:"));
|
|
4546
|
+
console.log(chalk3.cyan(` ${getManualUpgradeCommand(packageManager)}`));
|
|
4547
|
+
console.log();
|
|
4548
|
+
console.log("Then re-run:");
|
|
4549
|
+
console.log(chalk3.cyan(` ${buildRerunCommand(prompt)}`));
|
|
4550
|
+
return true;
|
|
4551
|
+
}
|
|
4552
|
+
async function silentUpgradeAfterCommand(currentVersion) {
|
|
4553
|
+
const latestVersion = await getLatestVersion();
|
|
4554
|
+
if (latestVersion === null || latestVersion === currentVersion) {
|
|
4555
|
+
return;
|
|
4556
|
+
}
|
|
4557
|
+
const packageManager = detectPackageManager();
|
|
4558
|
+
if (!isAutoUpgradeSupported(packageManager)) {
|
|
4559
|
+
return;
|
|
4560
|
+
}
|
|
4561
|
+
const isWindows = process.platform === "win32";
|
|
4562
|
+
const command = isWindows ? `${packageManager}.cmd` : packageManager;
|
|
4563
|
+
const args = packageManager === "pnpm" ? ["add", "-g", `${PACKAGE_NAME}@latest`] : ["install", "-g", `${PACKAGE_NAME}@latest`];
|
|
4564
|
+
const upgradeResult = await new Promise((resolve) => {
|
|
4565
|
+
const child = spawn(command, args, {
|
|
4566
|
+
stdio: "pipe",
|
|
4567
|
+
// Capture output instead of inheriting
|
|
4568
|
+
shell: isWindows,
|
|
4569
|
+
detached: !isWindows,
|
|
4570
|
+
// Detach on non-Windows
|
|
4571
|
+
windowsHide: true
|
|
4572
|
+
});
|
|
4573
|
+
const timeoutId = setTimeout(() => {
|
|
4574
|
+
child.kill();
|
|
4575
|
+
resolve(false);
|
|
4576
|
+
}, TIMEOUT_MS);
|
|
4577
|
+
child.on("close", (code) => {
|
|
4578
|
+
clearTimeout(timeoutId);
|
|
4579
|
+
resolve(code === 0);
|
|
4580
|
+
});
|
|
4581
|
+
child.on("error", () => {
|
|
4582
|
+
clearTimeout(timeoutId);
|
|
4583
|
+
resolve(false);
|
|
4584
|
+
});
|
|
4585
|
+
});
|
|
4586
|
+
if (!upgradeResult) {
|
|
4587
|
+
console.log(
|
|
4588
|
+
chalk3.yellow(
|
|
4589
|
+
`
|
|
4590
|
+
\u26A0 vm0 auto upgrade failed. Please run: ${getManualUpgradeCommand(packageManager)}`
|
|
4591
|
+
)
|
|
4592
|
+
);
|
|
4593
|
+
}
|
|
4594
|
+
}
|
|
4595
|
+
|
|
4414
4596
|
// src/commands/compose/index.ts
|
|
4415
4597
|
function getSecretsFromComposeContent(content) {
|
|
4416
4598
|
const refs = extractVariableReferences(content);
|
|
@@ -4419,7 +4601,7 @@ function getSecretsFromComposeContent(content) {
|
|
|
4419
4601
|
}
|
|
4420
4602
|
async function loadAndValidateConfig(configFile) {
|
|
4421
4603
|
if (!existsSync3(configFile)) {
|
|
4422
|
-
console.error(
|
|
4604
|
+
console.error(chalk4.red(`\u2717 Config file not found: ${configFile}`));
|
|
4423
4605
|
process.exit(1);
|
|
4424
4606
|
}
|
|
4425
4607
|
const content = await readFile4(configFile, "utf8");
|
|
@@ -4427,15 +4609,15 @@ async function loadAndValidateConfig(configFile) {
|
|
|
4427
4609
|
try {
|
|
4428
4610
|
config = parseYaml2(content);
|
|
4429
4611
|
} catch (error) {
|
|
4430
|
-
console.error(
|
|
4612
|
+
console.error(chalk4.red("\u2717 Invalid YAML format"));
|
|
4431
4613
|
if (error instanceof Error) {
|
|
4432
|
-
console.error(
|
|
4614
|
+
console.error(chalk4.dim(` ${error.message}`));
|
|
4433
4615
|
}
|
|
4434
4616
|
process.exit(1);
|
|
4435
4617
|
}
|
|
4436
4618
|
const validation = validateAgentCompose(config);
|
|
4437
4619
|
if (!validation.valid) {
|
|
4438
|
-
console.error(
|
|
4620
|
+
console.error(chalk4.red(`\u2717 ${validation.error}`));
|
|
4439
4621
|
process.exit(1);
|
|
4440
4622
|
}
|
|
4441
4623
|
const cfg = config;
|
|
@@ -4452,13 +4634,13 @@ function checkLegacyImageFormat(config) {
|
|
|
4452
4634
|
const image = agentConfig.image;
|
|
4453
4635
|
if (image) {
|
|
4454
4636
|
console.log(
|
|
4455
|
-
|
|
4637
|
+
chalk4.yellow(
|
|
4456
4638
|
`\u26A0 Agent "${name}": 'image' field is deprecated. Use 'apps' field for pre-installed tools.`
|
|
4457
4639
|
)
|
|
4458
4640
|
);
|
|
4459
4641
|
const warning = getLegacySystemTemplateWarning(image);
|
|
4460
4642
|
if (warning) {
|
|
4461
|
-
console.log(
|
|
4643
|
+
console.log(chalk4.yellow(` ${warning}`));
|
|
4462
4644
|
}
|
|
4463
4645
|
}
|
|
4464
4646
|
}
|
|
@@ -4473,7 +4655,7 @@ async function uploadAssets(agentName, agent, basePath) {
|
|
|
4473
4655
|
agent.framework
|
|
4474
4656
|
);
|
|
4475
4657
|
console.log(
|
|
4476
|
-
|
|
4658
|
+
chalk4.green(
|
|
4477
4659
|
`\u2713 Instructions ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.versionId.slice(0, 8)}`
|
|
4478
4660
|
)
|
|
4479
4661
|
);
|
|
@@ -4482,11 +4664,11 @@ async function uploadAssets(agentName, agent, basePath) {
|
|
|
4482
4664
|
if (agent.skills && Array.isArray(agent.skills)) {
|
|
4483
4665
|
console.log(`Uploading ${agent.skills.length} skill(s)...`);
|
|
4484
4666
|
for (const skillUrl of agent.skills) {
|
|
4485
|
-
console.log(
|
|
4667
|
+
console.log(chalk4.dim(` Downloading: ${skillUrl}`));
|
|
4486
4668
|
const result = await uploadSkill(skillUrl);
|
|
4487
4669
|
skillResults.push(result);
|
|
4488
4670
|
console.log(
|
|
4489
|
-
|
|
4671
|
+
chalk4.green(
|
|
4490
4672
|
` \u2713 Skill ${result.action === "deduplicated" ? "(unchanged)" : "uploaded"}: ${result.skillName} (${result.versionId.slice(0, 8)})`
|
|
4491
4673
|
)
|
|
4492
4674
|
);
|
|
@@ -4537,19 +4719,19 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4537
4719
|
}
|
|
4538
4720
|
console.log();
|
|
4539
4721
|
console.log(
|
|
4540
|
-
|
|
4722
|
+
chalk4.bold("Skills require the following environment variables:")
|
|
4541
4723
|
);
|
|
4542
4724
|
console.log();
|
|
4543
4725
|
if (newSecrets.length > 0) {
|
|
4544
|
-
console.log(
|
|
4726
|
+
console.log(chalk4.cyan(" Secrets:"));
|
|
4545
4727
|
for (const [name, skills] of newSecrets) {
|
|
4546
4728
|
const isNew = trulyNewSecrets.includes(name);
|
|
4547
|
-
const newMarker = isNew ?
|
|
4729
|
+
const newMarker = isNew ? chalk4.yellow(" (new)") : "";
|
|
4548
4730
|
console.log(` ${name.padEnd(24)}${newMarker} <- ${skills.join(", ")}`);
|
|
4549
4731
|
}
|
|
4550
4732
|
}
|
|
4551
4733
|
if (newVars.length > 0) {
|
|
4552
|
-
console.log(
|
|
4734
|
+
console.log(chalk4.cyan(" Vars:"));
|
|
4553
4735
|
for (const [name, skills] of newVars) {
|
|
4554
4736
|
console.log(` ${name.padEnd(24)} <- ${skills.join(", ")}`);
|
|
4555
4737
|
}
|
|
@@ -4558,10 +4740,10 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4558
4740
|
if (trulyNewSecrets.length > 0 && !options.yes) {
|
|
4559
4741
|
if (!isInteractive()) {
|
|
4560
4742
|
console.error(
|
|
4561
|
-
|
|
4743
|
+
chalk4.red(`\u2717 New secrets detected: ${trulyNewSecrets.join(", ")}`)
|
|
4562
4744
|
);
|
|
4563
4745
|
console.error(
|
|
4564
|
-
|
|
4746
|
+
chalk4.dim(
|
|
4565
4747
|
" Use --yes flag to approve new secrets in non-interactive mode."
|
|
4566
4748
|
)
|
|
4567
4749
|
);
|
|
@@ -4572,7 +4754,7 @@ async function displayAndConfirmVariables(variables, options) {
|
|
|
4572
4754
|
true
|
|
4573
4755
|
);
|
|
4574
4756
|
if (!confirmed) {
|
|
4575
|
-
console.log(
|
|
4757
|
+
console.log(chalk4.yellow("Compose cancelled"));
|
|
4576
4758
|
return false;
|
|
4577
4759
|
}
|
|
4578
4760
|
}
|
|
@@ -4594,64 +4776,71 @@ function mergeSkillVariables(agent, variables) {
|
|
|
4594
4776
|
agent.environment = environment;
|
|
4595
4777
|
}
|
|
4596
4778
|
}
|
|
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"));
|
|
4779
|
+
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(
|
|
4780
|
+
async (configFile, options) => {
|
|
4781
|
+
try {
|
|
4782
|
+
const { config, agentName, agent, basePath } = await loadAndValidateConfig(configFile);
|
|
4783
|
+
checkLegacyImageFormat(config);
|
|
4784
|
+
const skillResults = await uploadAssets(agentName, agent, basePath);
|
|
4785
|
+
const environment = agent.environment || {};
|
|
4786
|
+
const variables = await collectSkillVariables(
|
|
4787
|
+
skillResults,
|
|
4788
|
+
environment,
|
|
4789
|
+
agentName
|
|
4790
|
+
);
|
|
4791
|
+
const confirmed = await displayAndConfirmVariables(variables, options);
|
|
4792
|
+
if (!confirmed) {
|
|
4793
|
+
process.exit(0);
|
|
4794
|
+
}
|
|
4795
|
+
mergeSkillVariables(agent, variables);
|
|
4796
|
+
console.log("Uploading compose...");
|
|
4797
|
+
const response = await createOrUpdateCompose({ content: config });
|
|
4798
|
+
const scopeResponse = await getScope();
|
|
4799
|
+
const shortVersionId = response.versionId.slice(0, 8);
|
|
4800
|
+
const displayName = `${scopeResponse.slug}/${response.name}`;
|
|
4801
|
+
if (response.action === "created") {
|
|
4802
|
+
console.log(chalk4.green(`\u2713 Compose created: ${displayName}`));
|
|
4635
4803
|
} else {
|
|
4636
|
-
console.
|
|
4637
|
-
console.error(chalk3.dim(` ${error.message}`));
|
|
4804
|
+
console.log(chalk4.green(`\u2713 Compose version exists: ${displayName}`));
|
|
4638
4805
|
}
|
|
4639
|
-
|
|
4640
|
-
console.
|
|
4806
|
+
console.log(chalk4.dim(` Version: ${shortVersionId}`));
|
|
4807
|
+
console.log();
|
|
4808
|
+
console.log(" Run your agent:");
|
|
4809
|
+
console.log(
|
|
4810
|
+
chalk4.cyan(
|
|
4811
|
+
` vm0 run ${displayName}:${shortVersionId} --artifact-name <artifact> "your prompt"`
|
|
4812
|
+
)
|
|
4813
|
+
);
|
|
4814
|
+
if (options.autoUpdate !== false) {
|
|
4815
|
+
await silentUpgradeAfterCommand("9.12.0");
|
|
4816
|
+
}
|
|
4817
|
+
} catch (error) {
|
|
4818
|
+
if (error instanceof Error) {
|
|
4819
|
+
if (error.message.includes("Not authenticated")) {
|
|
4820
|
+
console.error(
|
|
4821
|
+
chalk4.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
4822
|
+
);
|
|
4823
|
+
} else {
|
|
4824
|
+
console.error(chalk4.red("\u2717 Failed to create compose"));
|
|
4825
|
+
console.error(chalk4.dim(` ${error.message}`));
|
|
4826
|
+
}
|
|
4827
|
+
} else {
|
|
4828
|
+
console.error(chalk4.red("\u2717 An unexpected error occurred"));
|
|
4829
|
+
}
|
|
4830
|
+
process.exit(1);
|
|
4641
4831
|
}
|
|
4642
|
-
process.exit(1);
|
|
4643
4832
|
}
|
|
4644
|
-
|
|
4833
|
+
);
|
|
4645
4834
|
|
|
4646
4835
|
// src/commands/run/run.ts
|
|
4647
|
-
import { Command as Command8, Option } from "commander";
|
|
4648
|
-
import
|
|
4836
|
+
import { Command as Command8, Option as Option2 } from "commander";
|
|
4837
|
+
import chalk9 from "chalk";
|
|
4649
4838
|
|
|
4650
4839
|
// src/lib/events/event-renderer.ts
|
|
4651
|
-
import
|
|
4840
|
+
import chalk6 from "chalk";
|
|
4652
4841
|
|
|
4653
4842
|
// src/lib/events/tool-formatters.ts
|
|
4654
|
-
import
|
|
4843
|
+
import chalk5 from "chalk";
|
|
4655
4844
|
function pluralize(count, singular, plural) {
|
|
4656
4845
|
return count === 1 ? singular : plural;
|
|
4657
4846
|
}
|
|
@@ -4665,15 +4854,15 @@ function formatToolHeader(data) {
|
|
|
4665
4854
|
return [headline];
|
|
4666
4855
|
}
|
|
4667
4856
|
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${
|
|
4857
|
+
Read: (input) => `Read${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4858
|
+
Edit: (input) => `Edit${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4859
|
+
Write: (input) => `Write${chalk5.dim(`(${String(input.file_path || "")})`)}`,
|
|
4860
|
+
Bash: (input) => `Bash${chalk5.dim(`(${truncate(String(input.command || ""), 60)})`)}`,
|
|
4861
|
+
Glob: (input) => `Glob${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
4862
|
+
Grep: (input) => `Grep${chalk5.dim(`(${String(input.pattern || "")})`)}`,
|
|
4863
|
+
Task: (input) => `Task${chalk5.dim(`(${truncate(String(input.description || ""), 60)})`)}`,
|
|
4864
|
+
WebFetch: (input) => `WebFetch${chalk5.dim(`(${truncate(String(input.url || ""), 60)})`)}`,
|
|
4865
|
+
WebSearch: (input) => `WebSearch${chalk5.dim(`(${truncate(String(input.query || ""), 60)})`)}`,
|
|
4677
4866
|
TodoWrite: () => "TodoWrite"
|
|
4678
4867
|
};
|
|
4679
4868
|
function getToolHeadline(tool, input) {
|
|
@@ -4706,7 +4895,7 @@ function formatToolResult(toolUse, result, verbose) {
|
|
|
4706
4895
|
}
|
|
4707
4896
|
if (isError) {
|
|
4708
4897
|
const errorMsg = resultText ? truncate(resultText, 80) : "Error";
|
|
4709
|
-
lines.push(`\u2514 \u2717 ${
|
|
4898
|
+
lines.push(`\u2514 \u2717 ${chalk5.dim(errorMsg)}`);
|
|
4710
4899
|
return lines;
|
|
4711
4900
|
}
|
|
4712
4901
|
if (resultText) {
|
|
@@ -4714,23 +4903,23 @@ function formatToolResult(toolUse, result, verbose) {
|
|
|
4714
4903
|
if (verbose) {
|
|
4715
4904
|
for (let i = 0; i < resultLines.length; i++) {
|
|
4716
4905
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4717
|
-
lines.push(`${prefix}${
|
|
4906
|
+
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
4718
4907
|
}
|
|
4719
4908
|
} else if (resultLines.length > 0) {
|
|
4720
4909
|
const previewCount = Math.min(3, resultLines.length);
|
|
4721
4910
|
for (let i = 0; i < previewCount; i++) {
|
|
4722
4911
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4723
|
-
lines.push(`${prefix}${
|
|
4912
|
+
lines.push(`${prefix}${chalk5.dim(resultLines[i])}`);
|
|
4724
4913
|
}
|
|
4725
4914
|
const remaining = resultLines.length - previewCount;
|
|
4726
4915
|
if (remaining > 0) {
|
|
4727
4916
|
lines.push(
|
|
4728
|
-
` ${
|
|
4917
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4729
4918
|
);
|
|
4730
4919
|
}
|
|
4731
4920
|
}
|
|
4732
4921
|
} else {
|
|
4733
|
-
lines.push(`\u2514 \u2713 ${
|
|
4922
|
+
lines.push(`\u2514 \u2713 ${chalk5.dim("Done")}`);
|
|
4734
4923
|
}
|
|
4735
4924
|
return lines;
|
|
4736
4925
|
}
|
|
@@ -4748,24 +4937,24 @@ function formatReadContent(resultText, verbose) {
|
|
|
4748
4937
|
const displayLines = contentLines.length > 0 ? contentLines : rawLines.filter((line) => line.trim().length > 0);
|
|
4749
4938
|
const totalLines = displayLines.length;
|
|
4750
4939
|
if (totalLines === 0) {
|
|
4751
|
-
lines.push(`\u2514 \u2713 ${
|
|
4940
|
+
lines.push(`\u2514 \u2713 ${chalk5.dim("(empty)")}`);
|
|
4752
4941
|
return lines;
|
|
4753
4942
|
}
|
|
4754
4943
|
if (verbose) {
|
|
4755
4944
|
for (let i = 0; i < displayLines.length; i++) {
|
|
4756
4945
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4757
|
-
lines.push(`${prefix}${
|
|
4946
|
+
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
4758
4947
|
}
|
|
4759
4948
|
} else {
|
|
4760
4949
|
const previewCount = Math.min(3, totalLines);
|
|
4761
4950
|
for (let i = 0; i < previewCount; i++) {
|
|
4762
4951
|
const prefix = i === 0 ? "\u2514 " : " ";
|
|
4763
|
-
lines.push(`${prefix}${
|
|
4952
|
+
lines.push(`${prefix}${chalk5.dim(displayLines[i] ?? "")}`);
|
|
4764
4953
|
}
|
|
4765
4954
|
const remaining = totalLines - previewCount;
|
|
4766
4955
|
if (remaining > 0) {
|
|
4767
4956
|
lines.push(
|
|
4768
|
-
` ${
|
|
4957
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4769
4958
|
);
|
|
4770
4959
|
}
|
|
4771
4960
|
}
|
|
@@ -4779,18 +4968,18 @@ function formatWritePreview(input, verbose) {
|
|
|
4779
4968
|
if (verbose) {
|
|
4780
4969
|
for (let i = 0; i < contentLines.length; i++) {
|
|
4781
4970
|
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4782
|
-
lines.push(`${prefix}${
|
|
4971
|
+
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
4783
4972
|
}
|
|
4784
4973
|
} else {
|
|
4785
4974
|
const previewCount = Math.min(3, totalLines);
|
|
4786
4975
|
for (let i = 0; i < previewCount; i++) {
|
|
4787
4976
|
const prefix = i === 0 ? "\u23BF " : " ";
|
|
4788
|
-
lines.push(`${prefix}${
|
|
4977
|
+
lines.push(`${prefix}${chalk5.dim(contentLines[i] ?? "")}`);
|
|
4789
4978
|
}
|
|
4790
4979
|
const remaining = totalLines - previewCount;
|
|
4791
4980
|
if (remaining > 0) {
|
|
4792
4981
|
lines.push(
|
|
4793
|
-
` ${
|
|
4982
|
+
` ${chalk5.dim(`\u2026 +${remaining} ${pluralize(remaining, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4794
4983
|
);
|
|
4795
4984
|
}
|
|
4796
4985
|
}
|
|
@@ -4805,34 +4994,34 @@ function formatEditDiff(input, verbose) {
|
|
|
4805
4994
|
const removed = oldLines.length;
|
|
4806
4995
|
const added = newLines.length;
|
|
4807
4996
|
const summary = `Added ${added} ${pluralize(added, "line", "lines")}, removed ${removed} ${pluralize(removed, "line", "lines")}`;
|
|
4808
|
-
lines.push(`\u23BF ${
|
|
4997
|
+
lines.push(`\u23BF ${chalk5.dim(summary)}`);
|
|
4809
4998
|
if (verbose) {
|
|
4810
4999
|
for (const line of oldLines) {
|
|
4811
|
-
lines.push(` - ${
|
|
5000
|
+
lines.push(` - ${chalk5.dim(line)}`);
|
|
4812
5001
|
}
|
|
4813
5002
|
for (const line of newLines) {
|
|
4814
|
-
lines.push(` + ${
|
|
5003
|
+
lines.push(` + ${chalk5.dim(line)}`);
|
|
4815
5004
|
}
|
|
4816
5005
|
} else {
|
|
4817
5006
|
const previewLimit = 3;
|
|
4818
5007
|
const showOld = Math.min(previewLimit, oldLines.length);
|
|
4819
5008
|
const showNew = Math.min(previewLimit, newLines.length);
|
|
4820
5009
|
for (let i = 0; i < showOld; i++) {
|
|
4821
|
-
lines.push(` - ${
|
|
5010
|
+
lines.push(` - ${chalk5.dim(truncate(oldLines[i] ?? "", 60))}`);
|
|
4822
5011
|
}
|
|
4823
5012
|
const remainingOld = oldLines.length - previewLimit;
|
|
4824
5013
|
if (remainingOld > 0) {
|
|
4825
5014
|
lines.push(
|
|
4826
|
-
` ${
|
|
5015
|
+
` ${chalk5.dim(`\u2026 +${remainingOld} ${pluralize(remainingOld, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4827
5016
|
);
|
|
4828
5017
|
}
|
|
4829
5018
|
for (let i = 0; i < showNew; i++) {
|
|
4830
|
-
lines.push(` + ${
|
|
5019
|
+
lines.push(` + ${chalk5.dim(truncate(newLines[i] ?? "", 60))}`);
|
|
4831
5020
|
}
|
|
4832
5021
|
const remainingNew = newLines.length - previewLimit;
|
|
4833
5022
|
if (remainingNew > 0) {
|
|
4834
5023
|
lines.push(
|
|
4835
|
-
` ${
|
|
5024
|
+
` ${chalk5.dim(`\u2026 +${remainingNew} ${pluralize(remainingNew, "line", "lines")} (vm0 logs <runId> to see all)`)}`
|
|
4836
5025
|
);
|
|
4837
5026
|
}
|
|
4838
5027
|
}
|
|
@@ -4870,12 +5059,12 @@ function getTodoStatusIcon(status) {
|
|
|
4870
5059
|
function formatTodoContent(content, status) {
|
|
4871
5060
|
switch (status) {
|
|
4872
5061
|
case "completed":
|
|
4873
|
-
return
|
|
5062
|
+
return chalk5.dim.strikethrough(content);
|
|
4874
5063
|
case "in_progress":
|
|
4875
5064
|
return content;
|
|
4876
5065
|
case "pending":
|
|
4877
5066
|
default:
|
|
4878
|
-
return
|
|
5067
|
+
return chalk5.dim(content);
|
|
4879
5068
|
}
|
|
4880
5069
|
}
|
|
4881
5070
|
|
|
@@ -4893,12 +5082,12 @@ var EventRenderer = class _EventRenderer {
|
|
|
4893
5082
|
* Called immediately after run is created, before polling events
|
|
4894
5083
|
*/
|
|
4895
5084
|
static renderRunStarted(info) {
|
|
4896
|
-
console.log(
|
|
4897
|
-
console.log(` Run ID: ${
|
|
5085
|
+
console.log(chalk6.bold("\u25B6 Run started"));
|
|
5086
|
+
console.log(` Run ID: ${chalk6.dim(info.runId)}`);
|
|
4898
5087
|
if (info.sandboxId) {
|
|
4899
|
-
console.log(` Sandbox: ${
|
|
5088
|
+
console.log(` Sandbox: ${chalk6.dim(info.sandboxId)}`);
|
|
4900
5089
|
}
|
|
4901
|
-
console.log(
|
|
5090
|
+
console.log(chalk6.dim(` (use "vm0 logs ${info.runId}" to view logs)`));
|
|
4902
5091
|
console.log();
|
|
4903
5092
|
}
|
|
4904
5093
|
/**
|
|
@@ -4936,16 +5125,16 @@ var EventRenderer = class _EventRenderer {
|
|
|
4936
5125
|
*/
|
|
4937
5126
|
static renderRunCompleted(result) {
|
|
4938
5127
|
console.log("");
|
|
4939
|
-
console.log(
|
|
5128
|
+
console.log(chalk6.green("\u2713 Run completed successfully"));
|
|
4940
5129
|
if (result) {
|
|
4941
|
-
console.log(` Checkpoint: ${
|
|
4942
|
-
console.log(` Session: ${
|
|
4943
|
-
console.log(` Conversation: ${
|
|
5130
|
+
console.log(` Checkpoint: ${chalk6.dim(result.checkpointId)}`);
|
|
5131
|
+
console.log(` Session: ${chalk6.dim(result.agentSessionId)}`);
|
|
5132
|
+
console.log(` Conversation: ${chalk6.dim(result.conversationId)}`);
|
|
4944
5133
|
if (result.artifact && Object.keys(result.artifact).length > 0) {
|
|
4945
5134
|
console.log(` Artifact:`);
|
|
4946
5135
|
for (const [name, version] of Object.entries(result.artifact)) {
|
|
4947
5136
|
console.log(
|
|
4948
|
-
` ${name}: ${
|
|
5137
|
+
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
4949
5138
|
);
|
|
4950
5139
|
}
|
|
4951
5140
|
}
|
|
@@ -4953,7 +5142,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
4953
5142
|
console.log(` Volumes:`);
|
|
4954
5143
|
for (const [name, version] of Object.entries(result.volumes)) {
|
|
4955
5144
|
console.log(
|
|
4956
|
-
` ${name}: ${
|
|
5145
|
+
` ${name}: ${chalk6.dim(_EventRenderer.formatVersion(version))}`
|
|
4957
5146
|
);
|
|
4958
5147
|
}
|
|
4959
5148
|
}
|
|
@@ -4965,10 +5154,10 @@ var EventRenderer = class _EventRenderer {
|
|
|
4965
5154
|
*/
|
|
4966
5155
|
static renderRunFailed(error, runId) {
|
|
4967
5156
|
console.log("");
|
|
4968
|
-
console.log(
|
|
4969
|
-
console.log(` Error: ${
|
|
5157
|
+
console.log(chalk6.red("\u2717 Run failed"));
|
|
5158
|
+
console.log(` Error: ${chalk6.red(error || "Unknown error")}`);
|
|
4970
5159
|
console.log(
|
|
4971
|
-
|
|
5160
|
+
chalk6.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
4972
5161
|
);
|
|
4973
5162
|
}
|
|
4974
5163
|
/**
|
|
@@ -5052,13 +5241,13 @@ var EventRenderer = class _EventRenderer {
|
|
|
5052
5241
|
const frameworkStr = String(event.data.framework || "claude-code");
|
|
5053
5242
|
const displayName = isSupportedFramework(frameworkStr) ? getFrameworkDisplayName(frameworkStr) : frameworkStr;
|
|
5054
5243
|
this.frameworkDisplayName = displayName;
|
|
5055
|
-
console.log(prefix +
|
|
5056
|
-
console.log(` Session: ${
|
|
5244
|
+
console.log(prefix + chalk6.bold(`\u25B7 ${displayName} Started`));
|
|
5245
|
+
console.log(` Session: ${chalk6.dim(String(event.data.sessionId || ""))}`);
|
|
5057
5246
|
if (event.data.model) {
|
|
5058
|
-
console.log(` Model: ${
|
|
5247
|
+
console.log(` Model: ${chalk6.dim(String(event.data.model))}`);
|
|
5059
5248
|
}
|
|
5060
5249
|
console.log(
|
|
5061
|
-
` Tools: ${
|
|
5250
|
+
` Tools: ${chalk6.dim(
|
|
5062
5251
|
Array.isArray(event.data.tools) ? event.data.tools.join(", ") : String(event.data.tools || "")
|
|
5063
5252
|
)}`
|
|
5064
5253
|
);
|
|
@@ -5075,18 +5264,18 @@ var EventRenderer = class _EventRenderer {
|
|
|
5075
5264
|
const success = Boolean(event.data.success);
|
|
5076
5265
|
if (success) {
|
|
5077
5266
|
console.log(
|
|
5078
|
-
prefix +
|
|
5267
|
+
prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Completed`)
|
|
5079
5268
|
);
|
|
5080
5269
|
} else {
|
|
5081
|
-
console.log(prefix +
|
|
5270
|
+
console.log(prefix + chalk6.bold(`\u25C6 ${this.frameworkDisplayName} Failed`));
|
|
5082
5271
|
}
|
|
5083
5272
|
const durationMs = Number(event.data.durationMs || 0);
|
|
5084
5273
|
const durationSec = (durationMs / 1e3).toFixed(1);
|
|
5085
|
-
console.log(` Duration: ${
|
|
5274
|
+
console.log(` Duration: ${chalk6.dim(durationSec + "s")}`);
|
|
5086
5275
|
const cost = Number(event.data.cost || 0);
|
|
5087
|
-
console.log(` Cost: ${
|
|
5276
|
+
console.log(` Cost: ${chalk6.dim("$" + cost.toFixed(4))}`);
|
|
5088
5277
|
const numTurns = Number(event.data.numTurns || 0);
|
|
5089
|
-
console.log(` Turns: ${
|
|
5278
|
+
console.log(` Turns: ${chalk6.dim(String(numTurns))}`);
|
|
5090
5279
|
const usage = event.data.usage;
|
|
5091
5280
|
if (usage && typeof usage === "object") {
|
|
5092
5281
|
const inputTokens = Number(usage.input_tokens || 0);
|
|
@@ -5098,7 +5287,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
5098
5287
|
return String(count);
|
|
5099
5288
|
};
|
|
5100
5289
|
console.log(
|
|
5101
|
-
` Tokens: ${
|
|
5290
|
+
` Tokens: ${chalk6.dim(
|
|
5102
5291
|
`input=${formatTokens(inputTokens)} output=${formatTokens(outputTokens)}`
|
|
5103
5292
|
)}`
|
|
5104
5293
|
);
|
|
@@ -5117,7 +5306,7 @@ var EventRenderer = class _EventRenderer {
|
|
|
5117
5306
|
};
|
|
5118
5307
|
|
|
5119
5308
|
// src/commands/run/shared.ts
|
|
5120
|
-
import
|
|
5309
|
+
import chalk8 from "chalk";
|
|
5121
5310
|
import * as fs5 from "fs";
|
|
5122
5311
|
import { config as dotenvConfig } from "dotenv";
|
|
5123
5312
|
|
|
@@ -5443,7 +5632,7 @@ function parseEvent(rawEvent, framework) {
|
|
|
5443
5632
|
}
|
|
5444
5633
|
|
|
5445
5634
|
// src/lib/events/codex-event-renderer.ts
|
|
5446
|
-
import
|
|
5635
|
+
import chalk7 from "chalk";
|
|
5447
5636
|
var CodexEventRenderer = class {
|
|
5448
5637
|
/**
|
|
5449
5638
|
* Check if an event is a Codex event
|
|
@@ -5490,13 +5679,13 @@ var CodexEventRenderer = class {
|
|
|
5490
5679
|
const cached = event.usage.cached_input_tokens || 0;
|
|
5491
5680
|
const cachedStr = cached ? ` (${cached} cached)` : "";
|
|
5492
5681
|
console.log(
|
|
5493
|
-
"[turn.completed]" +
|
|
5682
|
+
"[turn.completed]" + chalk7.dim(` ${input} in / ${output} out${cachedStr}`)
|
|
5494
5683
|
);
|
|
5495
5684
|
}
|
|
5496
5685
|
}
|
|
5497
5686
|
static renderTurnFailed(event) {
|
|
5498
5687
|
console.log(
|
|
5499
|
-
|
|
5688
|
+
chalk7.red("[turn.failed]") + (event.error ? ` ${event.error}` : "")
|
|
5500
5689
|
);
|
|
5501
5690
|
}
|
|
5502
5691
|
// eslint-disable-next-line complexity -- TODO: refactor complex function
|
|
@@ -5522,15 +5711,15 @@ var CodexEventRenderer = class {
|
|
|
5522
5711
|
if (output) {
|
|
5523
5712
|
const lines = output.split("\n").filter((l) => l.trim());
|
|
5524
5713
|
const preview = lines.slice(0, 3).join("\n ");
|
|
5525
|
-
const more = lines.length > 3 ?
|
|
5714
|
+
const more = lines.length > 3 ? chalk7.dim(` ... (${lines.length - 3} more lines)`) : "";
|
|
5526
5715
|
console.log(
|
|
5527
|
-
"[output]" + (exitCode !== 0 ?
|
|
5716
|
+
"[output]" + (exitCode !== 0 ? chalk7.red(` exit=${exitCode}`) : "")
|
|
5528
5717
|
);
|
|
5529
5718
|
if (preview) {
|
|
5530
5719
|
console.log(" " + preview + more);
|
|
5531
5720
|
}
|
|
5532
5721
|
} else if (exitCode !== 0) {
|
|
5533
|
-
console.log(
|
|
5722
|
+
console.log(chalk7.red("[output]") + chalk7.red(` exit=${exitCode}`));
|
|
5534
5723
|
}
|
|
5535
5724
|
}
|
|
5536
5725
|
return;
|
|
@@ -5540,7 +5729,7 @@ var CodexEventRenderer = class {
|
|
|
5540
5729
|
const icon = c20.kind === "add" ? "+" : c20.kind === "delete" ? "-" : "~";
|
|
5541
5730
|
return `${icon}${c20.path}`;
|
|
5542
5731
|
}).join(", ");
|
|
5543
|
-
console.log(
|
|
5732
|
+
console.log(chalk7.green("[files]") + ` ${summary}`);
|
|
5544
5733
|
return;
|
|
5545
5734
|
}
|
|
5546
5735
|
if (itemType === "file_edit" || itemType === "file_write" || itemType === "file_read") {
|
|
@@ -5553,7 +5742,7 @@ var CodexEventRenderer = class {
|
|
|
5553
5742
|
}
|
|
5554
5743
|
static renderError(event) {
|
|
5555
5744
|
console.log(
|
|
5556
|
-
|
|
5745
|
+
chalk7.red("[error]") + ` ${event.message || event.error || "Unknown error"}`
|
|
5557
5746
|
);
|
|
5558
5747
|
}
|
|
5559
5748
|
};
|
|
@@ -6612,9 +6801,9 @@ async function streamRealtimeEvents(runId, options) {
|
|
|
6612
6801
|
EventRenderer.renderRunFailed(error, rid);
|
|
6613
6802
|
},
|
|
6614
6803
|
onTimeout: (rid) => {
|
|
6615
|
-
console.error(
|
|
6804
|
+
console.error(chalk8.red("\n\u2717 Run timed out"));
|
|
6616
6805
|
console.error(
|
|
6617
|
-
|
|
6806
|
+
chalk8.dim(` (use "vm0 logs ${rid} --system" to view system logs)`)
|
|
6618
6807
|
);
|
|
6619
6808
|
}
|
|
6620
6809
|
});
|
|
@@ -6657,9 +6846,9 @@ async function pollEvents(runId, options) {
|
|
|
6657
6846
|
result = { succeeded: false, runId };
|
|
6658
6847
|
} else if (runStatus === "timeout") {
|
|
6659
6848
|
complete = true;
|
|
6660
|
-
console.error(
|
|
6849
|
+
console.error(chalk8.red("\n\u2717 Run timed out"));
|
|
6661
6850
|
console.error(
|
|
6662
|
-
|
|
6851
|
+
chalk8.dim(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
6663
6852
|
);
|
|
6664
6853
|
result = { succeeded: false, runId };
|
|
6665
6854
|
}
|
|
@@ -6673,11 +6862,11 @@ function showNextSteps(result) {
|
|
|
6673
6862
|
const { runId, sessionId, checkpointId } = result;
|
|
6674
6863
|
console.log();
|
|
6675
6864
|
console.log(" View agent logs:");
|
|
6676
|
-
console.log(
|
|
6865
|
+
console.log(chalk8.cyan(` vm0 logs ${runId}`));
|
|
6677
6866
|
if (sessionId) {
|
|
6678
6867
|
console.log(" Continue with session (latest conversation and artifact):");
|
|
6679
6868
|
console.log(
|
|
6680
|
-
|
|
6869
|
+
chalk8.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
6681
6870
|
);
|
|
6682
6871
|
}
|
|
6683
6872
|
if (checkpointId) {
|
|
@@ -6685,40 +6874,66 @@ function showNextSteps(result) {
|
|
|
6685
6874
|
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
6686
6875
|
);
|
|
6687
6876
|
console.log(
|
|
6688
|
-
|
|
6877
|
+
chalk8.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
6689
6878
|
);
|
|
6690
6879
|
}
|
|
6691
6880
|
}
|
|
6692
6881
|
function handleGenericRunError(error, commandLabel) {
|
|
6693
6882
|
if (error instanceof ApiRequestError && error.code === "concurrent_run_limit_exceeded") {
|
|
6694
|
-
console.error(
|
|
6883
|
+
console.error(chalk8.red(`\u2717 ${commandLabel} failed`));
|
|
6695
6884
|
console.error(
|
|
6696
|
-
|
|
6885
|
+
chalk8.dim(
|
|
6697
6886
|
` ${error.message} Use 'vm0 run list' to view runs, 'vm0 run kill <id>' to cancel.`
|
|
6698
6887
|
)
|
|
6699
6888
|
);
|
|
6700
6889
|
} else {
|
|
6701
|
-
console.error(
|
|
6702
|
-
console.error(
|
|
6890
|
+
console.error(chalk8.red(`\u2717 ${commandLabel} failed`));
|
|
6891
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6703
6892
|
}
|
|
6704
6893
|
}
|
|
6894
|
+
function handleRunError(error, identifier) {
|
|
6895
|
+
if (error instanceof Error) {
|
|
6896
|
+
if (error.message.includes("Not authenticated")) {
|
|
6897
|
+
console.error(chalk8.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
6898
|
+
} else if (error.message.includes("Realtime connection failed")) {
|
|
6899
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6900
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6901
|
+
console.error(chalk8.dim(" Try running without --experimental-realtime"));
|
|
6902
|
+
} else if (error.message.startsWith("Version not found:")) {
|
|
6903
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6904
|
+
console.error(chalk8.dim(" Make sure the version hash is correct"));
|
|
6905
|
+
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6906
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6907
|
+
} else if (error.message.includes("not found")) {
|
|
6908
|
+
console.error(chalk8.red(`\u2717 Agent not found: ${identifier}`));
|
|
6909
|
+
console.error(
|
|
6910
|
+
chalk8.dim(" Make sure you've composed the agent with: vm0 compose")
|
|
6911
|
+
);
|
|
6912
|
+
} else {
|
|
6913
|
+
handleGenericRunError(error, "Run");
|
|
6914
|
+
}
|
|
6915
|
+
} else {
|
|
6916
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6917
|
+
}
|
|
6918
|
+
process.exit(1);
|
|
6919
|
+
}
|
|
6705
6920
|
function handleResumeOrContinueError(error, commandLabel, resourceId, resourceLabel) {
|
|
6706
6921
|
if (error instanceof Error) {
|
|
6707
6922
|
if (error.message.includes("Not authenticated")) {
|
|
6708
|
-
console.error(
|
|
6923
|
+
console.error(chalk8.red("\u2717 Not authenticated. Run: vm0 auth login"));
|
|
6709
6924
|
} else if (error.message.includes("Realtime connection failed")) {
|
|
6710
|
-
console.error(
|
|
6711
|
-
console.error(
|
|
6712
|
-
console.error(
|
|
6925
|
+
console.error(chalk8.red("\u2717 Realtime streaming failed"));
|
|
6926
|
+
console.error(chalk8.dim(` ${error.message}`));
|
|
6927
|
+
console.error(chalk8.dim(" Try running without --experimental-realtime"));
|
|
6713
6928
|
} else if (error.message.startsWith("Environment file not found:")) {
|
|
6714
|
-
console.error(
|
|
6929
|
+
console.error(chalk8.red(`\u2717 ${error.message}`));
|
|
6715
6930
|
} else if (error.message.includes("not found")) {
|
|
6716
|
-
console.error(
|
|
6931
|
+
console.error(chalk8.red(`\u2717 ${resourceLabel} not found: ${resourceId}`));
|
|
6717
6932
|
} else {
|
|
6718
6933
|
handleGenericRunError(error, commandLabel);
|
|
6719
6934
|
}
|
|
6720
6935
|
} else {
|
|
6721
|
-
console.error(
|
|
6936
|
+
console.error(chalk8.red("\u2717 An unexpected error occurred"));
|
|
6722
6937
|
}
|
|
6723
6938
|
process.exit(1);
|
|
6724
6939
|
}
|
|
@@ -6757,7 +6972,7 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6757
6972
|
).option(
|
|
6758
6973
|
"--model-provider <type>",
|
|
6759
6974
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6760
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
6975
|
+
).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
6976
|
async (identifier, prompt, options) => {
|
|
6762
6977
|
try {
|
|
6763
6978
|
const { scope, name, version } = parseIdentifier(identifier);
|
|
@@ -6770,9 +6985,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6770
6985
|
} else {
|
|
6771
6986
|
const compose = await getComposeByName(name, scope);
|
|
6772
6987
|
if (!compose) {
|
|
6773
|
-
console.error(
|
|
6988
|
+
console.error(chalk9.red(`\u2717 Agent not found: ${identifier}`));
|
|
6774
6989
|
console.error(
|
|
6775
|
-
|
|
6990
|
+
chalk9.dim(
|
|
6776
6991
|
" Make sure you've composed the agent with: vm0 compose"
|
|
6777
6992
|
)
|
|
6778
6993
|
);
|
|
@@ -6812,9 +7027,9 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6812
7027
|
debugNoMockClaude: options.debugNoMockClaude || void 0
|
|
6813
7028
|
});
|
|
6814
7029
|
if (response.status === "failed") {
|
|
6815
|
-
console.error(
|
|
7030
|
+
console.error(chalk9.red("\u2717 Run preparation failed"));
|
|
6816
7031
|
if (response.error) {
|
|
6817
|
-
console.error(
|
|
7032
|
+
console.error(chalk9.dim(` ${response.error}`));
|
|
6818
7033
|
}
|
|
6819
7034
|
process.exit(1);
|
|
6820
7035
|
}
|
|
@@ -6829,44 +7044,18 @@ var mainRunCommand = new Command8().name("run").description("Run an agent").argu
|
|
|
6829
7044
|
process.exit(1);
|
|
6830
7045
|
}
|
|
6831
7046
|
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"));
|
|
7047
|
+
if (options.autoUpdate !== false) {
|
|
7048
|
+
await silentUpgradeAfterCommand("9.12.0");
|
|
6861
7049
|
}
|
|
6862
|
-
|
|
7050
|
+
} catch (error) {
|
|
7051
|
+
handleRunError(error, identifier);
|
|
6863
7052
|
}
|
|
6864
7053
|
}
|
|
6865
7054
|
);
|
|
6866
7055
|
|
|
6867
7056
|
// src/commands/run/resume.ts
|
|
6868
|
-
import { Command as Command9, Option as
|
|
6869
|
-
import
|
|
7057
|
+
import { Command as Command9, Option as Option3 } from "commander";
|
|
7058
|
+
import chalk10 from "chalk";
|
|
6870
7059
|
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
7060
|
"--env-file <path>",
|
|
6872
7061
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
@@ -6891,7 +7080,7 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6891
7080
|
).option(
|
|
6892
7081
|
"--model-provider <type>",
|
|
6893
7082
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6894
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
7083
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option3("--debug-no-mock-claude").hideHelp()).action(
|
|
6895
7084
|
async (checkpointId, prompt, options, command) => {
|
|
6896
7085
|
const allOpts = command.optsWithGlobals();
|
|
6897
7086
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6899,9 +7088,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6899
7088
|
try {
|
|
6900
7089
|
if (!isUUID(checkpointId)) {
|
|
6901
7090
|
console.error(
|
|
6902
|
-
|
|
7091
|
+
chalk10.red(`\u2717 Invalid checkpoint ID format: ${checkpointId}`)
|
|
6903
7092
|
);
|
|
6904
|
-
console.error(
|
|
7093
|
+
console.error(chalk10.dim(" Checkpoint ID must be a valid UUID"));
|
|
6905
7094
|
process.exit(1);
|
|
6906
7095
|
}
|
|
6907
7096
|
const checkpointInfo = await getCheckpoint(checkpointId);
|
|
@@ -6918,9 +7107,9 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6918
7107
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
6919
7108
|
});
|
|
6920
7109
|
if (response.status === "failed") {
|
|
6921
|
-
console.error(
|
|
7110
|
+
console.error(chalk10.red("\u2717 Run preparation failed"));
|
|
6922
7111
|
if (response.error) {
|
|
6923
|
-
console.error(
|
|
7112
|
+
console.error(chalk10.dim(` ${response.error}`));
|
|
6924
7113
|
}
|
|
6925
7114
|
process.exit(1);
|
|
6926
7115
|
}
|
|
@@ -6947,8 +7136,8 @@ var resumeCommand = new Command9().name("resume").description("Resume an agent r
|
|
|
6947
7136
|
);
|
|
6948
7137
|
|
|
6949
7138
|
// src/commands/run/continue.ts
|
|
6950
|
-
import { Command as Command10, Option as
|
|
6951
|
-
import
|
|
7139
|
+
import { Command as Command10, Option as Option4 } from "commander";
|
|
7140
|
+
import chalk11 from "chalk";
|
|
6952
7141
|
var continueCommand = new Command10().name("continue").description(
|
|
6953
7142
|
"Continue an agent run from a session (uses latest artifact version)"
|
|
6954
7143
|
).argument("<agentSessionId>", "Agent session ID to continue from").argument("<prompt>", "Prompt for the continued agent").option(
|
|
@@ -6975,7 +7164,7 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6975
7164
|
).option(
|
|
6976
7165
|
"--model-provider <type>",
|
|
6977
7166
|
"Override model provider (e.g., anthropic-api-key)"
|
|
6978
|
-
).option("--verbose", "Show full tool inputs and outputs").addOption(new
|
|
7167
|
+
).option("--verbose", "Show full tool inputs and outputs").addOption(new Option4("--debug-no-mock-claude").hideHelp()).action(
|
|
6979
7168
|
async (agentSessionId, prompt, options, command) => {
|
|
6980
7169
|
const allOpts = command.optsWithGlobals();
|
|
6981
7170
|
const vars = { ...allOpts.vars, ...options.vars };
|
|
@@ -6983,9 +7172,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
6983
7172
|
try {
|
|
6984
7173
|
if (!isUUID(agentSessionId)) {
|
|
6985
7174
|
console.error(
|
|
6986
|
-
|
|
7175
|
+
chalk11.red(`\u2717 Invalid agent session ID format: ${agentSessionId}`)
|
|
6987
7176
|
);
|
|
6988
|
-
console.error(
|
|
7177
|
+
console.error(chalk11.dim(" Agent session ID must be a valid UUID"));
|
|
6989
7178
|
process.exit(1);
|
|
6990
7179
|
}
|
|
6991
7180
|
const sessionInfo = await getSession(agentSessionId);
|
|
@@ -7002,9 +7191,9 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
7002
7191
|
debugNoMockClaude: options.debugNoMockClaude || allOpts.debugNoMockClaude || void 0
|
|
7003
7192
|
});
|
|
7004
7193
|
if (response.status === "failed") {
|
|
7005
|
-
console.error(
|
|
7194
|
+
console.error(chalk11.red("\u2717 Run preparation failed"));
|
|
7006
7195
|
if (response.error) {
|
|
7007
|
-
console.error(
|
|
7196
|
+
console.error(chalk11.dim(` ${response.error}`));
|
|
7008
7197
|
}
|
|
7009
7198
|
process.exit(1);
|
|
7010
7199
|
}
|
|
@@ -7032,20 +7221,20 @@ var continueCommand = new Command10().name("continue").description(
|
|
|
7032
7221
|
|
|
7033
7222
|
// src/commands/run/list.ts
|
|
7034
7223
|
import { Command as Command11 } from "commander";
|
|
7035
|
-
import
|
|
7224
|
+
import chalk12 from "chalk";
|
|
7036
7225
|
var UUID_LENGTH = 36;
|
|
7037
7226
|
function formatRunStatus(status, width) {
|
|
7038
7227
|
const paddedStatus = width ? status.padEnd(width) : status;
|
|
7039
7228
|
switch (status) {
|
|
7040
7229
|
case "running":
|
|
7041
|
-
return
|
|
7230
|
+
return chalk12.green(paddedStatus);
|
|
7042
7231
|
case "pending":
|
|
7043
|
-
return
|
|
7232
|
+
return chalk12.yellow(paddedStatus);
|
|
7044
7233
|
case "completed":
|
|
7045
|
-
return
|
|
7234
|
+
return chalk12.blue(paddedStatus);
|
|
7046
7235
|
case "failed":
|
|
7047
7236
|
case "timeout":
|
|
7048
|
-
return
|
|
7237
|
+
return chalk12.red(paddedStatus);
|
|
7049
7238
|
default:
|
|
7050
7239
|
return paddedStatus;
|
|
7051
7240
|
}
|
|
@@ -7055,7 +7244,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7055
7244
|
const response = await listRuns({ limit: 100 });
|
|
7056
7245
|
const activeRuns = response.runs;
|
|
7057
7246
|
if (activeRuns.length === 0) {
|
|
7058
|
-
console.log(
|
|
7247
|
+
console.log(chalk12.dim("No active runs"));
|
|
7059
7248
|
return;
|
|
7060
7249
|
}
|
|
7061
7250
|
const agentWidth = Math.max(
|
|
@@ -7069,7 +7258,7 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7069
7258
|
"STATUS".padEnd(statusWidth),
|
|
7070
7259
|
"CREATED"
|
|
7071
7260
|
].join(" ");
|
|
7072
|
-
console.log(
|
|
7261
|
+
console.log(chalk12.dim(header));
|
|
7073
7262
|
for (const run of activeRuns) {
|
|
7074
7263
|
const row = [
|
|
7075
7264
|
run.id.padEnd(UUID_LENGTH),
|
|
@@ -7080,12 +7269,12 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7080
7269
|
console.log(row);
|
|
7081
7270
|
}
|
|
7082
7271
|
} catch (error) {
|
|
7083
|
-
console.error(
|
|
7272
|
+
console.error(chalk12.red("\u2717 Failed to list runs"));
|
|
7084
7273
|
if (error instanceof Error) {
|
|
7085
7274
|
if (error.message.includes("Not authenticated")) {
|
|
7086
|
-
console.error(
|
|
7275
|
+
console.error(chalk12.dim(" Run: vm0 auth login"));
|
|
7087
7276
|
} else {
|
|
7088
|
-
console.error(
|
|
7277
|
+
console.error(chalk12.dim(` ${error.message}`));
|
|
7089
7278
|
}
|
|
7090
7279
|
}
|
|
7091
7280
|
process.exit(1);
|
|
@@ -7094,22 +7283,22 @@ var listCommand = new Command11().name("list").alias("ls").description("List act
|
|
|
7094
7283
|
|
|
7095
7284
|
// src/commands/run/kill.ts
|
|
7096
7285
|
import { Command as Command12 } from "commander";
|
|
7097
|
-
import
|
|
7286
|
+
import chalk13 from "chalk";
|
|
7098
7287
|
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
7288
|
try {
|
|
7100
7289
|
await cancelRun(runId);
|
|
7101
|
-
console.log(
|
|
7290
|
+
console.log(chalk13.green(`\u2713 Run ${runId} cancelled`));
|
|
7102
7291
|
} catch (error) {
|
|
7103
|
-
console.error(
|
|
7292
|
+
console.error(chalk13.red("\u2717 Failed to kill run"));
|
|
7104
7293
|
if (error instanceof Error) {
|
|
7105
7294
|
if (error.message.includes("Not authenticated")) {
|
|
7106
|
-
console.error(
|
|
7295
|
+
console.error(chalk13.dim(" Run: vm0 auth login"));
|
|
7107
7296
|
} else if (error.message.includes("not found") || error.message.includes("No such run")) {
|
|
7108
|
-
console.error(
|
|
7297
|
+
console.error(chalk13.dim(` Run not found: ${runId}`));
|
|
7109
7298
|
} else if (error.message.includes("cannot be cancelled")) {
|
|
7110
|
-
console.error(
|
|
7299
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
7111
7300
|
} else {
|
|
7112
|
-
console.error(
|
|
7301
|
+
console.error(chalk13.dim(` ${error.message}`));
|
|
7113
7302
|
}
|
|
7114
7303
|
}
|
|
7115
7304
|
process.exit(1);
|
|
@@ -7128,7 +7317,7 @@ import { Command as Command19 } from "commander";
|
|
|
7128
7317
|
|
|
7129
7318
|
// src/commands/volume/init.ts
|
|
7130
7319
|
import { Command as Command13 } from "commander";
|
|
7131
|
-
import
|
|
7320
|
+
import chalk14 from "chalk";
|
|
7132
7321
|
import path6 from "path";
|
|
7133
7322
|
|
|
7134
7323
|
// src/lib/storage/storage-utils.ts
|
|
@@ -7186,10 +7375,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7186
7375
|
const existingConfig = await readStorageConfig(cwd);
|
|
7187
7376
|
if (existingConfig) {
|
|
7188
7377
|
console.log(
|
|
7189
|
-
|
|
7378
|
+
chalk14.yellow(`Volume already initialized: ${existingConfig.name}`)
|
|
7190
7379
|
);
|
|
7191
7380
|
console.log(
|
|
7192
|
-
|
|
7381
|
+
chalk14.dim(`Config file: ${path6.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7193
7382
|
);
|
|
7194
7383
|
return;
|
|
7195
7384
|
}
|
|
@@ -7198,10 +7387,10 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7198
7387
|
volumeName = options.name;
|
|
7199
7388
|
} else if (!isInteractive()) {
|
|
7200
7389
|
console.error(
|
|
7201
|
-
|
|
7390
|
+
chalk14.red("\u2717 --name flag is required in non-interactive mode")
|
|
7202
7391
|
);
|
|
7203
7392
|
console.error(
|
|
7204
|
-
|
|
7393
|
+
chalk14.dim(" Usage: vm0 volume init --name <volume-name>")
|
|
7205
7394
|
);
|
|
7206
7395
|
process.exit(1);
|
|
7207
7396
|
} else {
|
|
@@ -7217,34 +7406,34 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7217
7406
|
}
|
|
7218
7407
|
);
|
|
7219
7408
|
if (name === void 0) {
|
|
7220
|
-
console.log(
|
|
7409
|
+
console.log(chalk14.dim("Cancelled"));
|
|
7221
7410
|
return;
|
|
7222
7411
|
}
|
|
7223
7412
|
volumeName = name;
|
|
7224
7413
|
}
|
|
7225
7414
|
if (!isValidStorageName(volumeName)) {
|
|
7226
|
-
console.error(
|
|
7415
|
+
console.error(chalk14.red(`\u2717 Invalid volume name: "${volumeName}"`));
|
|
7227
7416
|
console.error(
|
|
7228
|
-
|
|
7417
|
+
chalk14.dim(
|
|
7229
7418
|
" Volume names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7230
7419
|
)
|
|
7231
7420
|
);
|
|
7232
7421
|
console.error(
|
|
7233
|
-
|
|
7422
|
+
chalk14.dim(" Example: my-dataset, user-data-v2, training-set-2024")
|
|
7234
7423
|
);
|
|
7235
7424
|
process.exit(1);
|
|
7236
7425
|
}
|
|
7237
7426
|
await writeStorageConfig(volumeName, cwd);
|
|
7238
|
-
console.log(
|
|
7427
|
+
console.log(chalk14.green(`\u2713 Initialized volume: ${volumeName}`));
|
|
7239
7428
|
console.log(
|
|
7240
|
-
|
|
7429
|
+
chalk14.dim(
|
|
7241
7430
|
` Config saved to ${path6.join(cwd, ".vm0", "storage.yaml")}`
|
|
7242
7431
|
)
|
|
7243
7432
|
);
|
|
7244
7433
|
} catch (error) {
|
|
7245
|
-
console.error(
|
|
7434
|
+
console.error(chalk14.red("\u2717 Failed to initialize volume"));
|
|
7246
7435
|
if (error instanceof Error) {
|
|
7247
|
-
console.error(
|
|
7436
|
+
console.error(chalk14.dim(` ${error.message}`));
|
|
7248
7437
|
}
|
|
7249
7438
|
process.exit(1);
|
|
7250
7439
|
}
|
|
@@ -7252,7 +7441,7 @@ var initCommand = new Command13().name("init").description("Initialize a volume
|
|
|
7252
7441
|
|
|
7253
7442
|
// src/commands/volume/push.ts
|
|
7254
7443
|
import { Command as Command14 } from "commander";
|
|
7255
|
-
import
|
|
7444
|
+
import chalk15 from "chalk";
|
|
7256
7445
|
var pushCommand = new Command14().name("push").description("Push local files to cloud volume").option(
|
|
7257
7446
|
"-f, --force",
|
|
7258
7447
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7261,35 +7450,35 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
7261
7450
|
const cwd = process.cwd();
|
|
7262
7451
|
const config = await readStorageConfig(cwd);
|
|
7263
7452
|
if (!config) {
|
|
7264
|
-
console.error(
|
|
7265
|
-
console.error(
|
|
7453
|
+
console.error(chalk15.red("\u2717 No volume initialized in this directory"));
|
|
7454
|
+
console.error(chalk15.dim(" Run: vm0 volume init"));
|
|
7266
7455
|
process.exit(1);
|
|
7267
7456
|
}
|
|
7268
7457
|
console.log(`Pushing volume: ${config.name}`);
|
|
7269
7458
|
const result = await directUpload(config.name, "volume", cwd, {
|
|
7270
7459
|
onProgress: (message) => {
|
|
7271
|
-
console.log(
|
|
7460
|
+
console.log(chalk15.dim(message));
|
|
7272
7461
|
},
|
|
7273
7462
|
force: options.force
|
|
7274
7463
|
});
|
|
7275
7464
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7276
7465
|
if (result.empty) {
|
|
7277
|
-
console.log(
|
|
7466
|
+
console.log(chalk15.dim("No files found (empty volume)"));
|
|
7278
7467
|
} else if (result.deduplicated) {
|
|
7279
|
-
console.log(
|
|
7468
|
+
console.log(chalk15.green("\u2713 Content unchanged (deduplicated)"));
|
|
7280
7469
|
} else {
|
|
7281
|
-
console.log(
|
|
7470
|
+
console.log(chalk15.green("\u2713 Upload complete"));
|
|
7282
7471
|
}
|
|
7283
|
-
console.log(
|
|
7284
|
-
console.log(
|
|
7285
|
-
console.log(
|
|
7472
|
+
console.log(chalk15.dim(` Version: ${shortVersion}`));
|
|
7473
|
+
console.log(chalk15.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7474
|
+
console.log(chalk15.dim(` Size: ${formatBytes(result.size)}`));
|
|
7286
7475
|
} catch (error) {
|
|
7287
|
-
console.error(
|
|
7476
|
+
console.error(chalk15.red("\u2717 Push failed"));
|
|
7288
7477
|
if (error instanceof Error) {
|
|
7289
7478
|
if (error.message.includes("Not authenticated")) {
|
|
7290
|
-
console.error(
|
|
7479
|
+
console.error(chalk15.dim(" Run: vm0 auth login"));
|
|
7291
7480
|
} else {
|
|
7292
|
-
console.error(
|
|
7481
|
+
console.error(chalk15.dim(` ${error.message}`));
|
|
7293
7482
|
}
|
|
7294
7483
|
}
|
|
7295
7484
|
process.exit(1);
|
|
@@ -7298,21 +7487,21 @@ var pushCommand = new Command14().name("push").description("Push local files to
|
|
|
7298
7487
|
|
|
7299
7488
|
// src/commands/volume/pull.ts
|
|
7300
7489
|
import { Command as Command15 } from "commander";
|
|
7301
|
-
import
|
|
7490
|
+
import chalk17 from "chalk";
|
|
7302
7491
|
import path7 from "path";
|
|
7303
7492
|
import * as fs6 from "fs";
|
|
7304
7493
|
import * as os4 from "os";
|
|
7305
7494
|
import * as tar3 from "tar";
|
|
7306
7495
|
|
|
7307
7496
|
// src/lib/storage/pull-utils.ts
|
|
7308
|
-
import
|
|
7497
|
+
import chalk16 from "chalk";
|
|
7309
7498
|
async function handleEmptyStorageResponse(cwd) {
|
|
7310
|
-
console.log(
|
|
7499
|
+
console.log(chalk16.dim("Syncing local files..."));
|
|
7311
7500
|
const removedCount = await removeExtraFiles(cwd, /* @__PURE__ */ new Set());
|
|
7312
7501
|
if (removedCount > 0) {
|
|
7313
|
-
console.log(
|
|
7502
|
+
console.log(chalk16.green(`\u2713 Removed ${removedCount} files not in remote`));
|
|
7314
7503
|
}
|
|
7315
|
-
console.log(
|
|
7504
|
+
console.log(chalk16.green("\u2713 Synced (0 files)"));
|
|
7316
7505
|
return { removedCount };
|
|
7317
7506
|
}
|
|
7318
7507
|
|
|
@@ -7322,8 +7511,8 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7322
7511
|
const cwd = process.cwd();
|
|
7323
7512
|
const config = await readStorageConfig(cwd);
|
|
7324
7513
|
if (!config) {
|
|
7325
|
-
console.error(
|
|
7326
|
-
console.error(
|
|
7514
|
+
console.error(chalk17.red("\u2717 No volume initialized in this directory"));
|
|
7515
|
+
console.error(chalk17.dim(" Run: vm0 volume init"));
|
|
7327
7516
|
process.exit(1);
|
|
7328
7517
|
}
|
|
7329
7518
|
if (versionId) {
|
|
@@ -7331,7 +7520,7 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7331
7520
|
} else {
|
|
7332
7521
|
console.log(`Pulling volume: ${config.name}`);
|
|
7333
7522
|
}
|
|
7334
|
-
console.log(
|
|
7523
|
+
console.log(chalk17.dim("Getting download URL..."));
|
|
7335
7524
|
const downloadInfo = await getStorageDownload({
|
|
7336
7525
|
name: config.name,
|
|
7337
7526
|
type: "volume",
|
|
@@ -7345,18 +7534,18 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7345
7534
|
if (!downloadUrl) {
|
|
7346
7535
|
throw new Error("No download URL returned");
|
|
7347
7536
|
}
|
|
7348
|
-
console.log(
|
|
7537
|
+
console.log(chalk17.dim("Downloading from S3..."));
|
|
7349
7538
|
const s3Response = await fetch(downloadUrl);
|
|
7350
7539
|
if (!s3Response.ok) {
|
|
7351
7540
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7352
7541
|
}
|
|
7353
7542
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7354
7543
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7355
|
-
console.log(
|
|
7544
|
+
console.log(chalk17.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7356
7545
|
const tmpDir = fs6.mkdtempSync(path7.join(os4.tmpdir(), "vm0-"));
|
|
7357
7546
|
const tarPath = path7.join(tmpDir, "volume.tar.gz");
|
|
7358
7547
|
await fs6.promises.writeFile(tarPath, tarBuffer);
|
|
7359
|
-
console.log(
|
|
7548
|
+
console.log(chalk17.dim("Syncing local files..."));
|
|
7360
7549
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7361
7550
|
const remoteFilesSet = new Set(
|
|
7362
7551
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7364,10 +7553,10 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7364
7553
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7365
7554
|
if (removedCount > 0) {
|
|
7366
7555
|
console.log(
|
|
7367
|
-
|
|
7556
|
+
chalk17.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7368
7557
|
);
|
|
7369
7558
|
}
|
|
7370
|
-
console.log(
|
|
7559
|
+
console.log(chalk17.dim("Extracting files..."));
|
|
7371
7560
|
await tar3.extract({
|
|
7372
7561
|
file: tarPath,
|
|
7373
7562
|
cwd,
|
|
@@ -7375,14 +7564,14 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7375
7564
|
});
|
|
7376
7565
|
await fs6.promises.unlink(tarPath);
|
|
7377
7566
|
await fs6.promises.rmdir(tmpDir);
|
|
7378
|
-
console.log(
|
|
7567
|
+
console.log(chalk17.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7379
7568
|
} catch (error) {
|
|
7380
|
-
console.error(
|
|
7569
|
+
console.error(chalk17.red("\u2717 Pull failed"));
|
|
7381
7570
|
if (error instanceof Error) {
|
|
7382
7571
|
if (error.message.includes("Not authenticated")) {
|
|
7383
|
-
console.error(
|
|
7572
|
+
console.error(chalk17.dim(" Run: vm0 auth login"));
|
|
7384
7573
|
} else {
|
|
7385
|
-
console.error(
|
|
7574
|
+
console.error(chalk17.dim(` ${error.message}`));
|
|
7386
7575
|
}
|
|
7387
7576
|
}
|
|
7388
7577
|
process.exit(1);
|
|
@@ -7391,23 +7580,23 @@ var pullCommand = new Command15().name("pull").description("Pull cloud files to
|
|
|
7391
7580
|
|
|
7392
7581
|
// src/commands/volume/status.ts
|
|
7393
7582
|
import { Command as Command16 } from "commander";
|
|
7394
|
-
import
|
|
7583
|
+
import chalk18 from "chalk";
|
|
7395
7584
|
var statusCommand2 = new Command16().name("status").description("Show status of cloud volume").action(async () => {
|
|
7396
7585
|
try {
|
|
7397
7586
|
const cwd = process.cwd();
|
|
7398
7587
|
const config = await readStorageConfig(cwd);
|
|
7399
7588
|
if (!config) {
|
|
7400
|
-
console.error(
|
|
7401
|
-
console.error(
|
|
7589
|
+
console.error(chalk18.red("\u2717 No volume initialized in this directory"));
|
|
7590
|
+
console.error(chalk18.dim(" Run: vm0 volume init"));
|
|
7402
7591
|
process.exit(1);
|
|
7403
7592
|
}
|
|
7404
7593
|
if (config.type !== "volume") {
|
|
7405
7594
|
console.error(
|
|
7406
|
-
|
|
7595
|
+
chalk18.red(
|
|
7407
7596
|
"\u2717 This directory is initialized as an artifact, not a volume"
|
|
7408
7597
|
)
|
|
7409
7598
|
);
|
|
7410
|
-
console.error(
|
|
7599
|
+
console.error(chalk18.dim(" Use: vm0 artifact status"));
|
|
7411
7600
|
process.exit(1);
|
|
7412
7601
|
}
|
|
7413
7602
|
console.log(`Checking volume: ${config.name}`);
|
|
@@ -7417,25 +7606,25 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7417
7606
|
});
|
|
7418
7607
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7419
7608
|
if ("empty" in info) {
|
|
7420
|
-
console.log(
|
|
7421
|
-
console.log(
|
|
7609
|
+
console.log(chalk18.green("\u2713 Found (empty)"));
|
|
7610
|
+
console.log(chalk18.dim(` Version: ${shortVersion}`));
|
|
7422
7611
|
} else {
|
|
7423
|
-
console.log(
|
|
7424
|
-
console.log(
|
|
7425
|
-
console.log(
|
|
7426
|
-
console.log(
|
|
7612
|
+
console.log(chalk18.green("\u2713 Found"));
|
|
7613
|
+
console.log(chalk18.dim(` Version: ${shortVersion}`));
|
|
7614
|
+
console.log(chalk18.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
7615
|
+
console.log(chalk18.dim(` Size: ${formatBytes(info.size)}`));
|
|
7427
7616
|
}
|
|
7428
7617
|
} catch (error) {
|
|
7429
7618
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7430
|
-
console.error(
|
|
7431
|
-
console.error(
|
|
7619
|
+
console.error(chalk18.red("\u2717 Not found on remote"));
|
|
7620
|
+
console.error(chalk18.dim(" Run: vm0 volume push"));
|
|
7432
7621
|
} else {
|
|
7433
|
-
console.error(
|
|
7622
|
+
console.error(chalk18.red("\u2717 Status check failed"));
|
|
7434
7623
|
if (error instanceof Error) {
|
|
7435
7624
|
if (error.message.includes("Not authenticated")) {
|
|
7436
|
-
console.error(
|
|
7625
|
+
console.error(chalk18.dim(" Run: vm0 auth login"));
|
|
7437
7626
|
} else {
|
|
7438
|
-
console.error(
|
|
7627
|
+
console.error(chalk18.dim(` ${error.message}`));
|
|
7439
7628
|
}
|
|
7440
7629
|
}
|
|
7441
7630
|
}
|
|
@@ -7445,14 +7634,14 @@ var statusCommand2 = new Command16().name("status").description("Show status of
|
|
|
7445
7634
|
|
|
7446
7635
|
// src/commands/volume/list.ts
|
|
7447
7636
|
import { Command as Command17 } from "commander";
|
|
7448
|
-
import
|
|
7637
|
+
import chalk19 from "chalk";
|
|
7449
7638
|
var listCommand2 = new Command17().name("list").alias("ls").description("List all remote volumes").action(async () => {
|
|
7450
7639
|
try {
|
|
7451
7640
|
const items = await listStorages({ type: "volume" });
|
|
7452
7641
|
if (items.length === 0) {
|
|
7453
|
-
console.log(
|
|
7642
|
+
console.log(chalk19.dim("No volumes found"));
|
|
7454
7643
|
console.log(
|
|
7455
|
-
|
|
7644
|
+
chalk19.dim(" Create one with: vm0 volume init && vm0 volume push")
|
|
7456
7645
|
);
|
|
7457
7646
|
return;
|
|
7458
7647
|
}
|
|
@@ -7471,7 +7660,7 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7471
7660
|
"FILES".padStart(filesWidth),
|
|
7472
7661
|
"UPDATED"
|
|
7473
7662
|
].join(" ");
|
|
7474
|
-
console.log(
|
|
7663
|
+
console.log(chalk19.dim(header));
|
|
7475
7664
|
for (const item of items) {
|
|
7476
7665
|
const row = [
|
|
7477
7666
|
item.name.padEnd(nameWidth),
|
|
@@ -7482,12 +7671,12 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7482
7671
|
console.log(row);
|
|
7483
7672
|
}
|
|
7484
7673
|
} catch (error) {
|
|
7485
|
-
console.error(
|
|
7674
|
+
console.error(chalk19.red("\u2717 Failed to list volumes"));
|
|
7486
7675
|
if (error instanceof Error) {
|
|
7487
7676
|
if (error.message.includes("Not authenticated")) {
|
|
7488
|
-
console.error(
|
|
7677
|
+
console.error(chalk19.dim(" Run: vm0 auth login"));
|
|
7489
7678
|
} else {
|
|
7490
|
-
console.error(
|
|
7679
|
+
console.error(chalk19.dim(` ${error.message}`));
|
|
7491
7680
|
}
|
|
7492
7681
|
}
|
|
7493
7682
|
process.exit(1);
|
|
@@ -7496,10 +7685,10 @@ var listCommand2 = new Command17().name("list").alias("ls").description("List al
|
|
|
7496
7685
|
|
|
7497
7686
|
// src/commands/volume/clone.ts
|
|
7498
7687
|
import { Command as Command18 } from "commander";
|
|
7499
|
-
import
|
|
7688
|
+
import chalk21 from "chalk";
|
|
7500
7689
|
|
|
7501
7690
|
// src/lib/storage/clone-utils.ts
|
|
7502
|
-
import
|
|
7691
|
+
import chalk20 from "chalk";
|
|
7503
7692
|
import path8 from "path";
|
|
7504
7693
|
import * as fs7 from "fs";
|
|
7505
7694
|
import * as os5 from "os";
|
|
@@ -7509,18 +7698,18 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7509
7698
|
if (fs7.existsSync(destination)) {
|
|
7510
7699
|
throw new Error(`Directory "${destination}" already exists`);
|
|
7511
7700
|
}
|
|
7512
|
-
console.log(
|
|
7701
|
+
console.log(chalk20.dim(`Checking remote ${typeLabel}...`));
|
|
7513
7702
|
const downloadInfo = await getStorageDownload({
|
|
7514
7703
|
name,
|
|
7515
7704
|
type,
|
|
7516
7705
|
version: options.version
|
|
7517
7706
|
});
|
|
7518
|
-
console.log(
|
|
7707
|
+
console.log(chalk20.dim(`Creating directory: ${destination}/`));
|
|
7519
7708
|
await fs7.promises.mkdir(destination, { recursive: true });
|
|
7520
7709
|
if ("empty" in downloadInfo) {
|
|
7521
7710
|
await writeStorageConfig(name, destination, type);
|
|
7522
|
-
console.log(
|
|
7523
|
-
console.log(
|
|
7711
|
+
console.log(chalk20.green(`\u2713 Cloned empty ${typeLabel}: ${name}`));
|
|
7712
|
+
console.log(chalk20.dim(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7524
7713
|
return {
|
|
7525
7714
|
success: true,
|
|
7526
7715
|
fileCount: 0,
|
|
@@ -7532,7 +7721,7 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7532
7721
|
if (!downloadUrl) {
|
|
7533
7722
|
throw new Error("No download URL returned");
|
|
7534
7723
|
}
|
|
7535
|
-
console.log(
|
|
7724
|
+
console.log(chalk20.dim("Downloading from S3..."));
|
|
7536
7725
|
const s3Response = await fetch(downloadUrl);
|
|
7537
7726
|
if (!s3Response.ok) {
|
|
7538
7727
|
await fs7.promises.rm(destination, { recursive: true, force: true });
|
|
@@ -7540,12 +7729,12 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7540
7729
|
}
|
|
7541
7730
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7542
7731
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7543
|
-
console.log(
|
|
7732
|
+
console.log(chalk20.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7544
7733
|
const tmpDir = fs7.mkdtempSync(path8.join(os5.tmpdir(), "vm0-clone-"));
|
|
7545
7734
|
const tarPath = path8.join(tmpDir, "archive.tar.gz");
|
|
7546
7735
|
await fs7.promises.writeFile(tarPath, tarBuffer);
|
|
7547
7736
|
const files = await listTarFiles(tarPath);
|
|
7548
|
-
console.log(
|
|
7737
|
+
console.log(chalk20.dim("Extracting files..."));
|
|
7549
7738
|
await tar4.extract({
|
|
7550
7739
|
file: tarPath,
|
|
7551
7740
|
cwd: destination,
|
|
@@ -7553,9 +7742,9 @@ async function cloneStorage(name, type, destination, options = {}) {
|
|
|
7553
7742
|
});
|
|
7554
7743
|
await fs7.promises.unlink(tarPath);
|
|
7555
7744
|
await fs7.promises.rmdir(tmpDir);
|
|
7556
|
-
console.log(
|
|
7745
|
+
console.log(chalk20.green(`\u2713 Extracted ${files.length} files`));
|
|
7557
7746
|
await writeStorageConfig(name, destination, type);
|
|
7558
|
-
console.log(
|
|
7747
|
+
console.log(chalk20.green(`\u2713 Initialized .vm0/storage.yaml`));
|
|
7559
7748
|
return {
|
|
7560
7749
|
success: true,
|
|
7561
7750
|
fileCount: downloadInfo.fileCount,
|
|
@@ -7570,17 +7759,17 @@ var cloneCommand = new Command18().name("clone").description("Clone a remote vol
|
|
|
7570
7759
|
const targetDir = destination || name;
|
|
7571
7760
|
console.log(`Cloning volume: ${name}`);
|
|
7572
7761
|
const result = await cloneStorage(name, "volume", targetDir);
|
|
7573
|
-
console.log(
|
|
7762
|
+
console.log(chalk21.green(`
|
|
7574
7763
|
\u2713 Successfully cloned volume: ${name}`));
|
|
7575
|
-
console.log(
|
|
7576
|
-
console.log(
|
|
7764
|
+
console.log(chalk21.dim(` Location: ${targetDir}/`));
|
|
7765
|
+
console.log(chalk21.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7577
7766
|
} catch (error) {
|
|
7578
|
-
console.error(
|
|
7767
|
+
console.error(chalk21.red("\u2717 Clone failed"));
|
|
7579
7768
|
if (error instanceof Error) {
|
|
7580
7769
|
if (error.message.includes("Not authenticated")) {
|
|
7581
|
-
console.error(
|
|
7770
|
+
console.error(chalk21.dim(" Run: vm0 auth login"));
|
|
7582
7771
|
} else {
|
|
7583
|
-
console.error(
|
|
7772
|
+
console.error(chalk21.dim(` ${error.message}`));
|
|
7584
7773
|
}
|
|
7585
7774
|
}
|
|
7586
7775
|
process.exit(1);
|
|
@@ -7595,7 +7784,7 @@ import { Command as Command26 } from "commander";
|
|
|
7595
7784
|
|
|
7596
7785
|
// src/commands/artifact/init.ts
|
|
7597
7786
|
import { Command as Command20 } from "commander";
|
|
7598
|
-
import
|
|
7787
|
+
import chalk22 from "chalk";
|
|
7599
7788
|
import path9 from "path";
|
|
7600
7789
|
var initCommand2 = new Command20().name("init").description("Initialize an artifact in the current directory").option(
|
|
7601
7790
|
"-n, --name <name>",
|
|
@@ -7608,24 +7797,24 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7608
7797
|
if (existingConfig) {
|
|
7609
7798
|
if (existingConfig.type === "artifact") {
|
|
7610
7799
|
console.log(
|
|
7611
|
-
|
|
7800
|
+
chalk22.yellow(
|
|
7612
7801
|
`Artifact already initialized: ${existingConfig.name}`
|
|
7613
7802
|
)
|
|
7614
7803
|
);
|
|
7615
7804
|
} else {
|
|
7616
7805
|
console.log(
|
|
7617
|
-
|
|
7806
|
+
chalk22.yellow(
|
|
7618
7807
|
`Directory already initialized as volume: ${existingConfig.name}`
|
|
7619
7808
|
)
|
|
7620
7809
|
);
|
|
7621
7810
|
console.log(
|
|
7622
|
-
|
|
7811
|
+
chalk22.dim(
|
|
7623
7812
|
" To change type, delete .vm0/storage.yaml and reinitialize"
|
|
7624
7813
|
)
|
|
7625
7814
|
);
|
|
7626
7815
|
}
|
|
7627
7816
|
console.log(
|
|
7628
|
-
|
|
7817
|
+
chalk22.dim(`Config file: ${path9.join(cwd, ".vm0", "storage.yaml")}`)
|
|
7629
7818
|
);
|
|
7630
7819
|
return;
|
|
7631
7820
|
}
|
|
@@ -7634,10 +7823,10 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7634
7823
|
artifactName = options.name;
|
|
7635
7824
|
} else if (!isInteractive()) {
|
|
7636
7825
|
console.error(
|
|
7637
|
-
|
|
7826
|
+
chalk22.red("\u2717 --name flag is required in non-interactive mode")
|
|
7638
7827
|
);
|
|
7639
7828
|
console.error(
|
|
7640
|
-
|
|
7829
|
+
chalk22.dim(" Usage: vm0 artifact init --name <artifact-name>")
|
|
7641
7830
|
);
|
|
7642
7831
|
process.exit(1);
|
|
7643
7832
|
} else {
|
|
@@ -7653,34 +7842,34 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7653
7842
|
}
|
|
7654
7843
|
);
|
|
7655
7844
|
if (name === void 0) {
|
|
7656
|
-
console.log(
|
|
7845
|
+
console.log(chalk22.dim("Cancelled"));
|
|
7657
7846
|
return;
|
|
7658
7847
|
}
|
|
7659
7848
|
artifactName = name;
|
|
7660
7849
|
}
|
|
7661
7850
|
if (!isValidStorageName(artifactName)) {
|
|
7662
|
-
console.error(
|
|
7851
|
+
console.error(chalk22.red(`\u2717 Invalid artifact name: "${artifactName}"`));
|
|
7663
7852
|
console.error(
|
|
7664
|
-
|
|
7853
|
+
chalk22.dim(
|
|
7665
7854
|
" Artifact names must be 3-64 characters, lowercase alphanumeric with hyphens"
|
|
7666
7855
|
)
|
|
7667
7856
|
);
|
|
7668
7857
|
console.error(
|
|
7669
|
-
|
|
7858
|
+
chalk22.dim(" Example: my-project, user-workspace, code-artifact")
|
|
7670
7859
|
);
|
|
7671
7860
|
process.exit(1);
|
|
7672
7861
|
}
|
|
7673
7862
|
await writeStorageConfig(artifactName, cwd, "artifact");
|
|
7674
|
-
console.log(
|
|
7863
|
+
console.log(chalk22.green(`\u2713 Initialized artifact: ${artifactName}`));
|
|
7675
7864
|
console.log(
|
|
7676
|
-
|
|
7865
|
+
chalk22.dim(
|
|
7677
7866
|
` Config saved to ${path9.join(cwd, ".vm0", "storage.yaml")}`
|
|
7678
7867
|
)
|
|
7679
7868
|
);
|
|
7680
7869
|
} catch (error) {
|
|
7681
|
-
console.error(
|
|
7870
|
+
console.error(chalk22.red("\u2717 Failed to initialize artifact"));
|
|
7682
7871
|
if (error instanceof Error) {
|
|
7683
|
-
console.error(
|
|
7872
|
+
console.error(chalk22.dim(` ${error.message}`));
|
|
7684
7873
|
}
|
|
7685
7874
|
process.exit(1);
|
|
7686
7875
|
}
|
|
@@ -7688,7 +7877,7 @@ var initCommand2 = new Command20().name("init").description("Initialize an artif
|
|
|
7688
7877
|
|
|
7689
7878
|
// src/commands/artifact/push.ts
|
|
7690
7879
|
import { Command as Command21 } from "commander";
|
|
7691
|
-
import
|
|
7880
|
+
import chalk23 from "chalk";
|
|
7692
7881
|
var pushCommand2 = new Command21().name("push").description("Push local files to cloud artifact").option(
|
|
7693
7882
|
"-f, --force",
|
|
7694
7883
|
"Force upload even if content unchanged (recreate archive)"
|
|
@@ -7697,41 +7886,41 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7697
7886
|
const cwd = process.cwd();
|
|
7698
7887
|
const config = await readStorageConfig(cwd);
|
|
7699
7888
|
if (!config) {
|
|
7700
|
-
console.error(
|
|
7701
|
-
console.error(
|
|
7889
|
+
console.error(chalk23.red("\u2717 No artifact initialized in this directory"));
|
|
7890
|
+
console.error(chalk23.dim(" Run: vm0 artifact init"));
|
|
7702
7891
|
process.exit(1);
|
|
7703
7892
|
}
|
|
7704
7893
|
if (config.type !== "artifact") {
|
|
7705
7894
|
console.error(
|
|
7706
|
-
|
|
7895
|
+
chalk23.red(
|
|
7707
7896
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7708
7897
|
)
|
|
7709
7898
|
);
|
|
7710
|
-
console.error(
|
|
7899
|
+
console.error(chalk23.dim(" Use: vm0 volume push"));
|
|
7711
7900
|
process.exit(1);
|
|
7712
7901
|
}
|
|
7713
7902
|
console.log(`Pushing artifact: ${config.name}`);
|
|
7714
7903
|
const result = await directUpload(config.name, "artifact", cwd, {
|
|
7715
7904
|
onProgress: (message) => {
|
|
7716
|
-
console.log(
|
|
7905
|
+
console.log(chalk23.dim(message));
|
|
7717
7906
|
},
|
|
7718
7907
|
force: options.force
|
|
7719
7908
|
});
|
|
7720
7909
|
const shortVersion = result.versionId.slice(0, 8);
|
|
7721
7910
|
if (result.empty) {
|
|
7722
|
-
console.log(
|
|
7911
|
+
console.log(chalk23.dim("No files found (empty artifact)"));
|
|
7723
7912
|
} else if (result.deduplicated) {
|
|
7724
|
-
console.log(
|
|
7913
|
+
console.log(chalk23.green("\u2713 Content unchanged (deduplicated)"));
|
|
7725
7914
|
} else {
|
|
7726
|
-
console.log(
|
|
7915
|
+
console.log(chalk23.green("\u2713 Upload complete"));
|
|
7727
7916
|
}
|
|
7728
|
-
console.log(
|
|
7729
|
-
console.log(
|
|
7730
|
-
console.log(
|
|
7917
|
+
console.log(chalk23.dim(` Version: ${shortVersion}`));
|
|
7918
|
+
console.log(chalk23.dim(` Files: ${result.fileCount.toLocaleString()}`));
|
|
7919
|
+
console.log(chalk23.dim(` Size: ${formatBytes(result.size)}`));
|
|
7731
7920
|
} catch (error) {
|
|
7732
|
-
console.error(
|
|
7921
|
+
console.error(chalk23.red("\u2717 Push failed"));
|
|
7733
7922
|
if (error instanceof Error) {
|
|
7734
|
-
console.error(
|
|
7923
|
+
console.error(chalk23.dim(` ${error.message}`));
|
|
7735
7924
|
}
|
|
7736
7925
|
process.exit(1);
|
|
7737
7926
|
}
|
|
@@ -7739,7 +7928,7 @@ var pushCommand2 = new Command21().name("push").description("Push local files to
|
|
|
7739
7928
|
|
|
7740
7929
|
// src/commands/artifact/pull.ts
|
|
7741
7930
|
import { Command as Command22 } from "commander";
|
|
7742
|
-
import
|
|
7931
|
+
import chalk24 from "chalk";
|
|
7743
7932
|
import path10 from "path";
|
|
7744
7933
|
import * as fs8 from "fs";
|
|
7745
7934
|
import * as os6 from "os";
|
|
@@ -7749,17 +7938,17 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7749
7938
|
const cwd = process.cwd();
|
|
7750
7939
|
const config = await readStorageConfig(cwd);
|
|
7751
7940
|
if (!config) {
|
|
7752
|
-
console.error(
|
|
7753
|
-
console.error(
|
|
7941
|
+
console.error(chalk24.red("\u2717 No artifact initialized in this directory"));
|
|
7942
|
+
console.error(chalk24.dim(" Run: vm0 artifact init"));
|
|
7754
7943
|
process.exit(1);
|
|
7755
7944
|
}
|
|
7756
7945
|
if (config.type !== "artifact") {
|
|
7757
7946
|
console.error(
|
|
7758
|
-
|
|
7947
|
+
chalk24.red(
|
|
7759
7948
|
`\u2717 This directory is initialized as a volume, not an artifact`
|
|
7760
7949
|
)
|
|
7761
7950
|
);
|
|
7762
|
-
console.error(
|
|
7951
|
+
console.error(chalk24.dim(" Use: vm0 volume pull"));
|
|
7763
7952
|
process.exit(1);
|
|
7764
7953
|
}
|
|
7765
7954
|
if (versionId) {
|
|
@@ -7767,7 +7956,7 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7767
7956
|
} else {
|
|
7768
7957
|
console.log(`Pulling artifact: ${config.name}`);
|
|
7769
7958
|
}
|
|
7770
|
-
console.log(
|
|
7959
|
+
console.log(chalk24.dim("Getting download URL..."));
|
|
7771
7960
|
const downloadInfo = await getStorageDownload({
|
|
7772
7961
|
name: config.name,
|
|
7773
7962
|
type: "artifact",
|
|
@@ -7781,18 +7970,18 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7781
7970
|
if (!downloadUrl) {
|
|
7782
7971
|
throw new Error("No download URL returned");
|
|
7783
7972
|
}
|
|
7784
|
-
console.log(
|
|
7973
|
+
console.log(chalk24.dim("Downloading from S3..."));
|
|
7785
7974
|
const s3Response = await fetch(downloadUrl);
|
|
7786
7975
|
if (!s3Response.ok) {
|
|
7787
7976
|
throw new Error(`S3 download failed: ${s3Response.status}`);
|
|
7788
7977
|
}
|
|
7789
7978
|
const arrayBuffer = await s3Response.arrayBuffer();
|
|
7790
7979
|
const tarBuffer = Buffer.from(arrayBuffer);
|
|
7791
|
-
console.log(
|
|
7980
|
+
console.log(chalk24.green(`\u2713 Downloaded ${formatBytes(tarBuffer.length)}`));
|
|
7792
7981
|
const tmpDir = fs8.mkdtempSync(path10.join(os6.tmpdir(), "vm0-"));
|
|
7793
7982
|
const tarPath = path10.join(tmpDir, "artifact.tar.gz");
|
|
7794
7983
|
await fs8.promises.writeFile(tarPath, tarBuffer);
|
|
7795
|
-
console.log(
|
|
7984
|
+
console.log(chalk24.dim("Syncing local files..."));
|
|
7796
7985
|
const remoteFiles = await listTarFiles(tarPath);
|
|
7797
7986
|
const remoteFilesSet = new Set(
|
|
7798
7987
|
remoteFiles.map((f) => f.replace(/\\/g, "/"))
|
|
@@ -7800,10 +7989,10 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7800
7989
|
const removedCount = await removeExtraFiles(cwd, remoteFilesSet);
|
|
7801
7990
|
if (removedCount > 0) {
|
|
7802
7991
|
console.log(
|
|
7803
|
-
|
|
7992
|
+
chalk24.green(`\u2713 Removed ${removedCount} files not in remote`)
|
|
7804
7993
|
);
|
|
7805
7994
|
}
|
|
7806
|
-
console.log(
|
|
7995
|
+
console.log(chalk24.dim("Extracting files..."));
|
|
7807
7996
|
await tar5.extract({
|
|
7808
7997
|
file: tarPath,
|
|
7809
7998
|
cwd,
|
|
@@ -7811,11 +8000,11 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7811
8000
|
});
|
|
7812
8001
|
await fs8.promises.unlink(tarPath);
|
|
7813
8002
|
await fs8.promises.rmdir(tmpDir);
|
|
7814
|
-
console.log(
|
|
8003
|
+
console.log(chalk24.green(`\u2713 Extracted ${remoteFiles.length} files`));
|
|
7815
8004
|
} catch (error) {
|
|
7816
|
-
console.error(
|
|
8005
|
+
console.error(chalk24.red("\u2717 Pull failed"));
|
|
7817
8006
|
if (error instanceof Error) {
|
|
7818
|
-
console.error(
|
|
8007
|
+
console.error(chalk24.dim(` ${error.message}`));
|
|
7819
8008
|
}
|
|
7820
8009
|
process.exit(1);
|
|
7821
8010
|
}
|
|
@@ -7823,23 +8012,23 @@ var pullCommand2 = new Command22().name("pull").description("Pull cloud artifact
|
|
|
7823
8012
|
|
|
7824
8013
|
// src/commands/artifact/status.ts
|
|
7825
8014
|
import { Command as Command23 } from "commander";
|
|
7826
|
-
import
|
|
8015
|
+
import chalk25 from "chalk";
|
|
7827
8016
|
var statusCommand3 = new Command23().name("status").description("Show status of cloud artifact").action(async () => {
|
|
7828
8017
|
try {
|
|
7829
8018
|
const cwd = process.cwd();
|
|
7830
8019
|
const config = await readStorageConfig(cwd);
|
|
7831
8020
|
if (!config) {
|
|
7832
|
-
console.error(
|
|
7833
|
-
console.error(
|
|
8021
|
+
console.error(chalk25.red("\u2717 No artifact initialized in this directory"));
|
|
8022
|
+
console.error(chalk25.dim(" Run: vm0 artifact init"));
|
|
7834
8023
|
process.exit(1);
|
|
7835
8024
|
}
|
|
7836
8025
|
if (config.type !== "artifact") {
|
|
7837
8026
|
console.error(
|
|
7838
|
-
|
|
8027
|
+
chalk25.red(
|
|
7839
8028
|
"\u2717 This directory is initialized as a volume, not an artifact"
|
|
7840
8029
|
)
|
|
7841
8030
|
);
|
|
7842
|
-
console.error(
|
|
8031
|
+
console.error(chalk25.dim(" Use: vm0 volume status"));
|
|
7843
8032
|
process.exit(1);
|
|
7844
8033
|
}
|
|
7845
8034
|
console.log(`Checking artifact: ${config.name}`);
|
|
@@ -7849,22 +8038,22 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7849
8038
|
});
|
|
7850
8039
|
const shortVersion = info.versionId.slice(0, 8);
|
|
7851
8040
|
if ("empty" in info) {
|
|
7852
|
-
console.log(
|
|
7853
|
-
console.log(
|
|
8041
|
+
console.log(chalk25.green("\u2713 Found (empty)"));
|
|
8042
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
7854
8043
|
} else {
|
|
7855
|
-
console.log(
|
|
7856
|
-
console.log(
|
|
7857
|
-
console.log(
|
|
7858
|
-
console.log(
|
|
8044
|
+
console.log(chalk25.green("\u2713 Found"));
|
|
8045
|
+
console.log(chalk25.dim(` Version: ${shortVersion}`));
|
|
8046
|
+
console.log(chalk25.dim(` Files: ${info.fileCount.toLocaleString()}`));
|
|
8047
|
+
console.log(chalk25.dim(` Size: ${formatBytes(info.size)}`));
|
|
7859
8048
|
}
|
|
7860
8049
|
} catch (error) {
|
|
7861
8050
|
if (error instanceof Error && error.message.includes("not found")) {
|
|
7862
|
-
console.error(
|
|
7863
|
-
console.error(
|
|
8051
|
+
console.error(chalk25.red("\u2717 Not found on remote"));
|
|
8052
|
+
console.error(chalk25.dim(" Run: vm0 artifact push"));
|
|
7864
8053
|
} else {
|
|
7865
|
-
console.error(
|
|
8054
|
+
console.error(chalk25.red("\u2717 Status check failed"));
|
|
7866
8055
|
if (error instanceof Error) {
|
|
7867
|
-
console.error(
|
|
8056
|
+
console.error(chalk25.dim(` ${error.message}`));
|
|
7868
8057
|
}
|
|
7869
8058
|
}
|
|
7870
8059
|
process.exit(1);
|
|
@@ -7873,14 +8062,14 @@ var statusCommand3 = new Command23().name("status").description("Show status of
|
|
|
7873
8062
|
|
|
7874
8063
|
// src/commands/artifact/list.ts
|
|
7875
8064
|
import { Command as Command24 } from "commander";
|
|
7876
|
-
import
|
|
8065
|
+
import chalk26 from "chalk";
|
|
7877
8066
|
var listCommand3 = new Command24().name("list").alias("ls").description("List all remote artifacts").action(async () => {
|
|
7878
8067
|
try {
|
|
7879
8068
|
const items = await listStorages({ type: "artifact" });
|
|
7880
8069
|
if (items.length === 0) {
|
|
7881
|
-
console.log(
|
|
8070
|
+
console.log(chalk26.dim("No artifacts found"));
|
|
7882
8071
|
console.log(
|
|
7883
|
-
|
|
8072
|
+
chalk26.dim(
|
|
7884
8073
|
" Create one with: vm0 artifact init && vm0 artifact push"
|
|
7885
8074
|
)
|
|
7886
8075
|
);
|
|
@@ -7901,7 +8090,7 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7901
8090
|
"FILES".padStart(filesWidth),
|
|
7902
8091
|
"UPDATED"
|
|
7903
8092
|
].join(" ");
|
|
7904
|
-
console.log(
|
|
8093
|
+
console.log(chalk26.dim(header));
|
|
7905
8094
|
for (const item of items) {
|
|
7906
8095
|
const row = [
|
|
7907
8096
|
item.name.padEnd(nameWidth),
|
|
@@ -7912,12 +8101,12 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7912
8101
|
console.log(row);
|
|
7913
8102
|
}
|
|
7914
8103
|
} catch (error) {
|
|
7915
|
-
console.error(
|
|
8104
|
+
console.error(chalk26.red("\u2717 Failed to list artifacts"));
|
|
7916
8105
|
if (error instanceof Error) {
|
|
7917
8106
|
if (error.message.includes("Not authenticated")) {
|
|
7918
|
-
console.error(
|
|
8107
|
+
console.error(chalk26.dim(" Run: vm0 auth login"));
|
|
7919
8108
|
} else {
|
|
7920
|
-
console.error(
|
|
8109
|
+
console.error(chalk26.dim(` ${error.message}`));
|
|
7921
8110
|
}
|
|
7922
8111
|
}
|
|
7923
8112
|
process.exit(1);
|
|
@@ -7926,23 +8115,23 @@ var listCommand3 = new Command24().name("list").alias("ls").description("List al
|
|
|
7926
8115
|
|
|
7927
8116
|
// src/commands/artifact/clone.ts
|
|
7928
8117
|
import { Command as Command25 } from "commander";
|
|
7929
|
-
import
|
|
8118
|
+
import chalk27 from "chalk";
|
|
7930
8119
|
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
8120
|
try {
|
|
7932
8121
|
const targetDir = destination || name;
|
|
7933
8122
|
console.log(`Cloning artifact: ${name}`);
|
|
7934
8123
|
const result = await cloneStorage(name, "artifact", targetDir);
|
|
7935
|
-
console.log(
|
|
8124
|
+
console.log(chalk27.green(`
|
|
7936
8125
|
\u2713 Successfully cloned artifact: ${name}`));
|
|
7937
|
-
console.log(
|
|
7938
|
-
console.log(
|
|
8126
|
+
console.log(chalk27.dim(` Location: ${targetDir}/`));
|
|
8127
|
+
console.log(chalk27.dim(` Version: ${result.versionId.slice(0, 8)}`));
|
|
7939
8128
|
} catch (error) {
|
|
7940
|
-
console.error(
|
|
8129
|
+
console.error(chalk27.red("\u2717 Clone failed"));
|
|
7941
8130
|
if (error instanceof Error) {
|
|
7942
8131
|
if (error.message.includes("Not authenticated")) {
|
|
7943
|
-
console.error(
|
|
8132
|
+
console.error(chalk27.dim(" Run: vm0 auth login"));
|
|
7944
8133
|
} else {
|
|
7945
|
-
console.error(
|
|
8134
|
+
console.error(chalk27.dim(` ${error.message}`));
|
|
7946
8135
|
}
|
|
7947
8136
|
}
|
|
7948
8137
|
process.exit(1);
|
|
@@ -7953,7 +8142,7 @@ var cloneCommand2 = new Command25().name("clone").description("Clone a remote ar
|
|
|
7953
8142
|
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
8143
|
|
|
7955
8144
|
// src/commands/cook/cook.ts
|
|
7956
|
-
import { Command as Command27, Option as
|
|
8145
|
+
import { Command as Command27, Option as Option5 } from "commander";
|
|
7957
8146
|
import chalk29 from "chalk";
|
|
7958
8147
|
import { readFile as readFile7, mkdir as mkdir6 } from "fs/promises";
|
|
7959
8148
|
import { existsSync as existsSync9 } from "fs";
|
|
@@ -7961,145 +8150,6 @@ import path11 from "path";
|
|
|
7961
8150
|
import { parse as parseYaml4 } from "yaml";
|
|
7962
8151
|
import { config as dotenvConfig2 } from "dotenv";
|
|
7963
8152
|
|
|
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
8153
|
// src/lib/domain/cook-state.ts
|
|
8104
8154
|
import { homedir as homedir2 } from "os";
|
|
8105
8155
|
import { join as join6 } from "path";
|
|
@@ -8498,10 +8548,10 @@ async function runAgent(agentName, artifactDir, prompt, cwd, options) {
|
|
|
8498
8548
|
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
8549
|
"--env-file <path>",
|
|
8500
8550
|
"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
|
|
8551
|
+
).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
8552
|
async (prompt, options) => {
|
|
8503
8553
|
if (!options.noAutoUpdate) {
|
|
8504
|
-
const shouldExit = await checkAndUpgrade("9.
|
|
8554
|
+
const shouldExit = await checkAndUpgrade("9.12.0", prompt);
|
|
8505
8555
|
if (shouldExit) {
|
|
8506
8556
|
process.exit(0);
|
|
8507
8557
|
}
|
|
@@ -8577,7 +8627,7 @@ var logsCommand = new Command28().name("logs").description("View logs from the l
|
|
|
8577
8627
|
);
|
|
8578
8628
|
|
|
8579
8629
|
// src/commands/cook/continue.ts
|
|
8580
|
-
import { Command as Command29, Option as
|
|
8630
|
+
import { Command as Command29, Option as Option6 } from "commander";
|
|
8581
8631
|
import chalk31 from "chalk";
|
|
8582
8632
|
import path12 from "path";
|
|
8583
8633
|
var continueCommand2 = new Command29().name("continue").description(
|
|
@@ -8585,7 +8635,7 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8585
8635
|
).argument("<prompt>", "Prompt for the continued agent").option(
|
|
8586
8636
|
"--env-file <path>",
|
|
8587
8637
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8588
|
-
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new
|
|
8638
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option6("--debug-no-mock-claude").hideHelp()).action(
|
|
8589
8639
|
async (prompt, options) => {
|
|
8590
8640
|
const state = await loadCookState();
|
|
8591
8641
|
if (!state.lastSessionId) {
|
|
@@ -8630,7 +8680,7 @@ var continueCommand2 = new Command29().name("continue").description(
|
|
|
8630
8680
|
);
|
|
8631
8681
|
|
|
8632
8682
|
// src/commands/cook/resume.ts
|
|
8633
|
-
import { Command as Command30, Option as
|
|
8683
|
+
import { Command as Command30, Option as Option7 } from "commander";
|
|
8634
8684
|
import chalk32 from "chalk";
|
|
8635
8685
|
import path13 from "path";
|
|
8636
8686
|
var resumeCommand2 = new Command30().name("resume").description(
|
|
@@ -8638,7 +8688,7 @@ var resumeCommand2 = new Command30().name("resume").description(
|
|
|
8638
8688
|
).argument("<prompt>", "Prompt for the resumed agent").option(
|
|
8639
8689
|
"--env-file <path>",
|
|
8640
8690
|
"Load environment variables from file (priority: CLI flags > file > env vars)"
|
|
8641
|
-
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new
|
|
8691
|
+
).option("-v, --verbose", "Show full tool inputs and outputs").addOption(new Option7("--debug-no-mock-claude").hideHelp()).action(
|
|
8642
8692
|
async (prompt, options) => {
|
|
8643
8693
|
const state = await loadCookState();
|
|
8644
8694
|
if (!state.lastCheckpointId) {
|
|
@@ -11780,7 +11830,7 @@ var setupClaudeCommand = new Command57().name("setup-claude").description("Insta
|
|
|
11780
11830
|
|
|
11781
11831
|
// src/index.ts
|
|
11782
11832
|
var program = new Command58();
|
|
11783
|
-
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.
|
|
11833
|
+
program.name("vm0").description("VM0 CLI - Build and run agents with natural language").version("9.12.0");
|
|
11784
11834
|
program.addCommand(authCommand);
|
|
11785
11835
|
program.addCommand(infoCommand);
|
|
11786
11836
|
program.addCommand(composeCommand);
|