@beastmode-develeap/beastmode 0.1.326 → 0.1.328

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
@@ -5256,7 +5256,7 @@ var init_chat_handler = __esm({
5256
5256
  });
5257
5257
 
5258
5258
  // src/cli/ui/board-api-routes.ts
5259
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync16, readdirSync as readdirSync8, unlinkSync as unlinkSync4, mkdirSync as mkdirSync12, statSync as statSync6, renameSync as renameSync3 } from "fs";
5259
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync13, existsSync as existsSync16, readdirSync as readdirSync8, unlinkSync as unlinkSync4, mkdirSync as mkdirSync12, statSync as statSync6 } from "fs";
5260
5260
  import { join as join14, basename as basename5, resolve as resolve4, dirname as dirname5, sep } from "path";
5261
5261
  import { homedir } from "os";
5262
5262
  import { randomUUID as randomUUID2 } from "crypto";
@@ -5672,13 +5672,14 @@ function getBoardRoutes(factoryDir) {
5672
5672
  pattern: "/api/status",
5673
5673
  handler: async () => {
5674
5674
  const bmDir = join14(factoryDir, ".beastmode");
5675
- const factoryJsonPath = join14(bmDir, "factory.json");
5676
- if (!existsSync16(factoryJsonPath)) {
5677
- throw new Error("Not a valid factory: factory.json not found");
5678
- }
5679
- const factoryIdentity = JSON.parse(readFileSync13(factoryJsonPath, "utf-8"));
5680
- const projectsDir = join14(bmDir, "projects");
5681
- const projectCount = listProjectRecords(projectsDir).length;
5675
+ const boardUrl = getBoardUrl2(factoryDir);
5676
+ const factoryIdentity = await proxyToBoard(
5677
+ boardUrl,
5678
+ "GET",
5679
+ "/api/factory"
5680
+ );
5681
+ const projectsResp = await proxyToBoard(boardUrl, "GET", "/api/projects");
5682
+ const projectCount = (projectsResp.projects || []).length;
5682
5683
  const lockPath = join14(bmDir, "extensions.lock");
5683
5684
  let pluginNames = [];
5684
5685
  if (existsSync16(lockPath)) {
@@ -6263,9 +6264,10 @@ function getBoardRoutes(factoryDir) {
6263
6264
  {
6264
6265
  method: "GET",
6265
6266
  pattern: "/api/doctor",
6266
- handler: () => {
6267
- const projectsDir = join14(factoryDir, ".beastmode", "projects");
6268
- const projects = listProjectRecords(projectsDir);
6267
+ handler: async () => {
6268
+ const boardUrl = getBoardUrl2(factoryDir);
6269
+ const resp = await proxyToBoard(boardUrl, "GET", "/api/projects");
6270
+ const projects = resp.projects || [];
6269
6271
  const checks = [];
6270
6272
  for (const p of projects) {
6271
6273
  const hasStack = !!(p.stack && p.stack.detected);
@@ -6288,12 +6290,16 @@ function getBoardRoutes(factoryDir) {
6288
6290
  }
6289
6291
  },
6290
6292
  // ── Projects ──
6293
+ // #894: the project registry is now the board DB, not the filesystem.
6294
+ // These routes proxy to the board's /api/projects + /api/factory
6295
+ // endpoints so a dropped/renamed ./.beastmode mount can no longer wipe
6296
+ // the operator's projects.
6291
6297
  {
6292
6298
  method: "GET",
6293
6299
  pattern: "/api/projects",
6294
6300
  handler: () => {
6295
- const projectsDir = join14(factoryDir, ".beastmode", "projects");
6296
- return { projects: listProjectRecords(projectsDir) };
6301
+ const boardUrl = getBoardUrl2(factoryDir);
6302
+ return proxyToBoard(boardUrl, "GET", "/api/projects");
6297
6303
  }
6298
6304
  },
6299
6305
  {
@@ -6302,9 +6308,8 @@ function getBoardRoutes(factoryDir) {
6302
6308
  handler: (_body, params) => {
6303
6309
  const { name } = params;
6304
6310
  assertSafeName(name);
6305
- const record = readProjectRecord(join14(factoryDir, ".beastmode", "projects"), name);
6306
- if (!record) throw new Error(`Project not found: ${name}`);
6307
- return record;
6311
+ const boardUrl = getBoardUrl2(factoryDir);
6312
+ return proxyToBoard(boardUrl, "GET", `/api/projects/${encodeURIComponent(name)}`);
6308
6313
  }
6309
6314
  },
6310
6315
  {
@@ -6313,15 +6318,12 @@ function getBoardRoutes(factoryDir) {
6313
6318
  handler: (_body, params) => {
6314
6319
  const { name } = params;
6315
6320
  assertSafeName(name);
6316
- const extPath = join14(factoryDir, ".beastmode", "projects", name, "extensions.json");
6317
- if (!existsSync16(extPath)) {
6318
- return { plugins: { add: [], remove: [] }, mcps: { add: {}, remove: [] }, skills: { add: [], remove: [] } };
6319
- }
6320
- try {
6321
- return JSON.parse(readFileSync13(extPath, "utf-8"));
6322
- } catch {
6323
- return { plugins: { add: [], remove: [] }, mcps: { add: {}, remove: [] }, skills: { add: [], remove: [] } };
6324
- }
6321
+ const boardUrl = getBoardUrl2(factoryDir);
6322
+ return proxyToBoard(
6323
+ boardUrl,
6324
+ "GET",
6325
+ `/api/projects/${encodeURIComponent(name)}/extensions`
6326
+ );
6325
6327
  }
6326
6328
  },
6327
6329
  {
@@ -6374,10 +6376,9 @@ function getBoardRoutes(factoryDir) {
6374
6376
  {
6375
6377
  method: "POST",
6376
6378
  pattern: "/api/projects",
6377
- handler: (body) => {
6379
+ handler: async (body) => {
6378
6380
  const { path: projectPath, github_url, clone_target } = body;
6379
- const projectsDir = join14(factoryDir, ".beastmode", "projects");
6380
- if (!existsSync16(projectsDir)) mkdirSync12(projectsDir, { recursive: true });
6381
+ const boardUrl = getBoardUrl2(factoryDir);
6381
6382
  let resolvedPath;
6382
6383
  if (github_url) {
6383
6384
  const url = github_url.trim();
@@ -6437,12 +6438,14 @@ function getBoardRoutes(factoryDir) {
6437
6438
  throw new Error("Missing required field: provide either `path` (local) or `github_url` (clone)");
6438
6439
  }
6439
6440
  const projectName = basename5(resolvedPath);
6440
- if (existsSync16(join14(projectsDir, projectName, "project.json"))) {
6441
+ const existingResp = await proxyToBoard(boardUrl, "GET", "/api/projects");
6442
+ const existingProjects = existingResp.projects || [];
6443
+ if (existingProjects.some((p) => p.name === projectName)) {
6441
6444
  throw new HttpError(409, { error: `Project already exists: ${projectName}` });
6442
6445
  }
6443
6446
  const stack = detectStack(resolvedPath);
6444
6447
  let verifyPort = 3001;
6445
- for (const existing of listProjectRecords(projectsDir)) {
6448
+ for (const existing of existingProjects) {
6446
6449
  const port = existing.deploy?.verify_port;
6447
6450
  if (typeof port === "number" && port >= verifyPort) verifyPort = port + 1;
6448
6451
  }
@@ -6466,11 +6469,8 @@ function getBoardRoutes(factoryDir) {
6466
6469
  ...stack.packages ? { packages: stack.packages } : {}
6467
6470
  }
6468
6471
  });
6469
- writeProjectRecord(projectsDir, projectName, record);
6470
- const infraDir = join14(projectsDir, projectName, "infra");
6471
- mkdirSync12(join14(infraDir, "terraform"), { recursive: true });
6472
- mkdirSync12(join14(infraDir, "ci"), { recursive: true });
6473
- return record;
6472
+ const stored = await proxyToBoard(boardUrl, "POST", "/api/projects", record);
6473
+ return stored;
6474
6474
  }
6475
6475
  },
6476
6476
  {
@@ -6479,22 +6479,8 @@ function getBoardRoutes(factoryDir) {
6479
6479
  handler: (_body, params) => {
6480
6480
  const { name } = params;
6481
6481
  assertSafeName(name);
6482
- const projectsDir = join14(factoryDir, ".beastmode", "projects");
6483
- const subDir = join14(projectsDir, name);
6484
- const flatPath = join14(projectsDir, `${name}.json`);
6485
- const hasSubDir = existsSync16(join14(subDir, "project.json"));
6486
- const hasFlat = existsSync16(flatPath);
6487
- if (!hasSubDir && !hasFlat) throw new Error(`Project not found: ${name}`);
6488
- const archivedBase = join14(projectsDir, ".archived");
6489
- mkdirSync12(archivedBase, { recursive: true });
6490
- const uniq = (dest) => existsSync16(dest) ? `${dest}-${Date.now()}` : dest;
6491
- if (hasSubDir || existsSync16(subDir)) {
6492
- renameSync3(subDir, uniq(join14(archivedBase, name)));
6493
- }
6494
- if (hasFlat) {
6495
- renameSync3(flatPath, uniq(join14(archivedBase, `${name}.json`)));
6496
- }
6497
- return { success: true };
6482
+ const boardUrl = getBoardUrl2(factoryDir);
6483
+ return proxyToBoard(boardUrl, "DELETE", `/api/projects/${encodeURIComponent(name)}`);
6498
6484
  }
6499
6485
  },
6500
6486
  {
@@ -14888,7 +14874,7 @@ runnerCommand.command("build-image").description(
14888
14874
  // src/cli/commands/project-cmd.ts
14889
14875
  init_engine();
14890
14876
  import { Command as Command24 } from "commander";
14891
- import { existsSync as existsSync39, mkdirSync as mkdirSync24, readFileSync as readFileSync35, renameSync as renameSync4 } from "fs";
14877
+ import { existsSync as existsSync39, mkdirSync as mkdirSync24, readFileSync as readFileSync35, renameSync as renameSync3 } from "fs";
14892
14878
  import { join as join38, resolve as resolve21, basename as basename9 } from "path";
14893
14879
  import { execSync as execSync13 } from "child_process";
14894
14880
  var DEFAULT_MAX_PROJECTS = 5;
@@ -15008,7 +14994,7 @@ function projectRemoveAction(factoryDir, name) {
15008
14994
  if (!existsSync39(projectDir)) throw new Error(`Project not found: ${name}`);
15009
14995
  const archivedBase = join38(factoryDir, ".beastmode", "projects", ".archived");
15010
14996
  mkdirSync24(archivedBase, { recursive: true });
15011
- renameSync4(projectDir, join38(archivedBase, name));
14997
+ renameSync3(projectDir, join38(archivedBase, name));
15012
14998
  }
15013
14999
  var projectCommand = new Command24("project").description("Manage projects in this factory");
15014
15000
  projectCommand.command("add <path>").description("Register a project").option("--name <name>", "Override project name").option("--board-id <id>", "Link to existing board ID").action((path, opts) => {