@beastmode-develeap/beastmode 0.1.4 → 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 +94 -67
- 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";
|
|
@@ -6908,7 +6908,24 @@ function loginToGhcr(token) {
|
|
|
6908
6908
|
timeout: 15e3,
|
|
6909
6909
|
stdio: ["pipe", "pipe", "pipe"]
|
|
6910
6910
|
});
|
|
6911
|
-
|
|
6911
|
+
try {
|
|
6912
|
+
execSync(`docker manifest inspect ${GHCR_IMAGE_PREFIX}/board:latest`, {
|
|
6913
|
+
encoding: "utf-8",
|
|
6914
|
+
timeout: 15e3,
|
|
6915
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6916
|
+
});
|
|
6917
|
+
return true;
|
|
6918
|
+
} catch {
|
|
6919
|
+
try {
|
|
6920
|
+
execSync("docker logout ghcr.io", {
|
|
6921
|
+
encoding: "utf-8",
|
|
6922
|
+
timeout: 5e3,
|
|
6923
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6924
|
+
});
|
|
6925
|
+
} catch {
|
|
6926
|
+
}
|
|
6927
|
+
return false;
|
|
6928
|
+
}
|
|
6912
6929
|
} catch {
|
|
6913
6930
|
return false;
|
|
6914
6931
|
}
|
|
@@ -7051,7 +7068,7 @@ function step(n, total, text) {
|
|
|
7051
7068
|
}
|
|
7052
7069
|
|
|
7053
7070
|
// src/cli/commands/init.ts
|
|
7054
|
-
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) => {
|
|
7055
7072
|
try {
|
|
7056
7073
|
await runInit(name, opts);
|
|
7057
7074
|
} catch (err) {
|
|
@@ -7063,6 +7080,9 @@ function collect(val, acc) {
|
|
|
7063
7080
|
acc.push(val);
|
|
7064
7081
|
return acc;
|
|
7065
7082
|
}
|
|
7083
|
+
function readSecretFile(filePath) {
|
|
7084
|
+
return readFileSync14(resolve5(filePath), "utf-8").trim();
|
|
7085
|
+
}
|
|
7066
7086
|
function isSourceRepo(dir) {
|
|
7067
7087
|
return existsSync17(resolve5(dir, "daemon")) && existsSync17(resolve5(dir, "board")) && existsSync17(resolve5(dir, "cli"));
|
|
7068
7088
|
}
|
|
@@ -7107,8 +7127,8 @@ async function runInit(name, opts) {
|
|
|
7107
7127
|
throw new Error(`Factory already exists at ./${factoryName}. Use 'beastmode config' to modify.`);
|
|
7108
7128
|
}
|
|
7109
7129
|
if (opts.from) {
|
|
7110
|
-
const { readFileSync:
|
|
7111
|
-
const templateContent =
|
|
7130
|
+
const { readFileSync: readFileSync29 } = await import("fs");
|
|
7131
|
+
const templateContent = readFileSync29(resolve5(opts.from), "utf-8");
|
|
7112
7132
|
const { parseTemplate: parseTemplate2 } = await Promise.resolve().then(() => (init_template_importer(), template_importer_exports));
|
|
7113
7133
|
const template = parseTemplate2(templateContent);
|
|
7114
7134
|
info(`Importing from template: ${opts.from}`);
|
|
@@ -7252,6 +7272,11 @@ async function runInit(name, opts) {
|
|
|
7252
7272
|
task_backend: { adapter: backendAdapter }
|
|
7253
7273
|
};
|
|
7254
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
|
+
}
|
|
7255
7280
|
const secretReport = validateSecrets(config, process.env, {
|
|
7256
7281
|
deploy_target: deployTarget
|
|
7257
7282
|
});
|
|
@@ -7288,8 +7313,8 @@ async function runInit(name, opts) {
|
|
|
7288
7313
|
}
|
|
7289
7314
|
}
|
|
7290
7315
|
}
|
|
7291
|
-
let uiPassword = "";
|
|
7292
|
-
if (!opts.yes) {
|
|
7316
|
+
let uiPassword = opts.boardPassword || (opts.boardPasswordFile ? readSecretFile(opts.boardPasswordFile) : "") || "";
|
|
7317
|
+
if (!uiPassword && !opts.yes) {
|
|
7293
7318
|
const answer = await inquirer.prompt([
|
|
7294
7319
|
{
|
|
7295
7320
|
type: "password",
|
|
@@ -7304,6 +7329,8 @@ async function runInit(name, opts) {
|
|
|
7304
7329
|
} else {
|
|
7305
7330
|
info("No board password \u2014 UI will be open (fine for local dev)");
|
|
7306
7331
|
}
|
|
7332
|
+
} else if (uiPassword) {
|
|
7333
|
+
success("Board UI password set");
|
|
7307
7334
|
}
|
|
7308
7335
|
step(5, totalSteps, "Boot");
|
|
7309
7336
|
const projectName = basename4(projectPath);
|
|
@@ -7356,7 +7383,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7356
7383
|
const factoryName = name || ".";
|
|
7357
7384
|
const targetDir = resolve5(factoryName === "." ? "." : factoryName);
|
|
7358
7385
|
step(1, totalSteps, "Credentials");
|
|
7359
|
-
let githubToken = opts.githubToken || process.env.GITHUB_TOKEN || "";
|
|
7386
|
+
let githubToken = opts.githubToken || (opts.githubTokenFile ? readSecretFile(opts.githubTokenFile) : "") || process.env.GITHUB_TOKEN || "";
|
|
7360
7387
|
if (!githubToken && !opts.yes) {
|
|
7361
7388
|
const answer = await inquirer.prompt([
|
|
7362
7389
|
{
|
|
@@ -7373,7 +7400,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7373
7400
|
} else {
|
|
7374
7401
|
warn("GITHUB_TOKEN not set \u2014 add to .env later");
|
|
7375
7402
|
}
|
|
7376
|
-
let uiPassword = opts.boardPassword || "";
|
|
7403
|
+
let uiPassword = opts.boardPassword || (opts.boardPasswordFile ? readSecretFile(opts.boardPasswordFile) : "") || "";
|
|
7377
7404
|
if (!uiPassword && !opts.yes) {
|
|
7378
7405
|
const { password } = await inquirer.prompt([
|
|
7379
7406
|
{
|
|
@@ -7481,7 +7508,7 @@ async function runImageModeInit(name, opts) {
|
|
|
7481
7508
|
// src/cli/commands/export-config.ts
|
|
7482
7509
|
init_export_adapter();
|
|
7483
7510
|
import { Command as Command2 } from "commander";
|
|
7484
|
-
import { readFileSync as
|
|
7511
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync14, existsSync as existsSync18, readdirSync as readdirSync7 } from "fs";
|
|
7485
7512
|
import { resolve as resolve6, join as join16 } from "path";
|
|
7486
7513
|
function exportFactory(factoryDir, outputPath) {
|
|
7487
7514
|
const bmDir = join16(factoryDir, ".beastmode");
|
|
@@ -7489,12 +7516,12 @@ function exportFactory(factoryDir, outputPath) {
|
|
|
7489
7516
|
if (!existsSync18(configPath)) {
|
|
7490
7517
|
throw new Error(`No factory found at ${factoryDir}`);
|
|
7491
7518
|
}
|
|
7492
|
-
const config = JSON.parse(
|
|
7493
|
-
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"));
|
|
7494
7521
|
let plugins = [];
|
|
7495
7522
|
const lockPath = join16(bmDir, "extensions.lock");
|
|
7496
7523
|
if (existsSync18(lockPath)) {
|
|
7497
|
-
const lock = JSON.parse(
|
|
7524
|
+
const lock = JSON.parse(readFileSync15(lockPath, "utf-8"));
|
|
7498
7525
|
plugins = Object.keys(lock.plugins || {});
|
|
7499
7526
|
}
|
|
7500
7527
|
const template = {
|
|
@@ -7530,14 +7557,14 @@ function createArtifactExportCommand(artifact) {
|
|
|
7530
7557
|
throw new Error(`No scenarios directory found in run ${opts.run}`);
|
|
7531
7558
|
}
|
|
7532
7559
|
const files = readdirSync7(scenariosDir).filter((f) => f.endsWith(".md")).sort();
|
|
7533
|
-
sourceContent = files.map((f) =>
|
|
7560
|
+
sourceContent = files.map((f) => readFileSync15(join16(scenariosDir, f), "utf-8")).join("\n\n---\n\n");
|
|
7534
7561
|
} else {
|
|
7535
7562
|
const artifactFile = artifact === "nlspec" ? "nlspec.md" : "plan.md";
|
|
7536
7563
|
const artifactPath = join16(runDir, artifactFile);
|
|
7537
7564
|
if (!existsSync18(artifactPath)) {
|
|
7538
7565
|
throw new Error(`${artifactFile} not found in run ${opts.run}`);
|
|
7539
7566
|
}
|
|
7540
|
-
sourceContent =
|
|
7567
|
+
sourceContent = readFileSync15(artifactPath, "utf-8");
|
|
7541
7568
|
}
|
|
7542
7569
|
const result = runExportAdapter(opts.adapter, sourceContent);
|
|
7543
7570
|
if (opts.output) {
|
|
@@ -7761,7 +7788,7 @@ init_skill_manager();
|
|
|
7761
7788
|
init_presets();
|
|
7762
7789
|
import { Command as Command6 } from "commander";
|
|
7763
7790
|
import { resolve as resolve10 } from "path";
|
|
7764
|
-
import { readFileSync as
|
|
7791
|
+
import { readFileSync as readFileSync16, existsSync as existsSync19 } from "fs";
|
|
7765
7792
|
import { join as join17 } from "path";
|
|
7766
7793
|
function listPluginsAction(factoryDir) {
|
|
7767
7794
|
const lockPath = join17(factoryDir, ".beastmode", "extensions.lock");
|
|
@@ -7769,7 +7796,7 @@ function listPluginsAction(factoryDir) {
|
|
|
7769
7796
|
console.log(" No plugins installed (extensions.lock not found).");
|
|
7770
7797
|
return;
|
|
7771
7798
|
}
|
|
7772
|
-
const lock = JSON.parse(
|
|
7799
|
+
const lock = JSON.parse(readFileSync16(lockPath, "utf-8"));
|
|
7773
7800
|
const plugins = lock.plugins || {};
|
|
7774
7801
|
const names = Object.keys(plugins);
|
|
7775
7802
|
if (names.length === 0) {
|
|
@@ -7867,7 +7894,7 @@ var listCommand = new Command6("list").description("List installed extensions an
|
|
|
7867
7894
|
// src/cli/commands/import-cmd.ts
|
|
7868
7895
|
init_import_adapter();
|
|
7869
7896
|
import { Command as Command7 } from "commander";
|
|
7870
|
-
import { readFileSync as
|
|
7897
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync15, mkdirSync as mkdirSync13, existsSync as existsSync20 } from "fs";
|
|
7871
7898
|
import { resolve as resolve11, join as join18 } from "path";
|
|
7872
7899
|
var VALID_ARTIFACTS = ["nlspec", "plan", "scenarios"];
|
|
7873
7900
|
function createArtifactCommand(artifact) {
|
|
@@ -7877,7 +7904,7 @@ function createArtifactCommand(artifact) {
|
|
|
7877
7904
|
if (!existsSync20(sourcePath)) {
|
|
7878
7905
|
throw new Error(`Source file not found: ${sourcePath}`);
|
|
7879
7906
|
}
|
|
7880
|
-
const sourceContent =
|
|
7907
|
+
const sourceContent = readFileSync17(sourcePath, "utf-8");
|
|
7881
7908
|
const result = runImportAdapter(opts.adapter, sourceContent);
|
|
7882
7909
|
if (opts.output) {
|
|
7883
7910
|
const outputPath = resolve11(opts.output);
|
|
@@ -7913,7 +7940,7 @@ for (const artifact of VALID_ARTIFACTS) {
|
|
|
7913
7940
|
init_status_checker();
|
|
7914
7941
|
init_schemas();
|
|
7915
7942
|
import { Command as Command8 } from "commander";
|
|
7916
|
-
import { existsSync as existsSync21, readFileSync as
|
|
7943
|
+
import { existsSync as existsSync21, readFileSync as readFileSync18, readdirSync as readdirSync8 } from "fs";
|
|
7917
7944
|
import { execSync as execSync4 } from "child_process";
|
|
7918
7945
|
import { join as join19, resolve as resolve12 } from "path";
|
|
7919
7946
|
function statusAction(factoryDir, opts) {
|
|
@@ -7922,7 +7949,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7922
7949
|
throw new Error(`No factory found at ${factoryDir}`);
|
|
7923
7950
|
}
|
|
7924
7951
|
const factoryJsonPath = join19(bmDir, "factory.json");
|
|
7925
|
-
const rawIdentity = JSON.parse(
|
|
7952
|
+
const rawIdentity = JSON.parse(readFileSync18(factoryJsonPath, "utf-8"));
|
|
7926
7953
|
const factoryIdentity = FactoryIdentitySchema.parse(rawIdentity);
|
|
7927
7954
|
const projectsDir = join19(bmDir, "projects");
|
|
7928
7955
|
const projectCount = existsSync21(projectsDir) ? readdirSync8(projectsDir).filter((f) => f.endsWith(".json")).length : 0;
|
|
@@ -7932,7 +7959,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7932
7959
|
let mcpServers = {};
|
|
7933
7960
|
if (existsSync21(mcpPath)) {
|
|
7934
7961
|
try {
|
|
7935
|
-
const raw = JSON.parse(
|
|
7962
|
+
const raw = JSON.parse(readFileSync18(mcpPath, "utf-8"));
|
|
7936
7963
|
mcpServers = raw.servers || {};
|
|
7937
7964
|
} catch {
|
|
7938
7965
|
}
|
|
@@ -7941,7 +7968,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7941
7968
|
let hooks = {};
|
|
7942
7969
|
if (existsSync21(hooksPath)) {
|
|
7943
7970
|
try {
|
|
7944
|
-
const raw = JSON.parse(
|
|
7971
|
+
const raw = JSON.parse(readFileSync18(hooksPath, "utf-8"));
|
|
7945
7972
|
hooks = raw.hooks || {};
|
|
7946
7973
|
} catch {
|
|
7947
7974
|
}
|
|
@@ -7958,7 +7985,7 @@ function statusAction(factoryDir, opts) {
|
|
|
7958
7985
|
let pidAlive = false;
|
|
7959
7986
|
if (existsSync21(pidPath)) {
|
|
7960
7987
|
try {
|
|
7961
|
-
daemonPid = parseInt(
|
|
7988
|
+
daemonPid = parseInt(readFileSync18(pidPath, "utf-8").trim(), 10);
|
|
7962
7989
|
process.kill(daemonPid, 0);
|
|
7963
7990
|
pidAlive = true;
|
|
7964
7991
|
} catch {
|
|
@@ -8031,7 +8058,7 @@ var statusCommand = new Command8("status").description("Show factory status over
|
|
|
8031
8058
|
// src/cli/commands/config-cmd.ts
|
|
8032
8059
|
init_config_manager();
|
|
8033
8060
|
import { Command as Command9 } from "commander";
|
|
8034
|
-
import { existsSync as existsSync22, readFileSync as
|
|
8061
|
+
import { existsSync as existsSync22, readFileSync as readFileSync19, writeFileSync as writeFileSync16 } from "fs";
|
|
8035
8062
|
import { join as join20, resolve as resolve13 } from "path";
|
|
8036
8063
|
import { execSync as execSync5 } from "child_process";
|
|
8037
8064
|
function readConfig2(factoryDir) {
|
|
@@ -8039,7 +8066,7 @@ function readConfig2(factoryDir) {
|
|
|
8039
8066
|
if (!existsSync22(configPath)) {
|
|
8040
8067
|
throw new Error("No config.json found. Run beastmode init first.");
|
|
8041
8068
|
}
|
|
8042
|
-
return JSON.parse(
|
|
8069
|
+
return JSON.parse(readFileSync19(configPath, "utf-8"));
|
|
8043
8070
|
}
|
|
8044
8071
|
function writeConfig2(factoryDir, config) {
|
|
8045
8072
|
const configPath = join20(factoryDir, ".beastmode", "config.json");
|
|
@@ -8121,7 +8148,7 @@ init_schemas();
|
|
|
8121
8148
|
init_version();
|
|
8122
8149
|
init_plugin_resolver();
|
|
8123
8150
|
import { Command as Command11 } from "commander";
|
|
8124
|
-
import { existsSync as existsSync24, readFileSync as
|
|
8151
|
+
import { existsSync as existsSync24, readFileSync as readFileSync21, readdirSync as readdirSync9 } from "fs";
|
|
8125
8152
|
import { join as join22, resolve as resolve15 } from "path";
|
|
8126
8153
|
import { execSync as execSync6 } from "child_process";
|
|
8127
8154
|
import { homedir as homedir2, platform } from "os";
|
|
@@ -8131,7 +8158,7 @@ import * as https from "https";
|
|
|
8131
8158
|
// src/cli/commands/board.ts
|
|
8132
8159
|
import { Command as Command10 } from "commander";
|
|
8133
8160
|
import { resolve as resolve14, join as join21 } from "path";
|
|
8134
|
-
import { existsSync as existsSync23, readFileSync as
|
|
8161
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20, mkdirSync as mkdirSync14, writeFileSync as writeFileSync17 } from "fs";
|
|
8135
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) => {
|
|
8136
8163
|
try {
|
|
8137
8164
|
await runBoard(opts);
|
|
@@ -8175,7 +8202,7 @@ async function runBoard(opts) {
|
|
|
8175
8202
|
}
|
|
8176
8203
|
}
|
|
8177
8204
|
const factoryJsonPath = join21(factoryDir, ".beastmode", "factory.json");
|
|
8178
|
-
const factoryJson = JSON.parse(
|
|
8205
|
+
const factoryJson = JSON.parse(readFileSync20(factoryJsonPath, "utf-8"));
|
|
8179
8206
|
const factoryName = factoryJson.factory_name || "BeastMode Factory";
|
|
8180
8207
|
header(`BeastMode Board \u2014 ${factoryName}`);
|
|
8181
8208
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_server(), server_exports));
|
|
@@ -8413,7 +8440,7 @@ function checkProjectDirectory(factoryDir) {
|
|
|
8413
8440
|
let anyFail = false;
|
|
8414
8441
|
for (const file of projectFiles) {
|
|
8415
8442
|
try {
|
|
8416
|
-
const proj = JSON.parse(
|
|
8443
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8417
8444
|
const projPath = proj.path || "";
|
|
8418
8445
|
const projName = proj.name || file.replace(".json", "");
|
|
8419
8446
|
if (!projPath || !existsSync24(projPath)) {
|
|
@@ -8497,7 +8524,7 @@ function checkStack(factoryDir) {
|
|
|
8497
8524
|
const stacks = [];
|
|
8498
8525
|
for (const file of projectFiles) {
|
|
8499
8526
|
try {
|
|
8500
|
-
const proj = JSON.parse(
|
|
8527
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8501
8528
|
const name = proj.name || file.replace(".json", "");
|
|
8502
8529
|
const detected = proj.stack?.detected || "unknown";
|
|
8503
8530
|
const build = proj.stack?.build_command || "";
|
|
@@ -8546,7 +8573,7 @@ function checkBoardPassword(env, factoryDir) {
|
|
|
8546
8573
|
for (const filePath of [dotEnv, secretsEnv]) {
|
|
8547
8574
|
if (existsSync24(filePath)) {
|
|
8548
8575
|
try {
|
|
8549
|
-
const content =
|
|
8576
|
+
const content = readFileSync21(filePath, "utf-8");
|
|
8550
8577
|
const lines = content.split("\n");
|
|
8551
8578
|
const line = lines.find((l) => l.startsWith("BEASTMODE_UI_PASSWORD="));
|
|
8552
8579
|
if (line) {
|
|
@@ -8573,7 +8600,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8573
8600
|
let factoryIdentity = null;
|
|
8574
8601
|
if (factoryDirExists) {
|
|
8575
8602
|
try {
|
|
8576
|
-
const raw = JSON.parse(
|
|
8603
|
+
const raw = JSON.parse(readFileSync21(join22(bmDir, "factory.json"), "utf-8"));
|
|
8577
8604
|
factoryIdentity = FactoryIdentitySchema.parse(raw);
|
|
8578
8605
|
} catch {
|
|
8579
8606
|
}
|
|
@@ -8584,7 +8611,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8584
8611
|
const configPath = join22(bmDir, "config.json");
|
|
8585
8612
|
if (existsSync24(configPath)) {
|
|
8586
8613
|
try {
|
|
8587
|
-
const raw = JSON.parse(
|
|
8614
|
+
const raw = JSON.parse(readFileSync21(configPath, "utf-8"));
|
|
8588
8615
|
const result = FactoryConfigSchema.safeParse(raw);
|
|
8589
8616
|
if (result.success) {
|
|
8590
8617
|
config = raw;
|
|
@@ -8605,7 +8632,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8605
8632
|
for (const file of readdirSync9(projectsDir)) {
|
|
8606
8633
|
if (file.endsWith(".json")) {
|
|
8607
8634
|
try {
|
|
8608
|
-
const proj = JSON.parse(
|
|
8635
|
+
const proj = JSON.parse(readFileSync21(join22(projectsDir, file), "utf-8"));
|
|
8609
8636
|
if (proj.path) {
|
|
8610
8637
|
projectPaths.push({
|
|
8611
8638
|
name: proj.name || file.replace(".json", ""),
|
|
@@ -8627,7 +8654,7 @@ function doctorAction(factoryDir, env) {
|
|
|
8627
8654
|
const manifestPath = join22(pluginsDir, pluginName, "manifest.json");
|
|
8628
8655
|
if (existsSync24(manifestPath)) {
|
|
8629
8656
|
try {
|
|
8630
|
-
const manifest = JSON.parse(
|
|
8657
|
+
const manifest = JSON.parse(readFileSync21(manifestPath, "utf-8"));
|
|
8631
8658
|
installedPlugins.push({
|
|
8632
8659
|
name: pluginName,
|
|
8633
8660
|
engine_version: manifest.engine_version || "*"
|
|
@@ -8736,21 +8763,21 @@ init_upgrader();
|
|
|
8736
8763
|
init_schemas();
|
|
8737
8764
|
init_version();
|
|
8738
8765
|
import { Command as Command12 } from "commander";
|
|
8739
|
-
import { existsSync as existsSync25, readFileSync as
|
|
8766
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22, writeFileSync as writeFileSync18 } from "fs";
|
|
8740
8767
|
import { join as join23, resolve as resolve16 } from "path";
|
|
8741
8768
|
function readIdentity(factoryDir) {
|
|
8742
8769
|
const path = join23(factoryDir, ".beastmode", "factory.json");
|
|
8743
8770
|
if (!existsSync25(path)) {
|
|
8744
8771
|
throw new Error("No factory.json found. Run beastmode init first.");
|
|
8745
8772
|
}
|
|
8746
|
-
return FactoryIdentitySchema.parse(JSON.parse(
|
|
8773
|
+
return FactoryIdentitySchema.parse(JSON.parse(readFileSync22(path, "utf-8")));
|
|
8747
8774
|
}
|
|
8748
8775
|
function readConfig3(factoryDir) {
|
|
8749
8776
|
const path = join23(factoryDir, ".beastmode", "config.json");
|
|
8750
8777
|
if (!existsSync25(path)) {
|
|
8751
8778
|
return {};
|
|
8752
8779
|
}
|
|
8753
|
-
return JSON.parse(
|
|
8780
|
+
return JSON.parse(readFileSync22(path, "utf-8"));
|
|
8754
8781
|
}
|
|
8755
8782
|
function upgradeCheckAction(factoryDir) {
|
|
8756
8783
|
const identity = readIdentity(factoryDir);
|
|
@@ -8818,7 +8845,7 @@ var upgradeCommand = new Command12("upgrade").description("Upgrade engine versio
|
|
|
8818
8845
|
// src/cli/commands/migrate.ts
|
|
8819
8846
|
import { Command as Command13 } from "commander";
|
|
8820
8847
|
import { resolve as resolve17, join as join24 } from "path";
|
|
8821
|
-
import { existsSync as existsSync26, readFileSync as
|
|
8848
|
+
import { existsSync as existsSync26, readFileSync as readFileSync23, mkdirSync as mkdirSync15, writeFileSync as writeFileSync19 } from "fs";
|
|
8822
8849
|
init_migrator();
|
|
8823
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) => {
|
|
8824
8851
|
try {
|
|
@@ -8839,7 +8866,7 @@ async function runMigrate(opts) {
|
|
|
8839
8866
|
}
|
|
8840
8867
|
header("BeastMode Migrate");
|
|
8841
8868
|
info(`Reading daemon config from: ${configPath}`);
|
|
8842
|
-
const configContent =
|
|
8869
|
+
const configContent = readFileSync23(configPath, "utf-8");
|
|
8843
8870
|
const daemonConfig = parseDaemonConfig(configContent);
|
|
8844
8871
|
const runsDir = join24(cwd, "runs");
|
|
8845
8872
|
let runDirs = [];
|
|
@@ -8857,7 +8884,7 @@ async function runMigrate(opts) {
|
|
|
8857
8884
|
const cpPath = join24(runsDir, dir, "checkpoint.json");
|
|
8858
8885
|
if (existsSync26(cpPath)) {
|
|
8859
8886
|
try {
|
|
8860
|
-
const cp = JSON.parse(
|
|
8887
|
+
const cp = JSON.parse(readFileSync23(cpPath, "utf-8"));
|
|
8861
8888
|
checkpoints.set(dir, cp);
|
|
8862
8889
|
} catch {
|
|
8863
8890
|
}
|
|
@@ -8954,7 +8981,7 @@ async function runMigrate(opts) {
|
|
|
8954
8981
|
// src/cli/commands/run.ts
|
|
8955
8982
|
import { Command as Command14 } from "commander";
|
|
8956
8983
|
import { join as join25 } from "path";
|
|
8957
|
-
import { existsSync as existsSync27, readFileSync as
|
|
8984
|
+
import { existsSync as existsSync27, readFileSync as readFileSync24, writeFileSync as writeFileSync20, mkdirSync as mkdirSync16 } from "fs";
|
|
8958
8985
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
8959
8986
|
init_bridge();
|
|
8960
8987
|
init_schemas();
|
|
@@ -8983,7 +9010,7 @@ async function runPipeline(projectName, opts) {
|
|
|
8983
9010
|
throw new Error("Factory config not found. Run 'beastmode init' first.");
|
|
8984
9011
|
}
|
|
8985
9012
|
const factoryConfig = FactoryConfigSchema.parse(
|
|
8986
|
-
JSON.parse(
|
|
9013
|
+
JSON.parse(readFileSync24(configPath, "utf-8"))
|
|
8987
9014
|
);
|
|
8988
9015
|
let projectConfig = null;
|
|
8989
9016
|
const projectsDir = join25(bmDir, "projects");
|
|
@@ -9000,11 +9027,11 @@ async function runPipeline(projectName, opts) {
|
|
|
9000
9027
|
throw new Error(`Project not found: ${projectName}`);
|
|
9001
9028
|
}
|
|
9002
9029
|
projectConfig = ProjectConfigSchema.parse(
|
|
9003
|
-
JSON.parse(
|
|
9030
|
+
JSON.parse(readFileSync24(join25(projectsDir, file), "utf-8"))
|
|
9004
9031
|
);
|
|
9005
9032
|
} else if (projectFiles.length > 0) {
|
|
9006
9033
|
projectConfig = ProjectConfigSchema.parse(
|
|
9007
|
-
JSON.parse(
|
|
9034
|
+
JSON.parse(readFileSync24(join25(projectsDir, projectFiles[0]), "utf-8"))
|
|
9008
9035
|
);
|
|
9009
9036
|
info(`Using project: ${projectConfig.name}`);
|
|
9010
9037
|
}
|
|
@@ -9013,7 +9040,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9013
9040
|
let boardItems = [];
|
|
9014
9041
|
if (existsSync27(boardPath)) {
|
|
9015
9042
|
try {
|
|
9016
|
-
const raw = JSON.parse(
|
|
9043
|
+
const raw = JSON.parse(readFileSync24(boardPath, "utf-8"));
|
|
9017
9044
|
boardItems = Array.isArray(raw.items) ? raw.items : [];
|
|
9018
9045
|
} catch {
|
|
9019
9046
|
boardItems = [];
|
|
@@ -9087,7 +9114,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9087
9114
|
const startTime = Date.now();
|
|
9088
9115
|
const pollInterval = setInterval(() => {
|
|
9089
9116
|
try {
|
|
9090
|
-
const board = JSON.parse(
|
|
9117
|
+
const board = JSON.parse(readFileSync24(boardPath, "utf-8"));
|
|
9091
9118
|
const items = Array.isArray(board.items) ? board.items : [];
|
|
9092
9119
|
const taskItem = items.find((i) => i.id === taskId);
|
|
9093
9120
|
if (taskItem) {
|
|
@@ -9130,7 +9157,7 @@ async function runPipeline(projectName, opts) {
|
|
|
9130
9157
|
// src/cli/commands/daemon-cmd.ts
|
|
9131
9158
|
import { Command as Command15 } from "commander";
|
|
9132
9159
|
import { join as join26 } from "path";
|
|
9133
|
-
import { existsSync as existsSync28, readFileSync as
|
|
9160
|
+
import { existsSync as existsSync28, readFileSync as readFileSync25, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17 } from "fs";
|
|
9134
9161
|
init_bridge();
|
|
9135
9162
|
init_schemas();
|
|
9136
9163
|
var daemonCommand = new Command15("daemon").description("Start the BeastMode daemon via bridge").option("--dry-run", "Generate config but don't start daemon").option(
|
|
@@ -9159,7 +9186,7 @@ async function runDaemon(opts) {
|
|
|
9159
9186
|
throw new Error("Factory config not found. Run 'beastmode init' first.");
|
|
9160
9187
|
}
|
|
9161
9188
|
const factoryConfig = FactoryConfigSchema.parse(
|
|
9162
|
-
JSON.parse(
|
|
9189
|
+
JSON.parse(readFileSync25(configPath, "utf-8"))
|
|
9163
9190
|
);
|
|
9164
9191
|
let projectConfig = null;
|
|
9165
9192
|
const projectsDir = join26(bmDir, "projects");
|
|
@@ -9170,7 +9197,7 @@ async function runDaemon(opts) {
|
|
|
9170
9197
|
);
|
|
9171
9198
|
if (projectFiles.length > 0) {
|
|
9172
9199
|
projectConfig = ProjectConfigSchema.parse(
|
|
9173
|
-
JSON.parse(
|
|
9200
|
+
JSON.parse(readFileSync25(join26(projectsDir, projectFiles[0]), "utf-8"))
|
|
9174
9201
|
);
|
|
9175
9202
|
info(`Using project: ${projectConfig.name}`);
|
|
9176
9203
|
}
|
|
@@ -9272,7 +9299,7 @@ var mcpCommand = new Command16("mcp").description("Start the BeastMode MCP serve
|
|
|
9272
9299
|
// src/cli/commands/deploy.ts
|
|
9273
9300
|
import { Command as Command17 } from "commander";
|
|
9274
9301
|
import { resolve as resolve19, join as join28 } from "path";
|
|
9275
|
-
import { existsSync as existsSync30, writeFileSync as writeFileSync23, readFileSync as
|
|
9302
|
+
import { existsSync as existsSync30, writeFileSync as writeFileSync23, readFileSync as readFileSync27 } from "fs";
|
|
9276
9303
|
import { execSync as execSync7 } from "child_process";
|
|
9277
9304
|
import { randomBytes } from "crypto";
|
|
9278
9305
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -9362,8 +9389,8 @@ async function runDeploy(opts) {
|
|
|
9362
9389
|
const host = opts.host;
|
|
9363
9390
|
const dotEnv = join28(factoryDir, ".env");
|
|
9364
9391
|
const secretsEnv = join28(bmDir, "secrets.env.local");
|
|
9365
|
-
const envContent = existsSync30(dotEnv) ?
|
|
9366
|
-
const secretsContent = existsSync30(secretsEnv) ?
|
|
9392
|
+
const envContent = existsSync30(dotEnv) ? readFileSync27(dotEnv, "utf-8") : "";
|
|
9393
|
+
const secretsContent = existsSync30(secretsEnv) ? readFileSync27(secretsEnv, "utf-8") : "";
|
|
9367
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;
|
|
9368
9395
|
if (!hasPassword && opts.host === "0.0.0.0") {
|
|
9369
9396
|
const generated = randomBytes(18).toString("base64url");
|
|
@@ -9372,7 +9399,7 @@ async function runDeploy(opts) {
|
|
|
9372
9399
|
# Auto-generated board UI password (deploy)
|
|
9373
9400
|
BEASTMODE_UI_PASSWORD=${generated}
|
|
9374
9401
|
`;
|
|
9375
|
-
writeFileSync23(target, (existsSync30(target) ?
|
|
9402
|
+
writeFileSync23(target, (existsSync30(target) ? readFileSync27(target, "utf-8") : "") + append, "utf-8");
|
|
9376
9403
|
info(`Board UI password auto-generated and saved to ${target}`);
|
|
9377
9404
|
success(`Password: ${generated}`);
|
|
9378
9405
|
info("Save this password \u2014 you'll need it to access the board UI.");
|
|
@@ -9990,12 +10017,12 @@ var logsCommand = new Command21("logs").description("Stream BeastMode service lo
|
|
|
9990
10017
|
|
|
9991
10018
|
// src/cli/commands/update.ts
|
|
9992
10019
|
import { Command as Command22 } from "commander";
|
|
9993
|
-
import { readFileSync as
|
|
10020
|
+
import { readFileSync as readFileSync28, writeFileSync as writeFileSync25 } from "fs";
|
|
9994
10021
|
async function runUpdate(opts) {
|
|
9995
10022
|
const cwd = opts.cwd ?? process.cwd();
|
|
9996
10023
|
const composePath = requireComposeFile(cwd);
|
|
9997
10024
|
if (opts.tag) {
|
|
9998
|
-
let content =
|
|
10025
|
+
let content = readFileSync28(composePath, "utf-8");
|
|
9999
10026
|
const tagPattern = new RegExp(
|
|
10000
10027
|
`(${GHCR_IMAGE_PREFIX.replace(/[/]/g, "\\/")}\\/(?:board|daemon|ui)):([\\w.\\-]+)`,
|
|
10001
10028
|
"g"
|