@beastmode-develeap/beastmode 0.1.5 → 0.1.6
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/dist/index.js +76 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6402,13 +6402,13 @@ var init_server = __esm({
|
|
|
6402
6402
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6403
6403
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6404
6404
|
import { z as z2 } from "zod";
|
|
6405
|
-
import { readFileSync as
|
|
6405
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync22, existsSync as existsSync29, readdirSync as readdirSync10, mkdirSync as mkdirSync18 } from "fs";
|
|
6406
6406
|
import { join as join27, resolve as resolve18, basename as basename5 } from "path";
|
|
6407
6407
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
6408
6408
|
function readJsonFile2(filePath) {
|
|
6409
6409
|
if (!existsSync29(filePath)) return null;
|
|
6410
6410
|
try {
|
|
6411
|
-
return JSON.parse(
|
|
6411
|
+
return JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
6412
6412
|
} catch {
|
|
6413
6413
|
return null;
|
|
6414
6414
|
}
|
|
@@ -6435,7 +6435,7 @@ function getFactoryPath() {
|
|
|
6435
6435
|
function readFactoryStatus(factoryDir) {
|
|
6436
6436
|
const bmDir = join27(factoryDir, ".beastmode");
|
|
6437
6437
|
const factoryIdentity = FactoryIdentitySchema.parse(
|
|
6438
|
-
JSON.parse(
|
|
6438
|
+
JSON.parse(readFileSync26(join27(bmDir, "factory.json"), "utf-8"))
|
|
6439
6439
|
);
|
|
6440
6440
|
const projectsDir = join27(bmDir, "projects");
|
|
6441
6441
|
const projectCount = existsSync29(projectsDir) ? readdirSync10(projectsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
@@ -6443,7 +6443,7 @@ function readFactoryStatus(factoryDir) {
|
|
|
6443
6443
|
let pluginNames = [];
|
|
6444
6444
|
if (existsSync29(lockPath)) {
|
|
6445
6445
|
try {
|
|
6446
|
-
const lock = JSON.parse(
|
|
6446
|
+
const lock = JSON.parse(readFileSync26(lockPath, "utf-8"));
|
|
6447
6447
|
pluginNames = Object.keys(lock.plugins || {});
|
|
6448
6448
|
} catch {
|
|
6449
6449
|
}
|
|
@@ -6479,7 +6479,7 @@ function readFactoryStatus(factoryDir) {
|
|
|
6479
6479
|
let pidAlive = false;
|
|
6480
6480
|
if (existsSync29(pidFile)) {
|
|
6481
6481
|
try {
|
|
6482
|
-
daemonPid = parseInt(
|
|
6482
|
+
daemonPid = parseInt(readFileSync26(pidFile, "utf-8").trim(), 10);
|
|
6483
6483
|
process.kill(daemonPid, 0);
|
|
6484
6484
|
pidAlive = true;
|
|
6485
6485
|
} catch {
|
|
@@ -6503,7 +6503,7 @@ function readBoardItems(factoryDir) {
|
|
|
6503
6503
|
const filePath = join27(factoryDir, ".beastmode", "board.json");
|
|
6504
6504
|
if (!existsSync29(filePath)) return [];
|
|
6505
6505
|
try {
|
|
6506
|
-
const raw = JSON.parse(
|
|
6506
|
+
const raw = JSON.parse(readFileSync26(filePath, "utf-8"));
|
|
6507
6507
|
return Array.isArray(raw.items) ? raw.items : [];
|
|
6508
6508
|
} catch {
|
|
6509
6509
|
return [];
|
|
@@ -6535,7 +6535,7 @@ function createMcpServer() {
|
|
|
6535
6535
|
async ({ key_path }) => {
|
|
6536
6536
|
const factoryDir = getFactoryPath();
|
|
6537
6537
|
const configPath = join27(factoryDir, ".beastmode", "config.json");
|
|
6538
|
-
const config = existsSync29(configPath) ? JSON.parse(
|
|
6538
|
+
const config = existsSync29(configPath) ? JSON.parse(readFileSync26(configPath, "utf-8")) : generateDefaults();
|
|
6539
6539
|
try {
|
|
6540
6540
|
const value = configGet(config, key_path);
|
|
6541
6541
|
return { content: [{ type: "text", text: JSON.stringify(value, null, 2) }] };
|
|
@@ -6554,7 +6554,7 @@ function createMcpServer() {
|
|
|
6554
6554
|
async ({ key_path, value }) => {
|
|
6555
6555
|
const factoryDir = getFactoryPath();
|
|
6556
6556
|
const configPath = join27(factoryDir, ".beastmode", "config.json");
|
|
6557
|
-
const config = existsSync29(configPath) ? JSON.parse(
|
|
6557
|
+
const config = existsSync29(configPath) ? JSON.parse(readFileSync26(configPath, "utf-8")) : generateDefaults();
|
|
6558
6558
|
const coerced = coerceValue(value);
|
|
6559
6559
|
const updated = configSet(config, key_path, coerced);
|
|
6560
6560
|
writeFileSync22(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
|
|
@@ -6673,7 +6673,7 @@ function createMcpServer() {
|
|
|
6673
6673
|
const lockPath = join27(bmDir, "extensions.lock");
|
|
6674
6674
|
if (existsSync29(lockPath)) {
|
|
6675
6675
|
try {
|
|
6676
|
-
const lock = JSON.parse(
|
|
6676
|
+
const lock = JSON.parse(readFileSync26(lockPath, "utf-8"));
|
|
6677
6677
|
plugins = lock.plugins || {};
|
|
6678
6678
|
} catch {
|
|
6679
6679
|
}
|
|
@@ -6713,7 +6713,7 @@ function createMcpServer() {
|
|
|
6713
6713
|
}
|
|
6714
6714
|
const projects = readdirSync10(projectsDir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
6715
6715
|
try {
|
|
6716
|
-
return JSON.parse(
|
|
6716
|
+
return JSON.parse(readFileSync26(join27(projectsDir, f), "utf-8"));
|
|
6717
6717
|
} catch {
|
|
6718
6718
|
return null;
|
|
6719
6719
|
}
|
|
@@ -6859,7 +6859,7 @@ init_file_writer();
|
|
|
6859
6859
|
import { Command } from "commander";
|
|
6860
6860
|
import inquirer from "inquirer";
|
|
6861
6861
|
import { resolve as resolve5, basename as basename4, join as join15 } from "path";
|
|
6862
|
-
import { existsSync as existsSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync12 } from "fs";
|
|
6862
|
+
import { existsSync as existsSync17, writeFileSync as writeFileSync13, mkdirSync as mkdirSync12, readFileSync as readFileSync14 } from "fs";
|
|
6863
6863
|
|
|
6864
6864
|
// src/cli/utils/docker.ts
|
|
6865
6865
|
import { existsSync as existsSync9 } from "fs";
|
|
@@ -7068,7 +7068,7 @@ function step(n, total, text) {
|
|
|
7068
7068
|
}
|
|
7069
7069
|
|
|
7070
7070
|
// src/cli/commands/init.ts
|
|
7071
|
-
var initCommand = new Command("init").description("Create a new BeastMode factory").argument("[name]", "Factory name (default: current directory name)").option("--project <path>", "Path to target project").option("--preset <preset>", "Pipeline preset (full, lean, prototype, infra, docs)").option("--backend <backend>", "Task backend (beastmode-board, github-issues)").option("--deploy <target>", "Deploy target (pr-only, vercel, aws-ecs, ...)").option("--methodology <name>", "Development methodology plugin").option("--plugin <name>", "Install plugin (repeatable)", collect, []).option("--from <template>", "Import config from template file").option("--ui", "Open web wizard instead of CLI").option("--yes", "Accept all defaults (non-interactive)").option("--github-token <token>", "GitHub PAT (avoids interactive prompt)").option("--board-password <password>", "Board UI password (avoids interactive prompt)").action(async (name, opts) => {
|
|
7071
|
+
var initCommand = new Command("init").description("Create a new BeastMode factory").argument("[name]", "Factory name (default: current directory name)").option("--project <path>", "Path to target project").option("--preset <preset>", "Pipeline preset (full, lean, prototype, infra, docs)").option("--backend <backend>", "Task backend (beastmode-board, github-issues)").option("--deploy <target>", "Deploy target (pr-only, vercel, aws-ecs, ...)").option("--methodology <name>", "Development methodology plugin").option("--plugin <name>", "Install plugin (repeatable)", collect, []).option("--from <template>", "Import config from template file").option("--ui", "Open web wizard instead of CLI").option("--yes", "Accept all defaults (non-interactive)").option("--github-token <token>", "GitHub PAT (avoids interactive prompt)").option("--github-token-file <path>", "Read GitHub PAT from file (safer than --github-token)").option("--board-password <password>", "Board UI password (avoids interactive prompt)").option("--board-password-file <path>", "Read board password from file").action(async (name, opts) => {
|
|
7072
7072
|
try {
|
|
7073
7073
|
await runInit(name, opts);
|
|
7074
7074
|
} catch (err) {
|
|
@@ -7080,6 +7080,9 @@ function collect(val, acc) {
|
|
|
7080
7080
|
acc.push(val);
|
|
7081
7081
|
return acc;
|
|
7082
7082
|
}
|
|
7083
|
+
function readSecretFile(filePath) {
|
|
7084
|
+
return readFileSync14(resolve5(filePath), "utf-8").trim();
|
|
7085
|
+
}
|
|
7083
7086
|
function isSourceRepo(dir) {
|
|
7084
7087
|
return existsSync17(resolve5(dir, "daemon")) && existsSync17(resolve5(dir, "board")) && existsSync17(resolve5(dir, "cli"));
|
|
7085
7088
|
}
|
|
@@ -7124,8 +7127,8 @@ async function runInit(name, opts) {
|
|
|
7124
7127
|
throw new Error(`Factory already exists at ./${factoryName}. Use 'beastmode config' to modify.`);
|
|
7125
7128
|
}
|
|
7126
7129
|
if (opts.from) {
|
|
7127
|
-
const { readFileSync:
|
|
7128
|
-
const templateContent =
|
|
7130
|
+
const { readFileSync: readFileSync29 } = await import("fs");
|
|
7131
|
+
const templateContent = readFileSync29(resolve5(opts.from), "utf-8");
|
|
7129
7132
|
const { parseTemplate: parseTemplate2 } = await Promise.resolve().then(() => (init_template_importer(), template_importer_exports));
|
|
7130
7133
|
const template = parseTemplate2(templateContent);
|
|
7131
7134
|
info(`Importing from template: ${opts.from}`);
|
|
@@ -7269,6 +7272,11 @@ async function runInit(name, opts) {
|
|
|
7269
7272
|
task_backend: { adapter: backendAdapter }
|
|
7270
7273
|
};
|
|
7271
7274
|
const config = resolveDefaults(partialConfig, stack);
|
|
7275
|
+
if (opts.githubTokenFile && !process.env.GITHUB_TOKEN) {
|
|
7276
|
+
process.env.GITHUB_TOKEN = readSecretFile(opts.githubTokenFile);
|
|
7277
|
+
} else if (opts.githubToken && !process.env.GITHUB_TOKEN) {
|
|
7278
|
+
process.env.GITHUB_TOKEN = opts.githubToken;
|
|
7279
|
+
}
|
|
7272
7280
|
const secretReport = validateSecrets(config, process.env, {
|
|
7273
7281
|
deploy_target: deployTarget
|
|
7274
7282
|
});
|
|
@@ -7305,8 +7313,8 @@ async function runInit(name, opts) {
|
|
|
7305
7313
|
}
|
|
7306
7314
|
}
|
|
7307
7315
|
}
|
|
7308
|
-
let uiPassword = "";
|
|
7309
|
-
if (!opts.yes) {
|
|
7316
|
+
let uiPassword = opts.boardPassword || (opts.boardPasswordFile ? readSecretFile(opts.boardPasswordFile) : "") || "";
|
|
7317
|
+
if (!uiPassword && !opts.yes) {
|
|
7310
7318
|
const answer = await inquirer.prompt([
|
|
7311
7319
|
{
|
|
7312
7320
|
type: "password",
|
|
@@ -7321,6 +7329,8 @@ async function runInit(name, opts) {
|
|
|
7321
7329
|
} else {
|
|
7322
7330
|
info("No board password \u2014 UI will be open (fine for local dev)");
|
|
7323
7331
|
}
|
|
7332
|
+
} else if (uiPassword) {
|
|
7333
|
+
success("Board UI password set");
|
|
7324
7334
|
}
|
|
7325
7335
|
step(5, totalSteps, "Boot");
|
|
7326
7336
|
const projectName = basename4(projectPath);
|
|
@@ -7373,7 +7383,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7373
7383
|
const factoryName = name || ".";
|
|
7374
7384
|
const targetDir = resolve5(factoryName === "." ? "." : factoryName);
|
|
7375
7385
|
step(1, totalSteps, "Credentials");
|
|
7376
|
-
let githubToken = opts.githubToken || process.env.GITHUB_TOKEN || "";
|
|
7386
|
+
let githubToken = opts.githubToken || (opts.githubTokenFile ? readSecretFile(opts.githubTokenFile) : "") || process.env.GITHUB_TOKEN || "";
|
|
7377
7387
|
if (!githubToken && !opts.yes) {
|
|
7378
7388
|
const answer = await inquirer.prompt([
|
|
7379
7389
|
{
|
|
@@ -7390,7 +7400,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7390
7400
|
} else {
|
|
7391
7401
|
warn("GITHUB_TOKEN not set \u2014 add to .env later");
|
|
7392
7402
|
}
|
|
7393
|
-
let uiPassword = opts.boardPassword || "";
|
|
7403
|
+
let uiPassword = opts.boardPassword || (opts.boardPasswordFile ? readSecretFile(opts.boardPasswordFile) : "") || "";
|
|
7394
7404
|
if (!uiPassword && !opts.yes) {
|
|
7395
7405
|
const { password } = await inquirer.prompt([
|
|
7396
7406
|
{
|
|
@@ -7498,7 +7508,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7498
7508
|
// src/cli/commands/export-config.ts
|
|
7499
7509
|
init_export_adapter();
|
|
7500
7510
|
import { Command as Command2 } from "commander";
|
|
7501
|
-
import { readFileSync as
|
|
7511
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync14, existsSync as existsSync18, readdirSync as readdirSync7 } from "fs";
|
|
7502
7512
|
import { resolve as resolve6, join as join16 } from "path";
|
|
7503
7513
|
function exportFactory(factoryDir, outputPath) {
|
|
7504
7514
|
const bmDir = join16(factoryDir, ".beastmode");
|
|
@@ -7506,12 +7516,12 @@ function exportFactory(factoryDir, outputPath) {
|
|
|
7506
7516
|
if (!existsSync18(configPath)) {
|
|
7507
7517
|
throw new Error(`No factory found at ${factoryDir}`);
|
|
7508
7518
|
}
|
|
7509
|
-
const config = JSON.parse(
|
|
7510
|
-
const identity = JSON.parse(
|
|
7519
|
+
const config = JSON.parse(readFileSync15(configPath, "utf-8"));
|
|
7520
|
+
const identity = JSON.parse(readFileSync15(join16(bmDir, "factory.json"), "utf-8"));
|
|
7511
7521
|
let plugins = [];
|
|
7512
7522
|
const lockPath = join16(bmDir, "extensions.lock");
|
|
7513
7523
|
if (existsSync18(lockPath)) {
|
|
7514
|
-
const lock = JSON.parse(
|
|
7524
|
+
const lock = JSON.parse(readFileSync15(lockPath, "utf-8"));
|
|
7515
7525
|
plugins = Object.keys(lock.plugins || {});
|
|
7516
7526
|
}
|
|
7517
7527
|
const template = {
|
|
@@ -7547,14 +7557,14 @@ function createArtifactExportCommand(artifact) {
|
|
|
7547
7557
|
throw new Error(`No scenarios directory found in run ${opts.run}`);
|
|
7548
7558
|
}
|
|
7549
7559
|
const files = readdirSync7(scenariosDir).filter((f) => f.endsWith(".md")).sort();
|
|
7550
|
-
sourceContent = files.map((f) =>
|
|
7560
|
+
sourceContent = files.map((f) => readFileSync15(join16(scenariosDir, f), "utf-8")).join("\n\n---\n\n");
|
|
7551
7561
|
} else {
|
|
7552
7562
|
const artifactFile = artifact === "nlspec" ? "nlspec.md" : "plan.md";
|
|
7553
7563
|
const artifactPath = join16(runDir, artifactFile);
|
|
7554
7564
|
if (!existsSync18(artifactPath)) {
|
|
7555
7565
|
throw new Error(`${artifactFile} not found in run ${opts.run}`);
|
|
7556
7566
|
}
|
|
7557
|
-
sourceContent =
|
|
7567
|
+
sourceContent = readFileSync15(artifactPath, "utf-8");
|
|
7558
7568
|
}
|
|
7559
7569
|
const result = runExportAdapter(opts.adapter, sourceContent);
|
|
7560
7570
|
if (opts.output) {
|
|
@@ -7778,7 +7788,7 @@ init_skill_manager();
|
|
|
7778
7788
|
init_presets();
|
|
7779
7789
|
import { Command as Command6 } from "commander";
|
|
7780
7790
|
import { resolve as resolve10 } from "path";
|
|
7781
|
-
import { readFileSync as
|
|
7791
|
+
import { readFileSync as readFileSync16, existsSync as existsSync19 } from "fs";
|
|
7782
7792
|
import { join as join17 } from "path";
|
|
7783
7793
|
function listPluginsAction(factoryDir) {
|
|
7784
7794
|
const lockPath = join17(factoryDir, ".beastmode", "extensions.lock");
|
|
@@ -7786,7 +7796,7 @@ function listPluginsAction(factoryDir) {
|
|
|
7786
7796
|
console.log(" No plugins installed (extensions.lock not found).");
|
|
7787
7797
|
return;
|
|
7788
7798
|
}
|
|
7789
|
-
const lock = JSON.parse(
|
|
7799
|
+
const lock = JSON.parse(readFileSync16(lockPath, "utf-8"));
|
|
7790
7800
|
const plugins = lock.plugins || {};
|
|
7791
7801
|
const names = Object.keys(plugins);
|
|
7792
7802
|
if (names.length === 0) {
|
|
@@ -7884,7 +7894,7 @@ var listCommand = new Command6("list").description("List installed extensions an
|
|
|
7884
7894
|
// src/cli/commands/import-cmd.ts
|
|
7885
7895
|
init_import_adapter();
|
|
7886
7896
|
import { Command as Command7 } from "commander";
|
|
7887
|
-
import { readFileSync as
|
|
7897
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync15, mkdirSync as mkdirSync13, existsSync as existsSync20 } from "fs";
|
|
7888
7898
|
import { resolve as resolve11, join as join18 } from "path";
|
|
7889
7899
|
var VALID_ARTIFACTS = ["nlspec", "plan", "scenarios"];
|
|
7890
7900
|
function createArtifactCommand(artifact) {
|
|
@@ -7894,7 +7904,7 @@ function createArtifactCommand(artifact) {
|
|
|
7894
7904
|
if (!existsSync20(sourcePath)) {
|
|
7895
7905
|
throw new Error(`Source file not found: ${sourcePath}`);
|
|
7896
7906
|
}
|
|
7897
|
-
const sourceContent =
|
|
7907
|
+
const sourceContent = readFileSync17(sourcePath, "utf-8");
|
|
7898
7908
|
const result = runImportAdapter(opts.adapter, sourceContent);
|
|
7899
7909
|
if (opts.output) {
|
|
7900
7910
|
const outputPath = resolve11(opts.output);
|
|
@@ -7930,7 +7940,7 @@ for (const artifact of VALID_ARTIFACTS) {
|
|
|
7930
7940
|
init_status_checker();
|
|
7931
7941
|
init_schemas();
|
|
7932
7942
|
import { Command as Command8 } from "commander";
|
|
7933
|
-
import { existsSync as existsSync21, readFileSync as
|
|
7943
|
+
import { existsSync as existsSync21, readFileSync as readFileSync18, readdirSync as readdirSync8 } from "fs";
|
|
7934
7944
|
import { execSync as execSync4 } from "child_process";
|
|
7935
7945
|
import { join as join19, resolve as resolve12 } from "path";
|
|
7936
7946
|
function statusAction(factoryDir, opts) {
|
|
@@ -7939,7 +7949,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7939
7949
|
throw new Error(`No factory found at ${factoryDir}`);
|
|
7940
7950
|
}
|
|
7941
7951
|
const factoryJsonPath = join19(bmDir, "factory.json");
|
|
7942
|
-
const rawIdentity = JSON.parse(
|
|
7952
|
+
const rawIdentity = JSON.parse(readFileSync18(factoryJsonPath, "utf-8"));
|
|
7943
7953
|
const factoryIdentity = FactoryIdentitySchema.parse(rawIdentity);
|
|
7944
7954
|
const projectsDir = join19(bmDir, "projects");
|
|
7945
7955
|
const projectCount = existsSync21(projectsDir) ? readdirSync8(projectsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
@@ -7949,7 +7959,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7949
7959
|
let mcpServers = {};
|
|
7950
7960
|
if (existsSync21(mcpPath)) {
|
|
7951
7961
|
try {
|
|
7952
|
-
const raw = JSON.parse(
|
|
7962
|
+
const raw = JSON.parse(readFileSync18(mcpPath, "utf-8"));
|
|
7953
7963
|
mcpServers = raw.servers || {};
|
|
7954
7964
|
} catch {
|
|
7955
7965
|
}
|
|
@@ -7958,7 +7968,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7958
7968
|
let hooks = {};
|
|
7959
7969
|
if (existsSync21(hooksPath)) {
|
|
7960
7970
|
try {
|
|
7961
|
-
const raw = JSON.parse(
|
|
7971
|
+
const raw = JSON.parse(readFileSync18(hooksPath, "utf-8"));
|
|
7962
7972
|
hooks = raw.hooks || {};
|
|
7963
7973
|
} catch {
|
|
7964
7974
|
}
|
|
@@ -7975,7 +7985,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7975
7985
|
let pidAlive = false;
|
|
7976
7986
|
if (existsSync21(pidPath)) {
|
|
7977
7987
|
try {
|
|
7978
|
-
daemonPid = parseInt(
|
|
7988
|
+
daemonPid = parseInt(readFileSync18(pidPath, "utf-8").trim(), 10);
|
|
7979
7989
|
process.kill(daemonPid, 0);
|
|
7980
7990
|
pidAlive = true;
|
|
7981
7991
|
} catch {
|
|
@@ -8048,7 +8058,7 @@ var statusCommand = new Command8("status").description("Show factory status over
|
|
|
8048
8058
|
// src/cli/commands/config-cmd.ts
|
|
8049
8059
|
init_config_manager();
|
|
8050
8060
|
import { Command as Command9 } from "commander";
|
|
8051
|
-
import { existsSync as existsSync22, readFileSync as
|
|
8061
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
|
|
8052
8062
|
import { join as join20, resolve as resolve13 } from "path";
|
|
8053
8063
|
import { execSync as execSync5 } from "child_process";
|
|
8054
8064
|
function readConfig2(factoryDir) {
|
|
@@ -8056,7 +8066,7 @@ function readConfig2(factoryDir) {
|
|
|
8056
8066
|
if (!existsSync22(configPath)) {
|
|
8057
8067
|
throw new Error("No config.json found. Run beastmode init first.");
|
|
8058
8068
|
}
|
|
8059
|
-
return JSON.parse(
|
|
8069
|
+
return JSON.parse(readFileSync19(configPath, "utf-8"));
|
|
8060
8070
|
}
|
|
8061
8071
|
function writeConfig2(factoryDir, config) {
|
|
8062
8072
|
const configPath = join20(factoryDir, ".beastmode", "config.json");
|
|
@@ -8138,7 +8148,7 @@ init_schemas();
|
|
|
8138
8148
|
init_version();
|
|
8139
8149
|
init_plugin_resolver();
|
|
8140
8150
|
import { Command as Command11 } from "commander";
|
|
8141
|
-
import { existsSync as existsSync24, readFileSync as
|
|
8151
|
+
import { existsSync as existsSync24, readFileSync as readFileSync21, readdirSync as readdirSync9 } from "fs";
|
|
8142
8152
|
import { join as join22, resolve as resolve15 } from "path";
|
|
8143
8153
|
import { execSync as execSync6 } from "child_process";
|
|
8144
8154
|
import { homedir as homedir2, platform } from "os";
|
|
@@ -8148,7 +8158,7 @@ import * as https from "https";
|
|
|
8148
8158
|
// src/cli/commands/board.ts
|
|
8149
8159
|
import { Command as Command10 } from "commander";
|
|
8150
8160
|
import { resolve as resolve14, join as join21 } from "path";
|
|
8151
|
-
import { existsSync as existsSync23, readFileSync as
|
|
8161
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20, mkdirSync as mkdirSync14, writeFileSync as writeFileSync17 } from "fs";
|
|
8152
8162
|
var boardCommand = new Command10("board").description("Launch the BeastMode Board web UI").option("--port <number>", "Port to serve on", "7669").option("--host <host>", "Host to bind to (use 0.0.0.0 for external access)", "127.0.0.1").action(async (opts) => {
|
|
8153
8163
|
try {
|
|
8154
8164
|
await runBoard(opts);
|
|
@@ -8192,7 +8202,7 @@ async function runBoard(opts) {
|
|
|
8192
8202
|
}
|
|
8193
8203
|
}
|
|
8194
8204
|
const factoryJsonPath = join21(factoryDir, ".beastmode", "factory.json");
|
|
8195
|
-
const factoryJson = JSON.parse(
|
|
8205
|
+
const factoryJson = JSON.parse(readFileSync20(factoryJsonPath, "utf-8"));
|
|
8196
8206
|
const factoryName = factoryJson.factory_name || "BeastMode Factory";
|
|
8197
8207
|
header(`BeastMode Board \u2014 ${factoryName}`);
|
|
8198
8208
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
@@ -8430,7 +8440,7 @@ function checkProjectDirectory(factoryDir) {
|
|
|
8430
8440
|
let anyFail = false;
|
|
8431
8441
|
for (const file of projectFiles) {
|
|
8432
8442
|
try {
|
|
8433
|
-
const proj = JSON.parse(
|
|
8443
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8434
8444
|
const projPath = proj.path || "";
|
|
8435
8445
|
const projName = proj.name || file.replace(".json", "");
|
|
8436
8446
|
if (!projPath || !existsSync24(projPath)) {
|
|
@@ -8514,7 +8524,7 @@ function checkStack(factoryDir) {
|
|
|
8514
8524
|
const stacks = [];
|
|
8515
8525
|
for (const file of projectFiles) {
|
|
8516
8526
|
try {
|
|
8517
|
-
const proj = JSON.parse(
|
|
8527
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8518
8528
|
const name = proj.name || file.replace(".json", "");
|
|
8519
8529
|
const detected = proj.stack?.detected || "unknown";
|
|
8520
8530
|
const build = proj.stack?.build_command || "";
|
|
@@ -8563,7 +8573,7 @@ function checkBoardPassword(env, factoryDir) {
|
|
|
8563
8573
|
for (const filePath of [dotEnv, secretsEnv]) {
|
|
8564
8574
|
if (existsSync24(filePath)) {
|
|
8565
8575
|
try {
|
|
8566
|
-
const content =
|
|
8576
|
+
const content = readFileSync21(filePath, "utf-8");
|
|
8567
8577
|
const lines = content.split("\n");
|
|
8568
8578
|
const line = lines.find((l) => l.startsWith("BEASTMODE_UI_PASSWORD="));
|
|
8569
8579
|
if (line) {
|
|
@@ -8590,7 +8600,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8590
8600
|
let factoryIdentity = null;
|
|
8591
8601
|
if (factoryDirExists) {
|
|
8592
8602
|
try {
|
|
8593
|
-
const raw = JSON.parse(
|
|
8603
|
+
const raw = JSON.parse(readFileSync21(join22(bmDir, "factory.json"), "utf-8"));
|
|
8594
8604
|
factoryIdentity = FactoryIdentitySchema.parse(raw);
|
|
8595
8605
|
} catch {
|
|
8596
8606
|
}
|
|
@@ -8601,7 +8611,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8601
8611
|
const configPath = join22(bmDir, "config.json");
|
|
8602
8612
|
if (existsSync24(configPath)) {
|
|
8603
8613
|
try {
|
|
8604
|
-
const raw = JSON.parse(
|
|
8614
|
+
const raw = JSON.parse(readFileSync21(configPath, "utf-8"));
|
|
8605
8615
|
const result = FactoryConfigSchema.safeParse(raw);
|
|
8606
8616
|
if (result.success) {
|
|
8607
8617
|
config = raw;
|
|
@@ -8622,7 +8632,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8622
8632
|
for (const file of readdirSync9(projectsDir)) {
|
|
8623
8633
|
if (file.endsWith(".json")) {
|
|
8624
8634
|
try {
|
|
8625
|
-
const proj = JSON.parse(
|
|
8635
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8626
8636
|
if (proj.path) {
|
|
8627
8637
|
projectPaths.push({
|
|
8628
8638
|
name: proj.name || file.replace(".json", ""),
|
|
@@ -8644,7 +8654,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8644
8654
|
const manifestPath = join22(pluginsDir, pluginName, "manifest.json");
|
|
8645
8655
|
if (existsSync24(manifestPath)) {
|
|
8646
8656
|
try {
|
|
8647
|
-
const manifest = JSON.parse(
|
|
8657
|
+
const manifest = JSON.parse(readFileSync21(manifestPath, "utf-8"));
|
|
8648
8658
|
installedPlugins.push({
|
|
8649
8659
|
name: pluginName,
|
|
8650
8660
|
engine_version: manifest.engine_version || "*"
|
|
@@ -8753,21 +8763,21 @@ init_upgrader();
|
|
|
8753
8763
|
init_schemas();
|
|
8754
8764
|
init_version();
|
|
8755
8765
|
import { Command as Command12 } from "commander";
|
|
8756
|
-
import { existsSync as existsSync25, readFileSync as
|
|
8766
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "fs";
|
|
8757
8767
|
import { join as join23, resolve as resolve16 } from "path";
|
|
8758
8768
|
function readIdentity(factoryDir) {
|
|
8759
8769
|
const path = join23(factoryDir, ".beastmode", "factory.json");
|
|
8760
8770
|
if (!existsSync25(path)) {
|
|
8761
8771
|
throw new Error("No factory.json found. Run beastmode init first.");
|
|
8762
8772
|
}
|
|
8763
|
-
return FactoryIdentitySchema.parse(JSON.parse(
|
|
8773
|
+
return FactoryIdentitySchema.parse(JSON.parse(readFileSync22(path, "utf-8")));
|
|
8764
8774
|
}
|
|
8765
8775
|
function readConfig3(factoryDir) {
|
|
8766
8776
|
const path = join23(factoryDir, ".beastmode", "config.json");
|
|
8767
8777
|
if (!existsSync25(path)) {
|
|
8768
8778
|
return {};
|
|
8769
8779
|
}
|
|
8770
|
-
return JSON.parse(
|
|
8780
|
+
return JSON.parse(readFileSync22(path, "utf-8"));
|
|
8771
8781
|
}
|
|
8772
8782
|
function upgradeCheckAction(factoryDir) {
|
|
8773
8783
|
const identity = readIdentity(factoryDir);
|
|
@@ -8835,7 +8845,7 @@ var upgradeCommand = new Command12("upgrade").description("Upgrade engine versio
|
|
|
8835
8845
|
// src/cli/commands/migrate.ts
|
|
8836
8846
|
import { Command as Command13 } from "commander";
|
|
8837
8847
|
import { resolve as resolve17, join as join24 } from "path";
|
|
8838
|
-
import { existsSync as existsSync26, readFileSync as
|
|
8848
|
+
import { existsSync as existsSync26, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync19 } from "fs";
|
|
8839
8849
|
init_migrator();
|
|
8840
8850
|
var migrateCommand = new Command13("migrate").description("Migrate a daemon config into a .beastmode/ factory").option("--config <path>", "Path to beastmode.daemon.json").option("--dry-run", "Show what would be created without writing files").action(async (opts) => {
|
|
8841
8851
|
try {
|
|
@@ -8856,7 +8866,7 @@ async function runMigrate(opts) {
|
|
|
8856
8866
|
}
|
|
8857
8867
|
header("BeastMode Migrate");
|
|
8858
8868
|
info(`Reading daemon config from: ${configPath}`);
|
|
8859
|
-
const configContent =
|
|
8869
|
+
const configContent = readFileSync23(configPath, "utf-8");
|
|
8860
8870
|
const daemonConfig = parseDaemonConfig(configContent);
|
|
8861
8871
|
const runsDir = join24(cwd, "runs");
|
|
8862
8872
|
let runDirs = [];
|
|
@@ -8874,7 +8884,7 @@ async function runMigrate(opts) {
|
|
|
8874
8884
|
const cpPath = join24(runsDir, dir, "checkpoint.json");
|
|
8875
8885
|
if (existsSync26(cpPath)) {
|
|
8876
8886
|
try {
|
|
8877
|
-
const cp = JSON.parse(
|
|
8887
|
+
const cp = JSON.parse(readFileSync23(cpPath, "utf-8"));
|
|
8878
8888
|
checkpoints.set(dir, cp);
|
|
8879
8889
|
} catch {
|
|
8880
8890
|
}
|
|
@@ -8971,7 +8981,7 @@ async function runMigrate(opts) {
|
|
|
8971
8981
|
// src/cli/commands/run.ts
|
|
8972
8982
|
import { Command as Command14 } from "commander";
|
|
8973
8983
|
import { join as join25 } from "path";
|
|
8974
|
-
import { existsSync as existsSync27, readFileSync as
|
|
8984
|
+
import { existsSync as existsSync27, readFileSync as readFileSync24, writeFileSync as writeFileSync20, mkdirSync as mkdirSync16 } from "fs";
|
|
8975
8985
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8976
8986
|
init_bridge();
|
|
8977
8987
|
init_schemas();
|
|
@@ -9000,7 +9010,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9000
9010
|
throw new Error("Factory config not found. Run 'beastmode init' first.");
|
|
9001
9011
|
}
|
|
9002
9012
|
const factoryConfig = FactoryConfigSchema.parse(
|
|
9003
|
-
JSON.parse(
|
|
9013
|
+
JSON.parse(readFileSync24(configPath, "utf-8"))
|
|
9004
9014
|
);
|
|
9005
9015
|
let projectConfig = null;
|
|
9006
9016
|
const projectsDir = join25(bmDir, "projects");
|
|
@@ -9017,11 +9027,11 @@ async function runPipeline(projectName, opts) {
|
|
|
9017
9027
|
throw new Error(`Project not found: ${projectName}`);
|
|
9018
9028
|
}
|
|
9019
9029
|
projectConfig = ProjectConfigSchema.parse(
|
|
9020
|
-
JSON.parse(
|
|
9030
|
+
JSON.parse(readFileSync24(join25(projectsDir, file), "utf-8"))
|
|
9021
9031
|
);
|
|
9022
9032
|
} else if (projectFiles.length > 0) {
|
|
9023
9033
|
projectConfig = ProjectConfigSchema.parse(
|
|
9024
|
-
JSON.parse(
|
|
9034
|
+
JSON.parse(readFileSync24(join25(projectsDir, projectFiles[0]), "utf-8"))
|
|
9025
9035
|
);
|
|
9026
9036
|
info(`Using project: ${projectConfig.name}`);
|
|
9027
9037
|
}
|
|
@@ -9030,7 +9040,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9030
9040
|
let boardItems = [];
|
|
9031
9041
|
if (existsSync27(boardPath)) {
|
|
9032
9042
|
try {
|
|
9033
|
-
const raw = JSON.parse(
|
|
9043
|
+
const raw = JSON.parse(readFileSync24(boardPath, "utf-8"));
|
|
9034
9044
|
boardItems = Array.isArray(raw.items) ? raw.items : [];
|
|
9035
9045
|
} catch {
|
|
9036
9046
|
boardItems = [];
|
|
@@ -9104,7 +9114,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9104
9114
|
const startTime = Date.now();
|
|
9105
9115
|
const pollInterval = setInterval(() => {
|
|
9106
9116
|
try {
|
|
9107
|
-
const board = JSON.parse(
|
|
9117
|
+
const board = JSON.parse(readFileSync24(boardPath, "utf-8"));
|
|
9108
9118
|
const items = Array.isArray(board.items) ? board.items : [];
|
|
9109
9119
|
const taskItem = items.find((i) => i.id === taskId);
|
|
9110
9120
|
if (taskItem) {
|
|
@@ -9147,7 +9157,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9147
9157
|
// src/cli/commands/daemon-cmd.ts
|
|
9148
9158
|
import { Command as Command15 } from "commander";
|
|
9149
9159
|
import { join as join26 } from "path";
|
|
9150
|
-
import { existsSync as existsSync28, readFileSync as
|
|
9160
|
+
import { existsSync as existsSync28, readFileSync as readFileSync25, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17 } from "fs";
|
|
9151
9161
|
init_bridge();
|
|
9152
9162
|
init_schemas();
|
|
9153
9163
|
var daemonCommand = new Command15("daemon").description("Start the BeastMode daemon via bridge").option("--dry-run", "Generate config but don't start daemon").option(
|
|
@@ -9176,7 +9186,7 @@ async function runDaemon(opts) {
|
|
|
9176
9186
|
throw new Error("Factory config not found. Run 'beastmode init' first.");
|
|
9177
9187
|
}
|
|
9178
9188
|
const factoryConfig = FactoryConfigSchema.parse(
|
|
9179
|
-
JSON.parse(
|
|
9189
|
+
JSON.parse(readFileSync25(configPath, "utf-8"))
|
|
9180
9190
|
);
|
|
9181
9191
|
let projectConfig = null;
|
|
9182
9192
|
const projectsDir = join26(bmDir, "projects");
|
|
@@ -9187,7 +9197,7 @@ async function runDaemon(opts) {
|
|
|
9187
9197
|
);
|
|
9188
9198
|
if (projectFiles.length > 0) {
|
|
9189
9199
|
projectConfig = ProjectConfigSchema.parse(
|
|
9190
|
-
JSON.parse(
|
|
9200
|
+
JSON.parse(readFileSync25(join26(projectsDir, projectFiles[0]), "utf-8"))
|
|
9191
9201
|
);
|
|
9192
9202
|
info(`Using project: ${projectConfig.name}`);
|
|
9193
9203
|
}
|
|
@@ -9289,7 +9299,7 @@ var mcpCommand = new Command16("mcp").description("Start the BeastMode MCP serve
|
|
|
9289
9299
|
// src/cli/commands/deploy.ts
|
|
9290
9300
|
import { Command as Command17 } from "commander";
|
|
9291
9301
|
import { resolve as resolve19, join as join28 } from "path";
|
|
9292
|
-
import { existsSync as existsSync30, writeFileSync as writeFileSync23, readFileSync as
|
|
9302
|
+
import { existsSync as existsSync30, writeFileSync as writeFileSync23, readFileSync as readFileSync27 } from "fs";
|
|
9293
9303
|
import { execSync as execSync7 } from "child_process";
|
|
9294
9304
|
import { randomBytes } from "crypto";
|
|
9295
9305
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -9379,8 +9389,8 @@ async function runDeploy(opts) {
|
|
|
9379
9389
|
const host = opts.host;
|
|
9380
9390
|
const dotEnv = join28(factoryDir, ".env");
|
|
9381
9391
|
const secretsEnv = join28(bmDir, "secrets.env.local");
|
|
9382
|
-
const envContent = existsSync30(dotEnv) ?
|
|
9383
|
-
const secretsContent = existsSync30(secretsEnv) ?
|
|
9392
|
+
const envContent = existsSync30(dotEnv) ? readFileSync27(dotEnv, "utf-8") : "";
|
|
9393
|
+
const secretsContent = existsSync30(secretsEnv) ? readFileSync27(secretsEnv, "utf-8") : "";
|
|
9384
9394
|
const hasPassword = envContent.includes("BEASTMODE_UI_PASSWORD=") && !envContent.includes("BEASTMODE_UI_PASSWORD=\n") || secretsContent.includes("BEASTMODE_UI_PASSWORD=") && !secretsContent.includes("BEASTMODE_UI_PASSWORD=\n") || !!process.env.BEASTMODE_UI_PASSWORD;
|
|
9385
9395
|
if (!hasPassword && opts.host === "0.0.0.0") {
|
|
9386
9396
|
const generated = randomBytes(18).toString("base64url");
|
|
@@ -9389,7 +9399,7 @@ async function runDeploy(opts) {
|
|
|
9389
9399
|
# Auto-generated board UI password (deploy)
|
|
9390
9400
|
BEASTMODE_UI_PASSWORD=${generated}
|
|
9391
9401
|
`;
|
|
9392
|
-
writeFileSync23(target, (existsSync30(target) ?
|
|
9402
|
+
writeFileSync23(target, (existsSync30(target) ? readFileSync27(target, "utf-8") : "") + append, "utf-8");
|
|
9393
9403
|
info(`Board UI password auto-generated and saved to ${target}`);
|
|
9394
9404
|
success(`Password: ${generated}`);
|
|
9395
9405
|
info("Save this password \u2014 you'll need it to access the board UI.");
|
|
@@ -10007,12 +10017,12 @@ var logsCommand = new Command21("logs").description("Stream BeastMode service lo
|
|
|
10007
10017
|
|
|
10008
10018
|
// src/cli/commands/update.ts
|
|
10009
10019
|
import { Command as Command22 } from "commander";
|
|
10010
|
-
import { readFileSync as
|
|
10020
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync25 } from "fs";
|
|
10011
10021
|
async function runUpdate(opts) {
|
|
10012
10022
|
const cwd = opts.cwd ?? process.cwd();
|
|
10013
10023
|
const composePath = requireComposeFile(cwd);
|
|
10014
10024
|
if (opts.tag) {
|
|
10015
|
-
let content =
|
|
10025
|
+
let content = readFileSync28(composePath, "utf-8");
|
|
10016
10026
|
const tagPattern = new RegExp(
|
|
10017
10027
|
`(${GHCR_IMAGE_PREFIX.replace(/[/]/g, "\\/")}\\/(?:board|daemon|ui)):([\\w.\\-]+)`,
|
|
10018
10028
|
"g"
|