@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 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 readFileSync25, writeFileSync as writeFileSync22, existsSync as existsSync29, readdirSync as readdirSync10, mkdirSync as mkdirSync18 } from "fs";
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(readFileSync25(filePath, "utf-8"));
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(readFileSync25(join27(bmDir, "factory.json"), "utf-8"))
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(readFileSync25(lockPath, "utf-8"));
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(readFileSync25(pidFile, "utf-8").trim(), 10);
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(readFileSync25(filePath, "utf-8"));
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(readFileSync25(configPath, "utf-8")) : generateDefaults();
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(readFileSync25(configPath, "utf-8")) : generateDefaults();
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(readFileSync25(lockPath, "utf-8"));
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(readFileSync25(join27(projectsDir, f), "utf-8"));
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: readFileSync28 } = await import("fs");
7128
- const templateContent = readFileSync28(resolve5(opts.from), "utf-8");
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 readFileSync14, writeFileSync as writeFileSync14, existsSync as existsSync18, readdirSync as readdirSync7 } from "fs";
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(readFileSync14(configPath, "utf-8"));
7510
- const identity = JSON.parse(readFileSync14(join16(bmDir, "factory.json"), "utf-8"));
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(readFileSync14(lockPath, "utf-8"));
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) => readFileSync14(join16(scenariosDir, f), "utf-8")).join("\n\n---\n\n");
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 = readFileSync14(artifactPath, "utf-8");
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 readFileSync15, existsSync as existsSync19 } from "fs";
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(readFileSync15(lockPath, "utf-8"));
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 readFileSync16, writeFileSync as writeFileSync15, mkdirSync as mkdirSync13, existsSync as existsSync20 } from "fs";
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 = readFileSync16(sourcePath, "utf-8");
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 readFileSync17, readdirSync as readdirSync8 } from "fs";
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(readFileSync17(factoryJsonPath, "utf-8"));
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(readFileSync17(mcpPath, "utf-8"));
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(readFileSync17(hooksPath, "utf-8"));
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(readFileSync17(pidPath, "utf-8").trim(), 10);
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 readFileSync18, writeFileSync as writeFileSync16 } from "fs";
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(readFileSync18(configPath, "utf-8"));
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 readFileSync20, readdirSync as readdirSync9 } from "fs";
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 readFileSync19, mkdirSync as mkdirSync14, writeFileSync as writeFileSync17 } from "fs";
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(readFileSync19(factoryJsonPath, "utf-8"));
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(readFileSync20(join22(projectsDir, file), "utf-8"));
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(readFileSync20(join22(projectsDir, file), "utf-8"));
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 = readFileSync20(filePath, "utf-8");
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(readFileSync20(join22(bmDir, "factory.json"), "utf-8"));
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(readFileSync20(configPath, "utf-8"));
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(readFileSync20(join22(projectsDir, file), "utf-8"));
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(readFileSync20(manifestPath, "utf-8"));
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 readFileSync21, writeFileSync as writeFileSync18 } from "fs";
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(readFileSync21(path, "utf-8")));
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(readFileSync21(path, "utf-8"));
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 readFileSync22, mkdirSync as mkdirSync15, writeFileSync as writeFileSync19 } from "fs";
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 = readFileSync22(configPath, "utf-8");
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(readFileSync22(cpPath, "utf-8"));
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 readFileSync23, writeFileSync as writeFileSync20, mkdirSync as mkdirSync16 } from "fs";
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(readFileSync23(configPath, "utf-8"))
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(readFileSync23(join25(projectsDir, file), "utf-8"))
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(readFileSync23(join25(projectsDir, projectFiles[0]), "utf-8"))
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(readFileSync23(boardPath, "utf-8"));
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(readFileSync23(boardPath, "utf-8"));
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 readFileSync24, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17 } from "fs";
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(readFileSync24(configPath, "utf-8"))
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(readFileSync24(join26(projectsDir, projectFiles[0]), "utf-8"))
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 readFileSync26 } from "fs";
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) ? readFileSync26(dotEnv, "utf-8") : "";
9383
- const secretsContent = existsSync30(secretsEnv) ? readFileSync26(secretsEnv, "utf-8") : "";
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) ? readFileSync26(target, "utf-8") : "") + append, "utf-8");
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 readFileSync27, writeFileSync as writeFileSync25 } from "fs";
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 = readFileSync27(composePath, "utf-8");
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"