@vm0/cli 4.23.0 → 4.25.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 +278 -46
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -6,8 +6,8 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/index.ts
|
|
9
|
-
import { Command as
|
|
10
|
-
import
|
|
9
|
+
import { Command as Command24 } from "commander";
|
|
10
|
+
import chalk25 from "chalk";
|
|
11
11
|
|
|
12
12
|
// src/lib/auth.ts
|
|
13
13
|
import chalk from "chalk";
|
|
@@ -15407,17 +15407,18 @@ ${action}...`));
|
|
|
15407
15407
|
function showNextSteps(result) {
|
|
15408
15408
|
const { runId, sessionId, checkpointId } = result;
|
|
15409
15409
|
console.log();
|
|
15410
|
-
console.log("
|
|
15411
|
-
console.log(" View telemetry logs:");
|
|
15410
|
+
console.log(" View agent logs:");
|
|
15412
15411
|
console.log(chalk5.cyan(` vm0 logs ${runId}`));
|
|
15413
15412
|
if (sessionId) {
|
|
15414
|
-
console.log(" Continue with session (latest
|
|
15413
|
+
console.log(" Continue with session (latest conversation and artifact):");
|
|
15415
15414
|
console.log(
|
|
15416
15415
|
chalk5.cyan(` vm0 run continue ${sessionId} "your next prompt"`)
|
|
15417
15416
|
);
|
|
15418
15417
|
}
|
|
15419
15418
|
if (checkpointId) {
|
|
15420
|
-
console.log(
|
|
15419
|
+
console.log(
|
|
15420
|
+
" Resume from checkpoint (snapshotted conversation and artifact):"
|
|
15421
|
+
);
|
|
15421
15422
|
console.log(
|
|
15422
15423
|
chalk5.cyan(` vm0 run resume ${checkpointId} "your next prompt"`)
|
|
15423
15424
|
);
|
|
@@ -16397,8 +16398,8 @@ var artifactCommand = new Command12().name("artifact").description("Manage cloud
|
|
|
16397
16398
|
// src/commands/cook.ts
|
|
16398
16399
|
import { Command as Command13 } from "commander";
|
|
16399
16400
|
import chalk16 from "chalk";
|
|
16400
|
-
import { readFile as
|
|
16401
|
-
import { existsSync as
|
|
16401
|
+
import { readFile as readFile6, mkdir as mkdir6, writeFile as writeFile6, appendFile } from "fs/promises";
|
|
16402
|
+
import { existsSync as existsSync7, readFileSync } from "fs";
|
|
16402
16403
|
import path11 from "path";
|
|
16403
16404
|
import { spawn as spawn2 } from "child_process";
|
|
16404
16405
|
import { parse as parseYaml3 } from "yaml";
|
|
@@ -16512,6 +16513,31 @@ async function checkAndUpgrade(currentVersion, prompt) {
|
|
|
16512
16513
|
return true;
|
|
16513
16514
|
}
|
|
16514
16515
|
|
|
16516
|
+
// src/lib/cook-state.ts
|
|
16517
|
+
import { homedir as homedir2 } from "os";
|
|
16518
|
+
import { join as join6 } from "path";
|
|
16519
|
+
import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
16520
|
+
import { existsSync as existsSync6 } from "fs";
|
|
16521
|
+
var CONFIG_DIR3 = join6(homedir2(), ".vm0");
|
|
16522
|
+
var COOK_STATE_FILE = join6(CONFIG_DIR3, "cook.json");
|
|
16523
|
+
async function loadCookState() {
|
|
16524
|
+
if (!existsSync6(COOK_STATE_FILE)) {
|
|
16525
|
+
return {};
|
|
16526
|
+
}
|
|
16527
|
+
try {
|
|
16528
|
+
const content = await readFile5(COOK_STATE_FILE, "utf8");
|
|
16529
|
+
return JSON.parse(content);
|
|
16530
|
+
} catch {
|
|
16531
|
+
return {};
|
|
16532
|
+
}
|
|
16533
|
+
}
|
|
16534
|
+
async function saveCookState(state) {
|
|
16535
|
+
await mkdir5(CONFIG_DIR3, { recursive: true });
|
|
16536
|
+
const existing = await loadCookState();
|
|
16537
|
+
const merged = { ...existing, ...state };
|
|
16538
|
+
await writeFile5(COOK_STATE_FILE, JSON.stringify(merged, null, 2), "utf8");
|
|
16539
|
+
}
|
|
16540
|
+
|
|
16515
16541
|
// src/commands/cook.ts
|
|
16516
16542
|
var CONFIG_FILE3 = "vm0.yaml";
|
|
16517
16543
|
var ARTIFACT_DIR = "artifact";
|
|
@@ -16593,6 +16619,20 @@ function parseArtifactVersionFromCompletion(output, artifactName) {
|
|
|
16593
16619
|
function escapeRegExp(str) {
|
|
16594
16620
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16595
16621
|
}
|
|
16622
|
+
function parseRunIdsFromOutput(output) {
|
|
16623
|
+
const completionMarker = "Run completed successfully";
|
|
16624
|
+
const completionIndex = output.indexOf(completionMarker);
|
|
16625
|
+
if (completionIndex === -1) return {};
|
|
16626
|
+
const section = output.slice(completionIndex);
|
|
16627
|
+
const ESC = String.fromCharCode(27);
|
|
16628
|
+
const ansiPattern = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
|
|
16629
|
+
const stripped = section.replace(ansiPattern, "");
|
|
16630
|
+
return {
|
|
16631
|
+
runId: stripped.match(/vm0 logs ([0-9a-f-]{36})/)?.[1],
|
|
16632
|
+
sessionId: stripped.match(/vm0 run continue ([0-9a-f-]{36})/)?.[1],
|
|
16633
|
+
checkpointId: stripped.match(/vm0 run resume ([0-9a-f-]{36})/)?.[1]
|
|
16634
|
+
};
|
|
16635
|
+
}
|
|
16596
16636
|
function extractRequiredVarNames(config2) {
|
|
16597
16637
|
const refs = extractVariableReferences(config2);
|
|
16598
16638
|
const grouped = groupVariablesBySource(refs);
|
|
@@ -16602,7 +16642,7 @@ function extractRequiredVarNames(config2) {
|
|
|
16602
16642
|
}
|
|
16603
16643
|
function checkMissingVariables(varNames, envFilePath) {
|
|
16604
16644
|
let dotenvValues = {};
|
|
16605
|
-
if (
|
|
16645
|
+
if (existsSync7(envFilePath)) {
|
|
16606
16646
|
const result = dotenvConfig2({ path: envFilePath, quiet: true });
|
|
16607
16647
|
if (result.parsed) {
|
|
16608
16648
|
dotenvValues = result.parsed;
|
|
@@ -16620,31 +16660,56 @@ function checkMissingVariables(varNames, envFilePath) {
|
|
|
16620
16660
|
}
|
|
16621
16661
|
async function generateEnvPlaceholders(missingVars, envFilePath) {
|
|
16622
16662
|
const placeholders = missingVars.map((name) => `${name}=`).join("\n");
|
|
16623
|
-
if (
|
|
16663
|
+
if (existsSync7(envFilePath)) {
|
|
16624
16664
|
const existingContent = readFileSync(envFilePath, "utf8");
|
|
16625
16665
|
const needsNewline = existingContent.length > 0 && !existingContent.endsWith("\n");
|
|
16626
16666
|
const prefix = needsNewline ? "\n" : "";
|
|
16627
16667
|
await appendFile(envFilePath, `${prefix}${placeholders}
|
|
16628
16668
|
`);
|
|
16629
16669
|
} else {
|
|
16630
|
-
await
|
|
16670
|
+
await writeFile6(envFilePath, `${placeholders}
|
|
16631
16671
|
`);
|
|
16632
16672
|
}
|
|
16633
16673
|
}
|
|
16634
|
-
|
|
16635
|
-
const
|
|
16674
|
+
async function autoPullArtifact(runOutput, artifactDir) {
|
|
16675
|
+
const serverVersion = parseArtifactVersionFromCompletion(
|
|
16676
|
+
runOutput,
|
|
16677
|
+
ARTIFACT_DIR
|
|
16678
|
+
);
|
|
16679
|
+
if (serverVersion && existsSync7(artifactDir)) {
|
|
16680
|
+
console.log();
|
|
16681
|
+
console.log(chalk16.blue("Pulling updated artifact:"));
|
|
16682
|
+
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
16683
|
+
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
16684
|
+
try {
|
|
16685
|
+
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
16686
|
+
cwd: artifactDir,
|
|
16687
|
+
silent: true
|
|
16688
|
+
});
|
|
16689
|
+
printCommand("cd ..");
|
|
16690
|
+
} catch (error43) {
|
|
16691
|
+
console.error(chalk16.red(`\u2717 Artifact pull failed`));
|
|
16692
|
+
if (error43 instanceof Error) {
|
|
16693
|
+
console.error(chalk16.gray(` ${error43.message}`));
|
|
16694
|
+
}
|
|
16695
|
+
}
|
|
16696
|
+
}
|
|
16697
|
+
}
|
|
16698
|
+
var cookCmd = new Command13().name("cook").description("One-click agent preparation and execution from vm0.yaml");
|
|
16699
|
+
cookCmd.argument("[prompt]", "Prompt for the agent").action(async (prompt) => {
|
|
16700
|
+
const shouldExit = await checkAndUpgrade("4.25.0", prompt);
|
|
16636
16701
|
if (shouldExit) {
|
|
16637
16702
|
process.exit(0);
|
|
16638
16703
|
}
|
|
16639
16704
|
const cwd = process.cwd();
|
|
16640
16705
|
console.log(chalk16.blue(`Reading config: ${CONFIG_FILE3}`));
|
|
16641
|
-
if (!
|
|
16706
|
+
if (!existsSync7(CONFIG_FILE3)) {
|
|
16642
16707
|
console.error(chalk16.red(`\u2717 Config file not found: ${CONFIG_FILE3}`));
|
|
16643
16708
|
process.exit(1);
|
|
16644
16709
|
}
|
|
16645
16710
|
let config2;
|
|
16646
16711
|
try {
|
|
16647
|
-
const content = await
|
|
16712
|
+
const content = await readFile6(CONFIG_FILE3, "utf8");
|
|
16648
16713
|
config2 = parseYaml3(content);
|
|
16649
16714
|
} catch (error43) {
|
|
16650
16715
|
console.error(chalk16.red("\u2717 Invalid YAML format"));
|
|
@@ -16687,7 +16752,7 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16687
16752
|
console.log(chalk16.blue("Processing volumes:"));
|
|
16688
16753
|
for (const volumeConfig of Object.values(config2.volumes)) {
|
|
16689
16754
|
const volumeDir = path11.join(cwd, volumeConfig.name);
|
|
16690
|
-
if (!
|
|
16755
|
+
if (!existsSync7(volumeDir)) {
|
|
16691
16756
|
console.error(
|
|
16692
16757
|
chalk16.red(
|
|
16693
16758
|
`\u2717 Directory not found: ${volumeConfig.name}. Create the directory and add files first.`
|
|
@@ -16724,9 +16789,9 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16724
16789
|
console.log(chalk16.blue("Processing artifact:"));
|
|
16725
16790
|
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
16726
16791
|
try {
|
|
16727
|
-
if (!
|
|
16792
|
+
if (!existsSync7(artifactDir)) {
|
|
16728
16793
|
printCommand(`mkdir ${ARTIFACT_DIR}`);
|
|
16729
|
-
await
|
|
16794
|
+
await mkdir6(artifactDir, { recursive: true });
|
|
16730
16795
|
}
|
|
16731
16796
|
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
16732
16797
|
const existingConfig = await readStorageConfig(artifactDir);
|
|
@@ -16785,28 +16850,15 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16785
16850
|
} catch {
|
|
16786
16851
|
process.exit(1);
|
|
16787
16852
|
}
|
|
16788
|
-
const
|
|
16789
|
-
|
|
16790
|
-
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
printCommand(`cd ${ARTIFACT_DIR}`);
|
|
16796
|
-
printCommand(`vm0 artifact pull ${serverVersion}`);
|
|
16797
|
-
try {
|
|
16798
|
-
await execVm0Command(["artifact", "pull", serverVersion], {
|
|
16799
|
-
cwd: artifactDir,
|
|
16800
|
-
silent: true
|
|
16801
|
-
});
|
|
16802
|
-
printCommand("cd ..");
|
|
16803
|
-
} catch (error43) {
|
|
16804
|
-
console.error(chalk16.red(`\u2717 Artifact pull failed`));
|
|
16805
|
-
if (error43 instanceof Error) {
|
|
16806
|
-
console.error(chalk16.gray(` ${error43.message}`));
|
|
16807
|
-
}
|
|
16808
|
-
}
|
|
16853
|
+
const runIds = parseRunIdsFromOutput(runOutput);
|
|
16854
|
+
if (runIds.runId || runIds.sessionId || runIds.checkpointId) {
|
|
16855
|
+
await saveCookState({
|
|
16856
|
+
lastRunId: runIds.runId,
|
|
16857
|
+
lastSessionId: runIds.sessionId,
|
|
16858
|
+
lastCheckpointId: runIds.checkpointId
|
|
16859
|
+
});
|
|
16809
16860
|
}
|
|
16861
|
+
await autoPullArtifact(runOutput, artifactDir);
|
|
16810
16862
|
} else {
|
|
16811
16863
|
console.log();
|
|
16812
16864
|
console.log("To run your agent:");
|
|
@@ -16815,6 +16867,81 @@ var cookCommand = new Command13().name("cook").description("One-click agent prep
|
|
|
16815
16867
|
);
|
|
16816
16868
|
}
|
|
16817
16869
|
});
|
|
16870
|
+
cookCmd.command("logs").description("View logs from the last cook run").action(async () => {
|
|
16871
|
+
const state = await loadCookState();
|
|
16872
|
+
if (!state.lastRunId) {
|
|
16873
|
+
console.error(chalk16.red("\u2717 No previous run found"));
|
|
16874
|
+
console.error(chalk16.gray(" Run 'vm0 cook <prompt>' first"));
|
|
16875
|
+
process.exit(1);
|
|
16876
|
+
}
|
|
16877
|
+
printCommand(`vm0 logs ${state.lastRunId}`);
|
|
16878
|
+
await execVm0Command(["logs", state.lastRunId]);
|
|
16879
|
+
});
|
|
16880
|
+
cookCmd.command("continue").description(
|
|
16881
|
+
"Continue from the last session (latest conversation and artifact)"
|
|
16882
|
+
).argument("<prompt>", "Prompt for the continued agent").action(async (prompt) => {
|
|
16883
|
+
const state = await loadCookState();
|
|
16884
|
+
if (!state.lastSessionId) {
|
|
16885
|
+
console.error(chalk16.red("\u2717 No previous session found"));
|
|
16886
|
+
console.error(chalk16.gray(" Run 'vm0 cook <prompt>' first"));
|
|
16887
|
+
process.exit(1);
|
|
16888
|
+
}
|
|
16889
|
+
const cwd = process.cwd();
|
|
16890
|
+
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
16891
|
+
printCommand(`vm0 run continue ${state.lastSessionId} "${prompt}"`);
|
|
16892
|
+
console.log();
|
|
16893
|
+
let runOutput;
|
|
16894
|
+
try {
|
|
16895
|
+
runOutput = await execVm0RunWithCapture(
|
|
16896
|
+
["run", "continue", state.lastSessionId, prompt],
|
|
16897
|
+
{ cwd }
|
|
16898
|
+
);
|
|
16899
|
+
} catch {
|
|
16900
|
+
process.exit(1);
|
|
16901
|
+
}
|
|
16902
|
+
const newIds = parseRunIdsFromOutput(runOutput);
|
|
16903
|
+
if (newIds.runId || newIds.sessionId || newIds.checkpointId) {
|
|
16904
|
+
await saveCookState({
|
|
16905
|
+
lastRunId: newIds.runId,
|
|
16906
|
+
lastSessionId: newIds.sessionId,
|
|
16907
|
+
lastCheckpointId: newIds.checkpointId
|
|
16908
|
+
});
|
|
16909
|
+
}
|
|
16910
|
+
await autoPullArtifact(runOutput, artifactDir);
|
|
16911
|
+
});
|
|
16912
|
+
cookCmd.command("resume").description(
|
|
16913
|
+
"Resume from the last checkpoint (snapshotted conversation and artifact)"
|
|
16914
|
+
).argument("<prompt>", "Prompt for the resumed agent").action(async (prompt) => {
|
|
16915
|
+
const state = await loadCookState();
|
|
16916
|
+
if (!state.lastCheckpointId) {
|
|
16917
|
+
console.error(chalk16.red("\u2717 No previous checkpoint found"));
|
|
16918
|
+
console.error(chalk16.gray(" Run 'vm0 cook <prompt>' first"));
|
|
16919
|
+
process.exit(1);
|
|
16920
|
+
}
|
|
16921
|
+
const cwd = process.cwd();
|
|
16922
|
+
const artifactDir = path11.join(cwd, ARTIFACT_DIR);
|
|
16923
|
+
printCommand(`vm0 run resume ${state.lastCheckpointId} "${prompt}"`);
|
|
16924
|
+
console.log();
|
|
16925
|
+
let runOutput;
|
|
16926
|
+
try {
|
|
16927
|
+
runOutput = await execVm0RunWithCapture(
|
|
16928
|
+
["run", "resume", state.lastCheckpointId, prompt],
|
|
16929
|
+
{ cwd }
|
|
16930
|
+
);
|
|
16931
|
+
} catch {
|
|
16932
|
+
process.exit(1);
|
|
16933
|
+
}
|
|
16934
|
+
const newIds = parseRunIdsFromOutput(runOutput);
|
|
16935
|
+
if (newIds.runId || newIds.sessionId || newIds.checkpointId) {
|
|
16936
|
+
await saveCookState({
|
|
16937
|
+
lastRunId: newIds.runId,
|
|
16938
|
+
lastSessionId: newIds.sessionId,
|
|
16939
|
+
lastCheckpointId: newIds.checkpointId
|
|
16940
|
+
});
|
|
16941
|
+
}
|
|
16942
|
+
await autoPullArtifact(runOutput, artifactDir);
|
|
16943
|
+
});
|
|
16944
|
+
var cookCommand = cookCmd;
|
|
16818
16945
|
|
|
16819
16946
|
// src/commands/image/index.ts
|
|
16820
16947
|
import { Command as Command18 } from "commander";
|
|
@@ -16822,8 +16949,8 @@ import { Command as Command18 } from "commander";
|
|
|
16822
16949
|
// src/commands/image/build.ts
|
|
16823
16950
|
import { Command as Command14 } from "commander";
|
|
16824
16951
|
import chalk17 from "chalk";
|
|
16825
|
-
import { readFile as
|
|
16826
|
-
import { existsSync as
|
|
16952
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
16953
|
+
import { existsSync as existsSync8 } from "fs";
|
|
16827
16954
|
|
|
16828
16955
|
// src/lib/dockerfile-validator.ts
|
|
16829
16956
|
var ALLOWED_INSTRUCTIONS = /* @__PURE__ */ new Set(["FROM", "RUN"]);
|
|
@@ -16860,7 +16987,7 @@ var sleep2 = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
|
16860
16987
|
var buildCommand = new Command14().name("build").description("Build a custom image from a Dockerfile").requiredOption("-f, --file <path>", "Path to Dockerfile").requiredOption("-n, --name <name>", "Name for the image").option("--delete-existing", "Delete existing image before building").action(
|
|
16861
16988
|
async (options) => {
|
|
16862
16989
|
const { file: file2, name, deleteExisting } = options;
|
|
16863
|
-
if (!
|
|
16990
|
+
if (!existsSync8(file2)) {
|
|
16864
16991
|
console.error(chalk17.red(`\u2717 Dockerfile not found: ${file2}`));
|
|
16865
16992
|
process.exit(1);
|
|
16866
16993
|
}
|
|
@@ -16883,7 +17010,7 @@ var buildCommand = new Command14().name("build").description("Build a custom ima
|
|
|
16883
17010
|
}
|
|
16884
17011
|
try {
|
|
16885
17012
|
const scope = await apiClient.getScope();
|
|
16886
|
-
const dockerfile = await
|
|
17013
|
+
const dockerfile = await readFile7(file2, "utf8");
|
|
16887
17014
|
const validation = validateDockerfile(dockerfile);
|
|
16888
17015
|
if (!validation.valid) {
|
|
16889
17016
|
console.error(chalk17.red("\u2717 Dockerfile validation failed\n"));
|
|
@@ -17573,11 +17700,115 @@ var setCommand = new Command21().name("set").description("Set your scope slug").
|
|
|
17573
17700
|
// src/commands/scope/index.ts
|
|
17574
17701
|
var scopeCommand = new Command22().name("scope").description("Manage your scope (namespace for images)").addCommand(statusCommand3).addCommand(setCommand);
|
|
17575
17702
|
|
|
17703
|
+
// src/commands/init.ts
|
|
17704
|
+
import { Command as Command23 } from "commander";
|
|
17705
|
+
import chalk24 from "chalk";
|
|
17706
|
+
import * as readline2 from "readline";
|
|
17707
|
+
import { existsSync as existsSync9 } from "fs";
|
|
17708
|
+
import { writeFile as writeFile7 } from "fs/promises";
|
|
17709
|
+
var VM0_YAML_FILE = "vm0.yaml";
|
|
17710
|
+
var AGENTS_MD_FILE = "AGENTS.md";
|
|
17711
|
+
function generateVm0Yaml(agentName) {
|
|
17712
|
+
return `version: "1.0"
|
|
17713
|
+
|
|
17714
|
+
agents:
|
|
17715
|
+
${agentName}:
|
|
17716
|
+
provider: claude-code
|
|
17717
|
+
# Build agentic workflow using natural language
|
|
17718
|
+
instructions: AGENTS.md
|
|
17719
|
+
# Agent skills - see https://github.com/vm0-ai/vm0-skills for available skills
|
|
17720
|
+
# skills:
|
|
17721
|
+
# - https://github.com/vm0-ai/vm0-skills/tree/main/github
|
|
17722
|
+
environment:
|
|
17723
|
+
# Get token using: claude setup-token, then add to .env file
|
|
17724
|
+
CLAUDE_CODE_OAUTH_TOKEN: \${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
17725
|
+
`;
|
|
17726
|
+
}
|
|
17727
|
+
function generateAgentsMd() {
|
|
17728
|
+
return `# Agent Instructions
|
|
17729
|
+
|
|
17730
|
+
You are a HackerNews AI content curator.
|
|
17731
|
+
|
|
17732
|
+
## Workflow
|
|
17733
|
+
|
|
17734
|
+
1. Go to HackerNews and read the top 10 articles
|
|
17735
|
+
2. Find and extract AI-related content from these articles
|
|
17736
|
+
3. Summarize the findings into a X (Twitter) post format
|
|
17737
|
+
4. Write the summary to content.md
|
|
17738
|
+
`;
|
|
17739
|
+
}
|
|
17740
|
+
function checkExistingFiles() {
|
|
17741
|
+
const existingFiles = [];
|
|
17742
|
+
if (existsSync9(VM0_YAML_FILE)) existingFiles.push(VM0_YAML_FILE);
|
|
17743
|
+
if (existsSync9(AGENTS_MD_FILE)) existingFiles.push(AGENTS_MD_FILE);
|
|
17744
|
+
return existingFiles;
|
|
17745
|
+
}
|
|
17746
|
+
async function promptAgentName() {
|
|
17747
|
+
const rl = readline2.createInterface({
|
|
17748
|
+
input: process.stdin,
|
|
17749
|
+
output: process.stdout
|
|
17750
|
+
});
|
|
17751
|
+
return new Promise((resolve2, reject) => {
|
|
17752
|
+
rl.question(chalk24.cyan("? Enter agent name: "), (answer) => {
|
|
17753
|
+
rl.close();
|
|
17754
|
+
resolve2(answer.trim());
|
|
17755
|
+
});
|
|
17756
|
+
rl.on("SIGINT", () => {
|
|
17757
|
+
rl.close();
|
|
17758
|
+
console.log();
|
|
17759
|
+
reject(new Error("User cancelled"));
|
|
17760
|
+
});
|
|
17761
|
+
});
|
|
17762
|
+
}
|
|
17763
|
+
var initCommand3 = new Command23().name("init").description("Initialize a new VM0 project in the current directory").option("-f, --force", "Overwrite existing files").option("-n, --name <name>", "Agent name (skips interactive prompt)").action(async (options) => {
|
|
17764
|
+
const existingFiles = checkExistingFiles();
|
|
17765
|
+
if (existingFiles.length > 0 && !options.force) {
|
|
17766
|
+
for (const file2 of existingFiles) {
|
|
17767
|
+
console.log(chalk24.red(`\u2717 ${file2} already exists`));
|
|
17768
|
+
}
|
|
17769
|
+
console.log();
|
|
17770
|
+
console.log(`To overwrite: ${chalk24.cyan("vm0 init --force")}`);
|
|
17771
|
+
process.exit(1);
|
|
17772
|
+
}
|
|
17773
|
+
let agentName;
|
|
17774
|
+
if (options.name) {
|
|
17775
|
+
agentName = options.name.trim();
|
|
17776
|
+
} else {
|
|
17777
|
+
try {
|
|
17778
|
+
agentName = await promptAgentName();
|
|
17779
|
+
} catch {
|
|
17780
|
+
process.exit(0);
|
|
17781
|
+
}
|
|
17782
|
+
}
|
|
17783
|
+
if (!agentName || !validateAgentName(agentName)) {
|
|
17784
|
+
console.log(chalk24.red("\u2717 Invalid agent name"));
|
|
17785
|
+
console.log(
|
|
17786
|
+
chalk24.gray(" Must be 3-64 characters, alphanumeric and hyphens only")
|
|
17787
|
+
);
|
|
17788
|
+
console.log(chalk24.gray(" Must start and end with letter or number"));
|
|
17789
|
+
process.exit(1);
|
|
17790
|
+
}
|
|
17791
|
+
await writeFile7(VM0_YAML_FILE, generateVm0Yaml(agentName));
|
|
17792
|
+
const vm0Status = existingFiles.includes(VM0_YAML_FILE) ? " (overwritten)" : "";
|
|
17793
|
+
console.log(chalk24.green(`\u2713 Created ${VM0_YAML_FILE}${vm0Status}`));
|
|
17794
|
+
await writeFile7(AGENTS_MD_FILE, generateAgentsMd());
|
|
17795
|
+
const agentsStatus = existingFiles.includes(AGENTS_MD_FILE) ? " (overwritten)" : "";
|
|
17796
|
+
console.log(chalk24.green(`\u2713 Created ${AGENTS_MD_FILE}${agentsStatus}`));
|
|
17797
|
+
console.log();
|
|
17798
|
+
console.log("Next steps:");
|
|
17799
|
+
console.log(
|
|
17800
|
+
` 1. Get your Claude Code token: ${chalk24.cyan("claude setup-token")}`
|
|
17801
|
+
);
|
|
17802
|
+
console.log(` 2. Set the environment variable (or add to .env file):`);
|
|
17803
|
+
console.log(chalk24.gray(` export CLAUDE_CODE_OAUTH_TOKEN=<your-token>`));
|
|
17804
|
+
console.log(` 3. Run your agent: ${chalk24.cyan('vm0 cook "your prompt"')}`);
|
|
17805
|
+
});
|
|
17806
|
+
|
|
17576
17807
|
// src/index.ts
|
|
17577
|
-
var program = new
|
|
17578
|
-
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.
|
|
17808
|
+
var program = new Command24();
|
|
17809
|
+
program.name("vm0").description("VM0 CLI - A modern build tool").version("4.25.0");
|
|
17579
17810
|
program.command("info").description("Display environment information").action(async () => {
|
|
17580
|
-
console.log(
|
|
17811
|
+
console.log(chalk25.cyan("System Information:"));
|
|
17581
17812
|
console.log(`Node Version: ${process.version}`);
|
|
17582
17813
|
console.log(`Platform: ${process.platform}`);
|
|
17583
17814
|
console.log(`Architecture: ${process.arch}`);
|
|
@@ -17605,6 +17836,7 @@ program.addCommand(cookCommand);
|
|
|
17605
17836
|
program.addCommand(imageCommand);
|
|
17606
17837
|
program.addCommand(logsCommand);
|
|
17607
17838
|
program.addCommand(scopeCommand);
|
|
17839
|
+
program.addCommand(initCommand3);
|
|
17608
17840
|
if (process.argv[1]?.endsWith("index.js") || process.argv[1]?.endsWith("index.ts") || process.argv[1]?.endsWith("vm0")) {
|
|
17609
17841
|
program.parse();
|
|
17610
17842
|
}
|