@vm0/cli 4.9.0 → 4.11.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 +266 -101
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
9
|
import { Command as Command17 } from "commander";
|
|
10
|
-
import
|
|
10
|
+
import chalk18 from "chalk";
|
|
11
11
|
|
|
12
12
|
// src/lib/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -1200,10 +1200,13 @@ var EventRenderer = class {
|
|
|
1200
1200
|
* Render run failed state
|
|
1201
1201
|
* Note: This is run lifecycle status, not an event
|
|
1202
1202
|
*/
|
|
1203
|
-
static renderRunFailed(error43) {
|
|
1203
|
+
static renderRunFailed(error43, runId) {
|
|
1204
1204
|
console.log("");
|
|
1205
1205
|
console.log(chalk3.red("\u2717 Run failed"));
|
|
1206
1206
|
console.log(` Error: ${chalk3.red(error43 || "Unknown error")}`);
|
|
1207
|
+
console.log(
|
|
1208
|
+
chalk3.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
1209
|
+
);
|
|
1207
1210
|
}
|
|
1208
1211
|
static renderInit(event, prefix, suffix) {
|
|
1209
1212
|
console.log(
|
|
@@ -14596,11 +14599,14 @@ async function pollEvents(runId, options) {
|
|
|
14596
14599
|
};
|
|
14597
14600
|
} else if (runStatus === "failed") {
|
|
14598
14601
|
complete = true;
|
|
14599
|
-
EventRenderer.renderRunFailed(response.run.error);
|
|
14602
|
+
EventRenderer.renderRunFailed(response.run.error, runId);
|
|
14600
14603
|
result = { succeeded: false, runId };
|
|
14601
14604
|
} else if (runStatus === "timeout") {
|
|
14602
14605
|
complete = true;
|
|
14603
14606
|
console.error(chalk4.red("\n\u2717 Run timed out"));
|
|
14607
|
+
console.error(
|
|
14608
|
+
chalk4.gray(` (use "vm0 logs ${runId} --system" to view system logs)`)
|
|
14609
|
+
);
|
|
14604
14610
|
result = { succeeded: false, runId };
|
|
14605
14611
|
}
|
|
14606
14612
|
if (!complete) {
|
|
@@ -15719,17 +15725,116 @@ var artifactCommand = new Command10().name("artifact").description("Manage cloud
|
|
|
15719
15725
|
|
|
15720
15726
|
// src/commands/cook.ts
|
|
15721
15727
|
import { Command as Command11 } from "commander";
|
|
15722
|
-
import
|
|
15723
|
-
import { readFile as readFile5, mkdir as mkdir5 } from "fs/promises";
|
|
15724
|
-
import { existsSync as existsSync5 } from "fs";
|
|
15728
|
+
import chalk13 from "chalk";
|
|
15729
|
+
import { readFile as readFile5, mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
15730
|
+
import { existsSync as existsSync5, readFileSync } from "fs";
|
|
15725
15731
|
import path12 from "path";
|
|
15726
|
-
import { spawn } from "child_process";
|
|
15732
|
+
import { spawn as spawn2 } from "child_process";
|
|
15727
15733
|
import { parse as parseYaml3 } from "yaml";
|
|
15734
|
+
import { config as dotenvConfig2 } from "dotenv";
|
|
15735
|
+
|
|
15736
|
+
// src/lib/update-checker.ts
|
|
15737
|
+
import https from "https";
|
|
15738
|
+
import { spawn } from "child_process";
|
|
15739
|
+
import chalk12 from "chalk";
|
|
15740
|
+
var PACKAGE_NAME = "@vm0/cli";
|
|
15741
|
+
var NPM_REGISTRY_URL = `https://registry.npmjs.org/${encodeURIComponent(PACKAGE_NAME)}/latest`;
|
|
15742
|
+
var TIMEOUT_MS = 5e3;
|
|
15743
|
+
function escapeForShell(str) {
|
|
15744
|
+
return `"${str.replace(/"/g, '\\"')}"`;
|
|
15745
|
+
}
|
|
15746
|
+
function buildRerunCommand(prompt) {
|
|
15747
|
+
if (prompt) {
|
|
15748
|
+
return `vm0 cook ${escapeForShell(prompt)}`;
|
|
15749
|
+
}
|
|
15750
|
+
return "vm0 cook";
|
|
15751
|
+
}
|
|
15752
|
+
function getLatestVersion() {
|
|
15753
|
+
return new Promise((resolve2) => {
|
|
15754
|
+
const req = https.get(NPM_REGISTRY_URL, (res) => {
|
|
15755
|
+
let data = "";
|
|
15756
|
+
res.on("data", (chunk) => {
|
|
15757
|
+
data += chunk.toString();
|
|
15758
|
+
});
|
|
15759
|
+
res.on("end", () => {
|
|
15760
|
+
try {
|
|
15761
|
+
const json2 = JSON.parse(data);
|
|
15762
|
+
resolve2(json2.version ?? null);
|
|
15763
|
+
} catch {
|
|
15764
|
+
resolve2(null);
|
|
15765
|
+
}
|
|
15766
|
+
});
|
|
15767
|
+
});
|
|
15768
|
+
req.on("error", () => {
|
|
15769
|
+
resolve2(null);
|
|
15770
|
+
});
|
|
15771
|
+
req.setTimeout(TIMEOUT_MS, () => {
|
|
15772
|
+
req.destroy();
|
|
15773
|
+
resolve2(null);
|
|
15774
|
+
});
|
|
15775
|
+
});
|
|
15776
|
+
}
|
|
15777
|
+
function performUpgrade() {
|
|
15778
|
+
return new Promise((resolve2) => {
|
|
15779
|
+
const npm = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
15780
|
+
const child = spawn(npm, ["install", "-g", `${PACKAGE_NAME}@latest`], {
|
|
15781
|
+
stdio: "inherit",
|
|
15782
|
+
shell: process.platform === "win32"
|
|
15783
|
+
});
|
|
15784
|
+
child.on("close", (code) => {
|
|
15785
|
+
resolve2(code === 0);
|
|
15786
|
+
});
|
|
15787
|
+
child.on("error", () => {
|
|
15788
|
+
resolve2(false);
|
|
15789
|
+
});
|
|
15790
|
+
});
|
|
15791
|
+
}
|
|
15792
|
+
async function checkAndUpgrade(currentVersion, prompt) {
|
|
15793
|
+
const latestVersion = await getLatestVersion();
|
|
15794
|
+
if (latestVersion === null) {
|
|
15795
|
+
console.log(chalk12.yellow("Warning: Could not check for updates"));
|
|
15796
|
+
console.log();
|
|
15797
|
+
return false;
|
|
15798
|
+
}
|
|
15799
|
+
if (latestVersion === currentVersion) {
|
|
15800
|
+
return false;
|
|
15801
|
+
}
|
|
15802
|
+
console.log(chalk12.yellow("vm0 is currently in Early Access (EA)."));
|
|
15803
|
+
console.log(
|
|
15804
|
+
chalk12.yellow(
|
|
15805
|
+
`Current version: ${currentVersion} -> Latest version: ${latestVersion}`
|
|
15806
|
+
)
|
|
15807
|
+
);
|
|
15808
|
+
console.log(
|
|
15809
|
+
chalk12.yellow(
|
|
15810
|
+
"Please always use the latest version for best compatibility."
|
|
15811
|
+
)
|
|
15812
|
+
);
|
|
15813
|
+
console.log();
|
|
15814
|
+
console.log("Upgrading...");
|
|
15815
|
+
const success2 = await performUpgrade();
|
|
15816
|
+
if (success2) {
|
|
15817
|
+
console.log(chalk12.green(`Upgraded to ${latestVersion}`));
|
|
15818
|
+
console.log();
|
|
15819
|
+
console.log("To continue, run:");
|
|
15820
|
+
console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
|
|
15821
|
+
return true;
|
|
15822
|
+
}
|
|
15823
|
+
console.log();
|
|
15824
|
+
console.log(chalk12.red("Upgrade failed. Please run manually:"));
|
|
15825
|
+
console.log(chalk12.cyan(` npm install -g ${PACKAGE_NAME}@latest`));
|
|
15826
|
+
console.log();
|
|
15827
|
+
console.log("Then re-run:");
|
|
15828
|
+
console.log(chalk12.cyan(` ${buildRerunCommand(prompt)}`));
|
|
15829
|
+
return true;
|
|
15830
|
+
}
|
|
15831
|
+
|
|
15832
|
+
// src/commands/cook.ts
|
|
15728
15833
|
var CONFIG_FILE3 = "vm0.yaml";
|
|
15729
15834
|
var ARTIFACT_DIR = "artifact";
|
|
15730
15835
|
function execVm0Command(args, options = {}) {
|
|
15731
15836
|
return new Promise((resolve2, reject) => {
|
|
15732
|
-
const proc =
|
|
15837
|
+
const proc = spawn2("vm0", args, {
|
|
15733
15838
|
cwd: options.cwd,
|
|
15734
15839
|
stdio: options.silent ? "pipe" : ["inherit", "inherit", "inherit"],
|
|
15735
15840
|
shell: process.platform === "win32"
|
|
@@ -15758,7 +15863,7 @@ function execVm0Command(args, options = {}) {
|
|
|
15758
15863
|
}
|
|
15759
15864
|
function execVm0RunWithCapture(args, options = {}) {
|
|
15760
15865
|
return new Promise((resolve2, reject) => {
|
|
15761
|
-
const proc =
|
|
15866
|
+
const proc = spawn2("vm0", args, {
|
|
15762
15867
|
cwd: options.cwd,
|
|
15763
15868
|
stdio: ["inherit", "pipe", "pipe"],
|
|
15764
15869
|
shell: process.platform === "win32"
|
|
@@ -15802,11 +15907,53 @@ function parseArtifactVersionFromCompletion(output, artifactName) {
|
|
|
15802
15907
|
function escapeRegExp(str) {
|
|
15803
15908
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
15804
15909
|
}
|
|
15910
|
+
function extractRequiredVarNames(config2) {
|
|
15911
|
+
const refs = extractVariableReferences(config2);
|
|
15912
|
+
const grouped = groupVariablesBySource(refs);
|
|
15913
|
+
const varNames = grouped.vars.map((r) => r.name);
|
|
15914
|
+
const secretNames = grouped.secrets.map((r) => r.name);
|
|
15915
|
+
return [.../* @__PURE__ */ new Set([...varNames, ...secretNames])];
|
|
15916
|
+
}
|
|
15917
|
+
function checkMissingVariables(varNames, envFilePath) {
|
|
15918
|
+
let dotenvValues = {};
|
|
15919
|
+
if (existsSync5(envFilePath)) {
|
|
15920
|
+
const result = dotenvConfig2({ path: envFilePath });
|
|
15921
|
+
if (result.parsed) {
|
|
15922
|
+
dotenvValues = result.parsed;
|
|
15923
|
+
}
|
|
15924
|
+
}
|
|
15925
|
+
const missing = [];
|
|
15926
|
+
for (const name of varNames) {
|
|
15927
|
+
const inEnv = process.env[name] !== void 0;
|
|
15928
|
+
const inDotenv = dotenvValues[name] !== void 0;
|
|
15929
|
+
if (!inEnv && !inDotenv) {
|
|
15930
|
+
missing.push(name);
|
|
15931
|
+
}
|
|
15932
|
+
}
|
|
15933
|
+
return missing;
|
|
15934
|
+
}
|
|
15935
|
+
async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
15936
|
+
const placeholders = missingVars.map((name) => `${name}=`).join("\n");
|
|
15937
|
+
if (existsSync5(envFilePath)) {
|
|
15938
|
+
const existingContent = readFileSync(envFilePath, "utf8");
|
|
15939
|
+
const needsNewline = existingContent.length > 0 && !existingContent.endsWith("\n");
|
|
15940
|
+
const prefix = needsNewline ? "\n" : "";
|
|
15941
|
+
await appendFile(envFilePath, `${prefix}${placeholders}
|
|
15942
|
+
`);
|
|
15943
|
+
} else {
|
|
15944
|
+
await writeFile5(envFilePath, `${placeholders}
|
|
15945
|
+
`);
|
|
15946
|
+
}
|
|
15947
|
+
}
|
|
15805
15948
|
var cookCommand = new Command11().name("cook").description("One-click agent preparation and execution from vm0.yaml").argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
15949
|
+
const shouldExit = await checkAndUpgrade("4.11.0", prompt);
|
|
15950
|
+
if (shouldExit) {
|
|
15951
|
+
process.exit(0);
|
|
15952
|
+
}
|
|
15806
15953
|
const cwd = process.cwd();
|
|
15807
|
-
console.log(
|
|
15954
|
+
console.log(chalk13.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
15808
15955
|
if (!existsSync5(CONFIG_FILE3)) {
|
|
15809
|
-
console.error(
|
|
15956
|
+
console.error(chalk13.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
15810
15957
|
process.exit(1);
|
|
15811
15958
|
}
|
|
15812
15959
|
let config2;
|
|
@@ -15814,32 +15961,50 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15814
15961
|
const content = await readFile5(CONFIG_FILE3, "utf8");
|
|
15815
15962
|
config2 = parseYaml3(content);
|
|
15816
15963
|
} catch (error43) {
|
|
15817
|
-
console.error(
|
|
15964
|
+
console.error(chalk13.red("\u2717 Invalid YAML format"));
|
|
15818
15965
|
if (error43 instanceof Error) {
|
|
15819
|
-
console.error(
|
|
15966
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15820
15967
|
}
|
|
15821
15968
|
process.exit(1);
|
|
15822
15969
|
}
|
|
15823
15970
|
const validation = validateAgentCompose(config2);
|
|
15824
15971
|
if (!validation.valid) {
|
|
15825
|
-
console.error(
|
|
15972
|
+
console.error(chalk13.red(`\u2717 ${validation.error}`));
|
|
15826
15973
|
process.exit(1);
|
|
15827
15974
|
}
|
|
15828
15975
|
const agentNames = Object.keys(config2.agents);
|
|
15829
15976
|
const agentName = agentNames[0];
|
|
15830
15977
|
const volumeCount = config2.volumes ? Object.keys(config2.volumes).length : 0;
|
|
15831
15978
|
console.log(
|
|
15832
|
-
|
|
15979
|
+
chalk13.green(`\u2713 Config validated: 1 agent, ${volumeCount} volume(s)`)
|
|
15833
15980
|
);
|
|
15981
|
+
const requiredVarNames = extractRequiredVarNames(config2);
|
|
15982
|
+
if (requiredVarNames.length > 0) {
|
|
15983
|
+
const envFilePath = path12.join(cwd, ".env");
|
|
15984
|
+
const missingVars = checkMissingVariables(requiredVarNames, envFilePath);
|
|
15985
|
+
if (missingVars.length > 0) {
|
|
15986
|
+
await generateEnvPlaceholders(missingVars, envFilePath);
|
|
15987
|
+
console.log();
|
|
15988
|
+
console.log(
|
|
15989
|
+
chalk13.yellow(
|
|
15990
|
+
`\u26A0 Missing environment variables. Please fill in values in .env file:`
|
|
15991
|
+
)
|
|
15992
|
+
);
|
|
15993
|
+
for (const varName of missingVars) {
|
|
15994
|
+
console.log(chalk13.yellow(` ${varName}`));
|
|
15995
|
+
}
|
|
15996
|
+
process.exit(1);
|
|
15997
|
+
}
|
|
15998
|
+
}
|
|
15834
15999
|
if (config2.volumes && Object.keys(config2.volumes).length > 0) {
|
|
15835
16000
|
console.log();
|
|
15836
|
-
console.log(
|
|
16001
|
+
console.log(chalk13.blue("Processing volumes..."));
|
|
15837
16002
|
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
15838
16003
|
const volumeDir = path12.join(cwd, volumeConfig.name);
|
|
15839
|
-
console.log(
|
|
16004
|
+
console.log(chalk13.gray(` ${volumeConfig.name}/`));
|
|
15840
16005
|
if (!existsSync5(volumeDir)) {
|
|
15841
16006
|
console.error(
|
|
15842
|
-
|
|
16007
|
+
chalk13.red(
|
|
15843
16008
|
` \u2717 Directory not found. Create the directory and add files first.`
|
|
15844
16009
|
)
|
|
15845
16010
|
);
|
|
@@ -15852,30 +16017,30 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15852
16017
|
cwd: volumeDir,
|
|
15853
16018
|
silent: true
|
|
15854
16019
|
});
|
|
15855
|
-
console.log(
|
|
16020
|
+
console.log(chalk13.green(` \u2713 Initialized`));
|
|
15856
16021
|
}
|
|
15857
16022
|
await execVm0Command(["volume", "push"], {
|
|
15858
16023
|
cwd: volumeDir,
|
|
15859
16024
|
silent: true
|
|
15860
16025
|
});
|
|
15861
|
-
console.log(
|
|
16026
|
+
console.log(chalk13.green(` \u2713 Pushed`));
|
|
15862
16027
|
} catch (error43) {
|
|
15863
|
-
console.error(
|
|
16028
|
+
console.error(chalk13.red(` \u2717 Failed`));
|
|
15864
16029
|
if (error43 instanceof Error) {
|
|
15865
|
-
console.error(
|
|
16030
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15866
16031
|
}
|
|
15867
16032
|
process.exit(1);
|
|
15868
16033
|
}
|
|
15869
16034
|
}
|
|
15870
16035
|
}
|
|
15871
16036
|
console.log();
|
|
15872
|
-
console.log(
|
|
16037
|
+
console.log(chalk13.blue("Processing artifact..."));
|
|
15873
16038
|
const artifactDir = path12.join(cwd, ARTIFACT_DIR);
|
|
15874
|
-
console.log(
|
|
16039
|
+
console.log(chalk13.gray(` ${ARTIFACT_DIR}/`));
|
|
15875
16040
|
try {
|
|
15876
16041
|
if (!existsSync5(artifactDir)) {
|
|
15877
16042
|
await mkdir5(artifactDir, { recursive: true });
|
|
15878
|
-
console.log(
|
|
16043
|
+
console.log(chalk13.green(` \u2713 Created directory`));
|
|
15879
16044
|
}
|
|
15880
16045
|
const existingConfig = await readStorageConfig(artifactDir);
|
|
15881
16046
|
if (!existingConfig) {
|
|
@@ -15883,38 +16048,38 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15883
16048
|
cwd: artifactDir,
|
|
15884
16049
|
silent: true
|
|
15885
16050
|
});
|
|
15886
|
-
console.log(
|
|
16051
|
+
console.log(chalk13.green(` \u2713 Initialized`));
|
|
15887
16052
|
}
|
|
15888
16053
|
await execVm0Command(["artifact", "push"], {
|
|
15889
16054
|
cwd: artifactDir,
|
|
15890
16055
|
silent: true
|
|
15891
16056
|
});
|
|
15892
|
-
console.log(
|
|
16057
|
+
console.log(chalk13.green(` \u2713 Pushed`));
|
|
15893
16058
|
} catch (error43) {
|
|
15894
|
-
console.error(
|
|
16059
|
+
console.error(chalk13.red(` \u2717 Failed`));
|
|
15895
16060
|
if (error43 instanceof Error) {
|
|
15896
|
-
console.error(
|
|
16061
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15897
16062
|
}
|
|
15898
16063
|
process.exit(1);
|
|
15899
16064
|
}
|
|
15900
16065
|
console.log();
|
|
15901
|
-
console.log(
|
|
16066
|
+
console.log(chalk13.blue("Uploading compose..."));
|
|
15902
16067
|
try {
|
|
15903
16068
|
await execVm0Command(["compose", CONFIG_FILE3], {
|
|
15904
16069
|
cwd,
|
|
15905
16070
|
silent: true
|
|
15906
16071
|
});
|
|
15907
|
-
console.log(
|
|
16072
|
+
console.log(chalk13.green(`\u2713 Compose uploaded: ${agentName}`));
|
|
15908
16073
|
} catch (error43) {
|
|
15909
|
-
console.error(
|
|
16074
|
+
console.error(chalk13.red(`\u2717 Compose failed`));
|
|
15910
16075
|
if (error43 instanceof Error) {
|
|
15911
|
-
console.error(
|
|
16076
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15912
16077
|
}
|
|
15913
16078
|
process.exit(1);
|
|
15914
16079
|
}
|
|
15915
16080
|
if (prompt) {
|
|
15916
16081
|
console.log();
|
|
15917
|
-
console.log(
|
|
16082
|
+
console.log(chalk13.blue(`Running agent: ${agentName}`));
|
|
15918
16083
|
console.log();
|
|
15919
16084
|
let runOutput;
|
|
15920
16085
|
try {
|
|
@@ -15935,17 +16100,17 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15935
16100
|
);
|
|
15936
16101
|
if (serverVersion) {
|
|
15937
16102
|
console.log();
|
|
15938
|
-
console.log(
|
|
16103
|
+
console.log(chalk13.blue("Pulling updated artifact..."));
|
|
15939
16104
|
try {
|
|
15940
16105
|
await execVm0Command(["artifact", "pull"], {
|
|
15941
16106
|
cwd: artifactDir,
|
|
15942
16107
|
silent: true
|
|
15943
16108
|
});
|
|
15944
|
-
console.log(
|
|
16109
|
+
console.log(chalk13.green(`\u2713 Artifact pulled (${serverVersion})`));
|
|
15945
16110
|
} catch (error43) {
|
|
15946
|
-
console.error(
|
|
16111
|
+
console.error(chalk13.red(`\u2717 Artifact pull failed`));
|
|
15947
16112
|
if (error43 instanceof Error) {
|
|
15948
|
-
console.error(
|
|
16113
|
+
console.error(chalk13.gray(` ${error43.message}`));
|
|
15949
16114
|
}
|
|
15950
16115
|
}
|
|
15951
16116
|
}
|
|
@@ -15953,7 +16118,7 @@ var cookCommand = new Command11().name("cook").description("One-click agent prep
|
|
|
15953
16118
|
console.log();
|
|
15954
16119
|
console.log(" Run your agent:");
|
|
15955
16120
|
console.log(
|
|
15956
|
-
|
|
16121
|
+
chalk13.cyan(
|
|
15957
16122
|
` vm0 run ${agentName} --artifact-name ${ARTIFACT_DIR} "your prompt"`
|
|
15958
16123
|
)
|
|
15959
16124
|
);
|
|
@@ -15965,7 +16130,7 @@ import { Command as Command15 } from "commander";
|
|
|
15965
16130
|
|
|
15966
16131
|
// src/commands/image/build.ts
|
|
15967
16132
|
import { Command as Command12 } from "commander";
|
|
15968
|
-
import
|
|
16133
|
+
import chalk14 from "chalk";
|
|
15969
16134
|
import { readFile as readFile6 } from "fs/promises";
|
|
15970
16135
|
import { existsSync as existsSync6 } from "fs";
|
|
15971
16136
|
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
@@ -15973,13 +16138,13 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15973
16138
|
async (options) => {
|
|
15974
16139
|
const { file: file2, name, deleteExisting } = options;
|
|
15975
16140
|
if (!existsSync6(file2)) {
|
|
15976
|
-
console.error(
|
|
16141
|
+
console.error(chalk14.red(`\u2717 Dockerfile not found: ${file2}`));
|
|
15977
16142
|
process.exit(1);
|
|
15978
16143
|
}
|
|
15979
16144
|
const nameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,62}[a-zA-Z0-9]$/;
|
|
15980
16145
|
if (!nameRegex.test(name)) {
|
|
15981
16146
|
console.error(
|
|
15982
|
-
|
|
16147
|
+
chalk14.red(
|
|
15983
16148
|
"\u2717 Invalid name format. Must be 3-64 characters, letters, numbers, and hyphens only."
|
|
15984
16149
|
)
|
|
15985
16150
|
);
|
|
@@ -15987,7 +16152,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15987
16152
|
}
|
|
15988
16153
|
if (name.startsWith("vm0-")) {
|
|
15989
16154
|
console.error(
|
|
15990
|
-
|
|
16155
|
+
chalk14.red(
|
|
15991
16156
|
'\u2717 Invalid name. Cannot start with "vm0-" (reserved prefix).'
|
|
15992
16157
|
)
|
|
15993
16158
|
);
|
|
@@ -15995,8 +16160,8 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
15995
16160
|
}
|
|
15996
16161
|
try {
|
|
15997
16162
|
const dockerfile = await readFile6(file2, "utf8");
|
|
15998
|
-
console.log(
|
|
15999
|
-
console.log(
|
|
16163
|
+
console.log(chalk14.blue(`Building image: ${name}`));
|
|
16164
|
+
console.log(chalk14.gray(` Dockerfile: ${file2}`));
|
|
16000
16165
|
console.log();
|
|
16001
16166
|
const buildInfo = await apiClient.createImage({
|
|
16002
16167
|
dockerfile,
|
|
@@ -16004,7 +16169,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16004
16169
|
deleteExisting
|
|
16005
16170
|
});
|
|
16006
16171
|
const { imageId, buildId } = buildInfo;
|
|
16007
|
-
console.log(
|
|
16172
|
+
console.log(chalk14.gray(` Build ID: ${buildId}`));
|
|
16008
16173
|
console.log();
|
|
16009
16174
|
let logsOffset = 0;
|
|
16010
16175
|
let status = "building";
|
|
@@ -16020,7 +16185,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16020
16185
|
}
|
|
16021
16186
|
const statusData = await statusResponse.json();
|
|
16022
16187
|
for (const log of statusData.logs) {
|
|
16023
|
-
console.log(
|
|
16188
|
+
console.log(chalk14.gray(` ${log}`));
|
|
16024
16189
|
}
|
|
16025
16190
|
logsOffset = statusData.logsOffset;
|
|
16026
16191
|
status = statusData.status;
|
|
@@ -16030,27 +16195,27 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16030
16195
|
}
|
|
16031
16196
|
console.log();
|
|
16032
16197
|
if (status === "ready") {
|
|
16033
|
-
console.log(
|
|
16198
|
+
console.log(chalk14.green(`\u2713 Image built: ${name}`));
|
|
16034
16199
|
console.log();
|
|
16035
16200
|
console.log("Use in vm0.yaml:");
|
|
16036
|
-
console.log(
|
|
16037
|
-
console.log(
|
|
16038
|
-
console.log(
|
|
16201
|
+
console.log(chalk14.cyan(` agents:`));
|
|
16202
|
+
console.log(chalk14.cyan(` your-agent:`));
|
|
16203
|
+
console.log(chalk14.cyan(` image: "${name}"`));
|
|
16039
16204
|
} else {
|
|
16040
|
-
console.error(
|
|
16205
|
+
console.error(chalk14.red(`\u2717 Build failed`));
|
|
16041
16206
|
process.exit(1);
|
|
16042
16207
|
}
|
|
16043
16208
|
} catch (error43) {
|
|
16044
16209
|
if (error43 instanceof Error) {
|
|
16045
16210
|
if (error43.message.includes("Not authenticated")) {
|
|
16046
16211
|
console.error(
|
|
16047
|
-
|
|
16212
|
+
chalk14.red("\u2717 Not authenticated. Run: vm0 auth login")
|
|
16048
16213
|
);
|
|
16049
16214
|
} else {
|
|
16050
|
-
console.error(
|
|
16215
|
+
console.error(chalk14.red(`\u2717 ${error43.message}`));
|
|
16051
16216
|
}
|
|
16052
16217
|
} else {
|
|
16053
|
-
console.error(
|
|
16218
|
+
console.error(chalk14.red("\u2717 An unexpected error occurred"));
|
|
16054
16219
|
}
|
|
16055
16220
|
process.exit(1);
|
|
16056
16221
|
}
|
|
@@ -16059,7 +16224,7 @@ var buildCommand = new Command12().name("build").description("Build a custom ima
|
|
|
16059
16224
|
|
|
16060
16225
|
// src/commands/image/list.ts
|
|
16061
16226
|
import { Command as Command13 } from "commander";
|
|
16062
|
-
import
|
|
16227
|
+
import chalk15 from "chalk";
|
|
16063
16228
|
var listCommand = new Command13().name("list").alias("ls").description("List your custom images").action(async () => {
|
|
16064
16229
|
try {
|
|
16065
16230
|
const response = await apiClient.get("/api/images");
|
|
@@ -16072,43 +16237,43 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
|
|
|
16072
16237
|
const data = await response.json();
|
|
16073
16238
|
const { images } = data;
|
|
16074
16239
|
if (images.length === 0) {
|
|
16075
|
-
console.log(
|
|
16240
|
+
console.log(chalk15.gray("No images found."));
|
|
16076
16241
|
console.log();
|
|
16077
16242
|
console.log("Build your first image:");
|
|
16078
16243
|
console.log(
|
|
16079
|
-
|
|
16244
|
+
chalk15.cyan(" vm0 image build --file Dockerfile --name my-image")
|
|
16080
16245
|
);
|
|
16081
16246
|
return;
|
|
16082
16247
|
}
|
|
16083
|
-
console.log(
|
|
16248
|
+
console.log(chalk15.bold("Your images:"));
|
|
16084
16249
|
console.log();
|
|
16085
16250
|
console.log(
|
|
16086
|
-
|
|
16251
|
+
chalk15.gray(
|
|
16087
16252
|
`${"NAME".padEnd(30)} ${"STATUS".padEnd(12)} ${"CREATED".padEnd(20)}`
|
|
16088
16253
|
)
|
|
16089
16254
|
);
|
|
16090
|
-
console.log(
|
|
16255
|
+
console.log(chalk15.gray("-".repeat(62)));
|
|
16091
16256
|
for (const image of images) {
|
|
16092
|
-
const statusColor = image.status === "ready" ?
|
|
16257
|
+
const statusColor = image.status === "ready" ? chalk15.green : image.status === "building" ? chalk15.yellow : chalk15.red;
|
|
16093
16258
|
const createdAt = new Date(image.createdAt).toLocaleString();
|
|
16094
16259
|
console.log(
|
|
16095
16260
|
`${image.alias.padEnd(30)} ${statusColor(image.status.padEnd(12))} ${createdAt.padEnd(20)}`
|
|
16096
16261
|
);
|
|
16097
16262
|
if (image.status === "error" && image.errorMessage) {
|
|
16098
|
-
console.log(
|
|
16263
|
+
console.log(chalk15.red(` Error: ${image.errorMessage}`));
|
|
16099
16264
|
}
|
|
16100
16265
|
}
|
|
16101
16266
|
console.log();
|
|
16102
|
-
console.log(
|
|
16267
|
+
console.log(chalk15.gray(`Total: ${images.length} image(s)`));
|
|
16103
16268
|
} catch (error43) {
|
|
16104
16269
|
if (error43 instanceof Error) {
|
|
16105
16270
|
if (error43.message.includes("Not authenticated")) {
|
|
16106
|
-
console.error(
|
|
16271
|
+
console.error(chalk15.red("Not authenticated. Run: vm0 auth login"));
|
|
16107
16272
|
} else {
|
|
16108
|
-
console.error(
|
|
16273
|
+
console.error(chalk15.red(`Error: ${error43.message}`));
|
|
16109
16274
|
}
|
|
16110
16275
|
} else {
|
|
16111
|
-
console.error(
|
|
16276
|
+
console.error(chalk15.red("An unexpected error occurred"));
|
|
16112
16277
|
}
|
|
16113
16278
|
process.exit(1);
|
|
16114
16279
|
}
|
|
@@ -16116,7 +16281,7 @@ var listCommand = new Command13().name("list").alias("ls").description("List you
|
|
|
16116
16281
|
|
|
16117
16282
|
// src/commands/image/delete.ts
|
|
16118
16283
|
import { Command as Command14 } from "commander";
|
|
16119
|
-
import
|
|
16284
|
+
import chalk16 from "chalk";
|
|
16120
16285
|
import * as readline from "readline";
|
|
16121
16286
|
var deleteCommand = new Command14().name("delete").alias("rm").description("Delete a custom image").argument("<name>", "Name of the image to delete").option("-f, --force", "Skip confirmation prompt").action(async (name, options) => {
|
|
16122
16287
|
try {
|
|
@@ -16130,7 +16295,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16130
16295
|
const data = await listResponse.json();
|
|
16131
16296
|
const image = data.images.find((img) => img.alias === name);
|
|
16132
16297
|
if (!image) {
|
|
16133
|
-
console.error(
|
|
16298
|
+
console.error(chalk16.red(`Image not found: ${name}`));
|
|
16134
16299
|
process.exit(1);
|
|
16135
16300
|
}
|
|
16136
16301
|
if (!options.force) {
|
|
@@ -16140,7 +16305,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16140
16305
|
});
|
|
16141
16306
|
const answer = await new Promise((resolve2) => {
|
|
16142
16307
|
rl.question(
|
|
16143
|
-
|
|
16308
|
+
chalk16.yellow(`Delete image "${name}"? [y/N] `),
|
|
16144
16309
|
(answer2) => {
|
|
16145
16310
|
rl.close();
|
|
16146
16311
|
resolve2(answer2);
|
|
@@ -16148,7 +16313,7 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16148
16313
|
);
|
|
16149
16314
|
});
|
|
16150
16315
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
16151
|
-
console.log(
|
|
16316
|
+
console.log(chalk16.gray("Cancelled."));
|
|
16152
16317
|
return;
|
|
16153
16318
|
}
|
|
16154
16319
|
}
|
|
@@ -16159,16 +16324,16 @@ var deleteCommand = new Command14().name("delete").alias("rm").description("Dele
|
|
|
16159
16324
|
error43.error?.message || "Failed to delete image"
|
|
16160
16325
|
);
|
|
16161
16326
|
}
|
|
16162
|
-
console.log(
|
|
16327
|
+
console.log(chalk16.green(`Deleted image: ${name}`));
|
|
16163
16328
|
} catch (error43) {
|
|
16164
16329
|
if (error43 instanceof Error) {
|
|
16165
16330
|
if (error43.message.includes("Not authenticated")) {
|
|
16166
|
-
console.error(
|
|
16331
|
+
console.error(chalk16.red("Not authenticated. Run: vm0 auth login"));
|
|
16167
16332
|
} else {
|
|
16168
|
-
console.error(
|
|
16333
|
+
console.error(chalk16.red(`Error: ${error43.message}`));
|
|
16169
16334
|
}
|
|
16170
16335
|
} else {
|
|
16171
|
-
console.error(
|
|
16336
|
+
console.error(chalk16.red("An unexpected error occurred"));
|
|
16172
16337
|
}
|
|
16173
16338
|
process.exit(1);
|
|
16174
16339
|
}
|
|
@@ -16179,7 +16344,7 @@ var imageCommand = new Command15().name("image").description("Manage custom imag
|
|
|
16179
16344
|
|
|
16180
16345
|
// src/commands/logs/index.ts
|
|
16181
16346
|
import { Command as Command16 } from "commander";
|
|
16182
|
-
import
|
|
16347
|
+
import chalk17 from "chalk";
|
|
16183
16348
|
|
|
16184
16349
|
// src/lib/time-parser.ts
|
|
16185
16350
|
function parseTime(timeStr) {
|
|
@@ -16241,23 +16406,23 @@ function formatMetric(metric) {
|
|
|
16241
16406
|
function formatNetworkLog(entry) {
|
|
16242
16407
|
let statusColor;
|
|
16243
16408
|
if (entry.status >= 200 && entry.status < 300) {
|
|
16244
|
-
statusColor =
|
|
16409
|
+
statusColor = chalk17.green;
|
|
16245
16410
|
} else if (entry.status >= 300 && entry.status < 400) {
|
|
16246
|
-
statusColor =
|
|
16411
|
+
statusColor = chalk17.yellow;
|
|
16247
16412
|
} else if (entry.status >= 400) {
|
|
16248
|
-
statusColor =
|
|
16413
|
+
statusColor = chalk17.red;
|
|
16249
16414
|
} else {
|
|
16250
|
-
statusColor =
|
|
16415
|
+
statusColor = chalk17.gray;
|
|
16251
16416
|
}
|
|
16252
16417
|
let latencyColor;
|
|
16253
16418
|
if (entry.latency_ms < 500) {
|
|
16254
|
-
latencyColor =
|
|
16419
|
+
latencyColor = chalk17.green;
|
|
16255
16420
|
} else if (entry.latency_ms < 2e3) {
|
|
16256
|
-
latencyColor =
|
|
16421
|
+
latencyColor = chalk17.yellow;
|
|
16257
16422
|
} else {
|
|
16258
|
-
latencyColor =
|
|
16423
|
+
latencyColor = chalk17.red;
|
|
16259
16424
|
}
|
|
16260
|
-
return `[${entry.timestamp}] ${
|
|
16425
|
+
return `[${entry.timestamp}] ${chalk17.cyan(entry.method.padEnd(6))} ${statusColor(entry.status)} ${latencyColor(entry.latency_ms + "ms")} ${formatBytes5(entry.request_size)}/${formatBytes5(entry.response_size)} ${chalk17.gray(entry.url)}`;
|
|
16261
16426
|
}
|
|
16262
16427
|
function renderAgentEvent(event) {
|
|
16263
16428
|
const parsed = ClaudeEventParser.parse(
|
|
@@ -16277,7 +16442,7 @@ function getLogType(options) {
|
|
|
16277
16442
|
].filter(Boolean).length;
|
|
16278
16443
|
if (selected > 1) {
|
|
16279
16444
|
console.error(
|
|
16280
|
-
|
|
16445
|
+
chalk17.red(
|
|
16281
16446
|
"Options --agent, --system, --metrics, and --network are mutually exclusive"
|
|
16282
16447
|
)
|
|
16283
16448
|
);
|
|
@@ -16330,7 +16495,7 @@ var logsCommand = new Command16().name("logs").description("View logs for an age
|
|
|
16330
16495
|
async function showAgentEvents(runId, options) {
|
|
16331
16496
|
const response = await apiClient.getAgentEvents(runId, options);
|
|
16332
16497
|
if (response.events.length === 0) {
|
|
16333
|
-
console.log(
|
|
16498
|
+
console.log(chalk17.yellow("No agent events found for this run."));
|
|
16334
16499
|
return;
|
|
16335
16500
|
}
|
|
16336
16501
|
for (const event of response.events) {
|
|
@@ -16339,7 +16504,7 @@ async function showAgentEvents(runId, options) {
|
|
|
16339
16504
|
if (response.hasMore) {
|
|
16340
16505
|
console.log();
|
|
16341
16506
|
console.log(
|
|
16342
|
-
|
|
16507
|
+
chalk17.gray(
|
|
16343
16508
|
`Showing ${response.events.length} events. Use --limit to see more.`
|
|
16344
16509
|
)
|
|
16345
16510
|
);
|
|
@@ -16348,21 +16513,21 @@ async function showAgentEvents(runId, options) {
|
|
|
16348
16513
|
async function showSystemLog(runId, options) {
|
|
16349
16514
|
const response = await apiClient.getSystemLog(runId, options);
|
|
16350
16515
|
if (!response.systemLog) {
|
|
16351
|
-
console.log(
|
|
16516
|
+
console.log(chalk17.yellow("No system log found for this run."));
|
|
16352
16517
|
return;
|
|
16353
16518
|
}
|
|
16354
16519
|
console.log(response.systemLog);
|
|
16355
16520
|
if (response.hasMore) {
|
|
16356
16521
|
console.log();
|
|
16357
16522
|
console.log(
|
|
16358
|
-
|
|
16523
|
+
chalk17.gray("More log entries available. Use --limit to see more.")
|
|
16359
16524
|
);
|
|
16360
16525
|
}
|
|
16361
16526
|
}
|
|
16362
16527
|
async function showMetrics(runId, options) {
|
|
16363
16528
|
const response = await apiClient.getMetrics(runId, options);
|
|
16364
16529
|
if (response.metrics.length === 0) {
|
|
16365
|
-
console.log(
|
|
16530
|
+
console.log(chalk17.yellow("No metrics found for this run."));
|
|
16366
16531
|
return;
|
|
16367
16532
|
}
|
|
16368
16533
|
for (const metric of response.metrics) {
|
|
@@ -16371,7 +16536,7 @@ async function showMetrics(runId, options) {
|
|
|
16371
16536
|
if (response.hasMore) {
|
|
16372
16537
|
console.log();
|
|
16373
16538
|
console.log(
|
|
16374
|
-
|
|
16539
|
+
chalk17.gray(
|
|
16375
16540
|
`Showing ${response.metrics.length} metrics. Use --limit to see more.`
|
|
16376
16541
|
)
|
|
16377
16542
|
);
|
|
@@ -16381,7 +16546,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
16381
16546
|
const response = await apiClient.getNetworkLogs(runId, options);
|
|
16382
16547
|
if (response.networkLogs.length === 0) {
|
|
16383
16548
|
console.log(
|
|
16384
|
-
|
|
16549
|
+
chalk17.yellow(
|
|
16385
16550
|
"No network logs found for this run. Network logs are only captured when beta_network_security is enabled."
|
|
16386
16551
|
)
|
|
16387
16552
|
);
|
|
@@ -16393,7 +16558,7 @@ async function showNetworkLogs(runId, options) {
|
|
|
16393
16558
|
if (response.hasMore) {
|
|
16394
16559
|
console.log();
|
|
16395
16560
|
console.log(
|
|
16396
|
-
|
|
16561
|
+
chalk17.gray(
|
|
16397
16562
|
`Showing ${response.networkLogs.length} network logs. Use --limit to see more.`
|
|
16398
16563
|
)
|
|
16399
16564
|
);
|
|
@@ -16402,25 +16567,25 @@ async function showNetworkLogs(runId, options) {
|
|
|
16402
16567
|
function handleError(error43, runId) {
|
|
16403
16568
|
if (error43 instanceof Error) {
|
|
16404
16569
|
if (error43.message.includes("Not authenticated")) {
|
|
16405
|
-
console.error(
|
|
16570
|
+
console.error(chalk17.red("Not authenticated. Run: vm0 auth login"));
|
|
16406
16571
|
} else if (error43.message.includes("not found")) {
|
|
16407
|
-
console.error(
|
|
16572
|
+
console.error(chalk17.red(`Run not found: ${runId}`));
|
|
16408
16573
|
} else if (error43.message.includes("Invalid time format")) {
|
|
16409
|
-
console.error(
|
|
16574
|
+
console.error(chalk17.red(error43.message));
|
|
16410
16575
|
} else {
|
|
16411
|
-
console.error(
|
|
16412
|
-
console.error(
|
|
16576
|
+
console.error(chalk17.red("Failed to fetch logs"));
|
|
16577
|
+
console.error(chalk17.gray(` ${error43.message}`));
|
|
16413
16578
|
}
|
|
16414
16579
|
} else {
|
|
16415
|
-
console.error(
|
|
16580
|
+
console.error(chalk17.red("An unexpected error occurred"));
|
|
16416
16581
|
}
|
|
16417
16582
|
}
|
|
16418
16583
|
|
|
16419
16584
|
// src/index.ts
|
|
16420
16585
|
var program = new Command17();
|
|
16421
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
16586
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.11.0");
|
|
16422
16587
|
program.command("info").description("Display environment information").action(async () => {
|
|
16423
|
-
console.log(
|
|
16588
|
+
console.log(chalk18.cyan("System Information:"));
|
|
16424
16589
|
console.log(`Node Version: ${process.version}`);
|
|
16425
16590
|
console.log(`Platform: ${process.platform}`);
|
|
16426
16591
|
console.log(`Architecture: ${process.arch}`);
|