@rubytech/create-maxy-code 0.1.573 → 0.1.574

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.
Files changed (127) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/admins-write/__tests__/index.test.ts +97 -0
  3. package/payload/platform/lib/admins-write/dist/index.d.ts +12 -0
  4. package/payload/platform/lib/admins-write/dist/index.d.ts.map +1 -1
  5. package/payload/platform/lib/admins-write/dist/index.js +27 -5
  6. package/payload/platform/lib/admins-write/dist/index.js.map +1 -1
  7. package/payload/platform/lib/admins-write/src/index.ts +35 -5
  8. package/payload/platform/lib/admins-write/vitest.config.ts +14 -0
  9. package/payload/platform/lib/dispatch-read/dist/session.d.ts.map +1 -1
  10. package/payload/platform/lib/dispatch-read/dist/session.js +19 -4
  11. package/payload/platform/lib/dispatch-read/dist/session.js.map +1 -1
  12. package/payload/platform/lib/dispatch-read/src/__tests__/session.test.ts +91 -0
  13. package/payload/platform/lib/dispatch-read/src/session.ts +25 -6
  14. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  15. package/payload/platform/plugins/admin/PLUGIN.md +8 -3
  16. package/payload/platform/plugins/admin/hooks/__tests__/html-structure-gate.test.sh +264 -0
  17. package/payload/platform/plugins/admin/hooks/__tests__/quote-render-pdf-conformance.test.sh +122 -24
  18. package/payload/platform/plugins/admin/hooks/__tests__/specialist-dispatch-gate.test.sh +158 -0
  19. package/payload/platform/plugins/admin/hooks/html-structure-gate.sh +165 -0
  20. package/payload/platform/plugins/admin/hooks/quote-render-pdf-conformance.sh +111 -19
  21. package/payload/platform/plugins/admin/hooks/specialist-dispatch-gate.sh +159 -0
  22. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts +27 -0
  23. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.d.ts.map +1 -0
  24. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js +29 -0
  25. package/payload/platform/plugins/admin/mcp/dist/admin-bind-classify.js.map +1 -0
  26. package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts +11 -0
  27. package/payload/platform/plugins/admin/mcp/dist/binding-validate.d.ts.map +1 -0
  28. package/payload/platform/plugins/admin/mcp/dist/binding-validate.js +20 -0
  29. package/payload/platform/plugins/admin/mcp/dist/binding-validate.js.map +1 -0
  30. package/payload/platform/plugins/admin/mcp/dist/index.js +133 -1
  31. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  32. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +32 -2
  33. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +157 -46
  34. package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +8 -0
  35. package/payload/platform/plugins/docs/references/admin-ui.md +71 -31
  36. package/payload/platform/plugins/docs/references/channel-wake-and-prompt.md +38 -13
  37. package/payload/platform/plugins/docs/references/internals.md +6 -0
  38. package/payload/platform/plugins/docs/references/outlook-guide.md +31 -1
  39. package/payload/platform/plugins/docs/references/troubleshooting.md +10 -0
  40. package/payload/platform/plugins/outlook/PLUGIN.md +3 -1
  41. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts +2 -0
  42. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.d.ts.map +1 -0
  43. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js +177 -0
  44. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger-write-sites.test.js.map +1 -0
  45. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts +2 -0
  46. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.d.ts.map +1 -0
  47. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js +130 -0
  48. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-ledger.test.js.map +1 -0
  49. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts +2 -0
  50. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.d.ts.map +1 -0
  51. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js +162 -0
  52. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-reconcile.test.js.map +1 -0
  53. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts +2 -0
  54. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.d.ts.map +1 -0
  55. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js +168 -0
  56. package/payload/platform/plugins/outlook/mcp/dist/__tests__/draft-state-fields.test.js.map +1 -0
  57. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts +64 -0
  58. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.d.ts.map +1 -0
  59. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js +110 -0
  60. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-ledger.js.map +1 -0
  61. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts +119 -0
  62. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.d.ts.map +1 -0
  63. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js +0 -0
  64. package/payload/platform/plugins/outlook/mcp/dist/lib/draft-reconcile.js.map +1 -0
  65. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts +8 -0
  66. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.d.ts.map +1 -0
  67. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js +247 -0
  68. package/payload/platform/plugins/outlook/mcp/dist/scripts/draft-reconcile.js.map +1 -0
  69. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.d.ts.map +1 -1
  70. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js +10 -0
  71. package/payload/platform/plugins/outlook/mcp/dist/tools/draft-send.js.map +1 -1
  72. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.d.ts.map +1 -1
  73. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js +21 -0
  74. package/payload/platform/plugins/outlook/mcp/dist/tools/draft.js.map +1 -1
  75. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts +16 -0
  76. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.d.ts.map +1 -1
  77. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js +5 -1
  78. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-fetch-body.js.map +1 -1
  79. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts +4 -0
  80. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.d.ts.map +1 -1
  81. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js +2 -1
  82. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-list.js.map +1 -1
  83. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.d.ts.map +1 -1
  84. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js +24 -0
  85. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-reply.js.map +1 -1
  86. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.d.ts.map +1 -1
  87. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js +2 -1
  88. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-search.js.map +1 -1
  89. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.d.ts.map +1 -1
  90. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js +29 -0
  91. package/payload/platform/plugins/outlook/mcp/dist/tools/mail-send.js.map +1 -1
  92. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts +2 -0
  93. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.d.ts.map +1 -0
  94. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js +21 -0
  95. package/payload/platform/plugins/scheduling/mcp/dist/__tests__/draft-reconcile-throttle.test.js.map +1 -0
  96. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts +13 -0
  97. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.d.ts.map +1 -0
  98. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js +10 -0
  99. package/payload/platform/plugins/scheduling/mcp/dist/lib/draft-reconcile-throttle.js.map +1 -0
  100. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +54 -0
  101. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  102. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts +32 -0
  103. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.d.ts.map +1 -0
  104. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js +144 -0
  105. package/payload/platform/services/claude-session-manager/dist/authored-specialist-tools.js.map +1 -0
  106. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  107. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  108. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  109. package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts +44 -0
  110. package/payload/platform/services/claude-session-manager/dist/html-structure-census.d.ts.map +1 -0
  111. package/payload/platform/services/claude-session-manager/dist/html-structure-census.js +185 -0
  112. package/payload/platform/services/claude-session-manager/dist/html-structure-census.js.map +1 -0
  113. package/payload/platform/services/claude-session-manager/dist/index.js +125 -0
  114. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  115. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.d.ts.map +1 -1
  116. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js +7 -0
  117. package/payload/platform/services/claude-session-manager/dist/quote-delivery-reconcile.js.map +1 -1
  118. package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts +42 -0
  119. package/payload/platform/services/claude-session-manager/dist/quote-print-census.d.ts.map +1 -0
  120. package/payload/platform/services/claude-session-manager/dist/quote-print-census.js +254 -0
  121. package/payload/platform/services/claude-session-manager/dist/quote-print-census.js.map +1 -0
  122. package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts +92 -0
  123. package/payload/platform/services/claude-session-manager/dist/specialist-census.d.ts.map +1 -0
  124. package/payload/platform/services/claude-session-manager/dist/specialist-census.js +227 -0
  125. package/payload/platform/services/claude-session-manager/dist/specialist-census.js.map +1 -0
  126. package/payload/platform/templates/account-settings.json +8 -4
  127. package/payload/server/server.js +465 -361
@@ -2983,15 +2983,22 @@ var require_session = __commonJS({
2983
2983
  exports.withSession = withSession3;
2984
2984
  exports.__setDriverForTests = __setDriverForTests;
2985
2985
  var node_fs_1 = __require("fs");
2986
+ var node_path_1 = __require("path");
2986
2987
  var neo4j_driver_1 = __importDefault(__require("neo4j-driver"));
2987
2988
  var driver2 = null;
2988
2989
  function password2() {
2989
2990
  if (process.env.NEO4J_PASSWORD)
2990
2991
  return process.env.NEO4J_PASSWORD;
2991
- const file = process.env.NEO4J_PASSWORD_FILE;
2992
- if (file && (0, node_fs_1.existsSync)(file))
2993
- return (0, node_fs_1.readFileSync)(file, "utf-8").trim();
2994
- throw new Error("[dispatch-read] Neo4j password not found in NEO4J_PASSWORD or NEO4J_PASSWORD_FILE");
2992
+ const root = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT;
2993
+ if (!root) {
2994
+ throw new Error("[dispatch-read] neither MAXY_PLATFORM_ROOT nor PLATFORM_ROOT is set \u2014 cannot locate config/.neo4j-password");
2995
+ }
2996
+ const passwordFile = (0, node_path_1.resolve)(root, "config/.neo4j-password");
2997
+ try {
2998
+ return (0, node_fs_1.readFileSync)(passwordFile, "utf-8").trim();
2999
+ } catch (err) {
3000
+ throw new Error(`[dispatch-read] Neo4j password not found. Expected at ${passwordFile}, or in NEO4J_PASSWORD. Read failed: ${err instanceof Error ? err.message : String(err)}`);
3001
+ }
2995
3002
  }
2996
3003
  function getDriver2() {
2997
3004
  if (driver2)
@@ -5095,10 +5102,10 @@ var require_dist7 = __commonJS({
5095
5102
 
5096
5103
  // server/index.ts
5097
5104
  init_dist();
5098
- import { readFileSync as readFileSync55, existsSync as existsSync56, watchFile, readdirSync as readdirSync32, statSync as statSync30 } from "fs";
5105
+ import { readFileSync as readFileSync55, existsSync as existsSync55, watchFile, readdirSync as readdirSync32, statSync as statSync30 } from "fs";
5099
5106
  import { spawn as spawn3 } from "child_process";
5100
5107
  import { createHash as createHash8 } from "crypto";
5101
- import { resolve as resolve51, join as join63, basename as basename17 } from "path";
5108
+ import { resolve as resolve52, join as join63, basename as basename17 } from "path";
5102
5109
  import { homedir as homedir5 } from "os";
5103
5110
 
5104
5111
  // server/lib/route-cache-watchers.ts
@@ -6658,20 +6665,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
6658
6665
  // server/routes/health.ts
6659
6666
  init_claude_agent();
6660
6667
  function checkPort(port2, timeoutMs = 500) {
6661
- return new Promise((resolve52) => {
6668
+ return new Promise((resolve53) => {
6662
6669
  const socket = createConnection2(port2, "127.0.0.1");
6663
6670
  socket.setTimeout(timeoutMs);
6664
6671
  socket.once("connect", () => {
6665
6672
  socket.destroy();
6666
- resolve52(true);
6673
+ resolve53(true);
6667
6674
  });
6668
6675
  socket.once("error", () => {
6669
6676
  socket.destroy();
6670
- resolve52(false);
6677
+ resolve53(false);
6671
6678
  });
6672
6679
  socket.once("timeout", () => {
6673
6680
  socket.destroy();
6674
- resolve52(false);
6681
+ resolve53(false);
6675
6682
  });
6676
6683
  });
6677
6684
  }
@@ -7648,7 +7655,7 @@ async function defaultResolve(accountId) {
7648
7655
  return resolveSocket2(accountId);
7649
7656
  }
7650
7657
  async function fetchAvatar(accountId, jid, deps = {}) {
7651
- const resolve52 = deps.resolve;
7658
+ const resolve53 = deps.resolve;
7652
7659
  const httpGet = deps.httpGet ?? defaultHttpGet;
7653
7660
  const maxAgeMs = deps.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
7654
7661
  const cached3 = readAvatar(accountId, jid);
@@ -7658,7 +7665,7 @@ async function fetchAvatar(accountId, jid, deps = {}) {
7658
7665
  return "fresh";
7659
7666
  }
7660
7667
  console.log(`${TAG7} op=cache jid=${jid} hit=false ageMs=${ageMs2}`);
7661
- const res = resolve52 ? resolve52(accountId) : await defaultResolve(accountId);
7668
+ const res = resolve53 ? resolve53(accountId) : await defaultResolve(accountId);
7662
7669
  if (!res.ok) {
7663
7670
  console.log(`${TAG7} op=no-socket jid=${jid} account=${accountId.slice(0, 8)} reason=${res.reason}`);
7664
7671
  return "no-socket";
@@ -9149,8 +9156,8 @@ async function startLogin(opts) {
9149
9156
  await clearAuth(authDir);
9150
9157
  let resolveCode = null;
9151
9158
  let rejectCode = null;
9152
- const codePromise = new Promise((resolve52, reject) => {
9153
- resolveCode = resolve52;
9159
+ const codePromise = new Promise((resolve53, reject) => {
9160
+ resolveCode = resolve53;
9154
9161
  rejectCode = reject;
9155
9162
  });
9156
9163
  const codeTimer = setTimeout(
@@ -16891,16 +16898,27 @@ function writeAdminEntry(input) {
16891
16898
  }
16892
16899
  const rowsBefore = users.map((u) => id8(u.userId)).join(",");
16893
16900
  const existing = users.findIndex((u) => u.userId === input.userId);
16901
+ const pinRotated = existing !== -1 && users[existing].pin !== input.pin;
16902
+ const boundFields = [
16903
+ input.phone !== void 0 ? "phone" : null,
16904
+ input.telegram !== void 0 ? "telegram" : null
16905
+ ].filter(Boolean);
16894
16906
  if (existing === -1) {
16895
- users.push({ userId: input.userId, pin: input.pin });
16907
+ const row = { userId: input.userId, pin: input.pin };
16908
+ if (input.phone !== void 0) row.phone = input.phone;
16909
+ if (input.telegram !== void 0) row.telegram = input.telegram;
16910
+ users.push(row);
16896
16911
  } else {
16897
- users[existing] = { ...users[existing], pin: input.pin };
16912
+ const row = { ...users[existing], pin: input.pin };
16913
+ if (input.phone !== void 0) row.phone = input.phone;
16914
+ if (input.telegram !== void 0) row.telegram = input.telegram;
16915
+ users[existing] = row;
16898
16916
  }
16899
16917
  writeFileAtomic(input.usersFile, JSON.stringify(users, null, 2) + "\n", 384);
16900
16918
  result.usersJsonResult = "ok";
16901
16919
  appendUsersAuditLine(input.audit, {
16902
- action: existing === -1 ? "add" : "set-pin",
16903
- field: existing === -1 ? "row" : "pin",
16920
+ action: existing === -1 ? "add" : pinRotated ? "set-pin" : "set-binding",
16921
+ field: existing === -1 ? "row" : pinRotated ? "pin" : boundFields.join(","),
16904
16922
  rowsBefore,
16905
16923
  rowsAfter: users.map((u) => id8(u.userId)).join(",")
16906
16924
  });
@@ -17410,7 +17428,7 @@ var onboarding_default = app13;
17410
17428
 
17411
17429
  // server/routes/dispatch.ts
17412
17430
  init_dist();
17413
- import { resolve as resolve22 } from "path";
17431
+ import { resolve as resolve23 } from "path";
17414
17432
  import { randomUUID as randomUUID5 } from "crypto";
17415
17433
 
17416
17434
  // ../lib/dispatch-read/src/config.ts
@@ -17454,16 +17472,26 @@ function terminalVisitStatuses(cfg) {
17454
17472
  }
17455
17473
 
17456
17474
  // ../lib/dispatch-read/src/session.ts
17457
- import { existsSync as existsSync27, readFileSync as readFileSync32 } from "fs";
17475
+ import { readFileSync as readFileSync32 } from "fs";
17476
+ import { resolve as resolve22 } from "path";
17458
17477
  import neo4j from "neo4j-driver";
17459
17478
  var driver = null;
17460
17479
  function password() {
17461
17480
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
17462
- const file = process.env.NEO4J_PASSWORD_FILE;
17463
- if (file && existsSync27(file)) return readFileSync32(file, "utf-8").trim();
17464
- throw new Error(
17465
- "[dispatch-read] Neo4j password not found in NEO4J_PASSWORD or NEO4J_PASSWORD_FILE"
17466
- );
17481
+ const root = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT;
17482
+ if (!root) {
17483
+ throw new Error(
17484
+ "[dispatch-read] neither MAXY_PLATFORM_ROOT nor PLATFORM_ROOT is set \u2014 cannot locate config/.neo4j-password"
17485
+ );
17486
+ }
17487
+ const passwordFile = resolve22(root, "config/.neo4j-password");
17488
+ try {
17489
+ return readFileSync32(passwordFile, "utf-8").trim();
17490
+ } catch (err) {
17491
+ throw new Error(
17492
+ `[dispatch-read] Neo4j password not found. Expected at ${passwordFile}, or in NEO4J_PASSWORD. Read failed: ${err instanceof Error ? err.message : String(err)}`
17493
+ );
17494
+ }
17467
17495
  }
17468
17496
  function getDriver() {
17469
17497
  if (driver) return driver;
@@ -17903,7 +17931,7 @@ function accountFor(cacheKey) {
17903
17931
  if (!cacheKey) return null;
17904
17932
  const accountId = getAccountIdForSession(cacheKey);
17905
17933
  if (!accountId) return null;
17906
- return { accountId, accountDir: resolve22(ACCOUNTS_DIR, accountId) };
17934
+ return { accountId, accountDir: resolve23(ACCOUNTS_DIR, accountId) };
17907
17935
  }
17908
17936
  var app14 = new Hono();
17909
17937
  app14.use("*", requireAdminSession);
@@ -18727,7 +18755,7 @@ init_dist();
18727
18755
  init_paths();
18728
18756
  init_remote_auth();
18729
18757
  init_loop_registry();
18730
- import { appendFileSync as appendFileSync3, existsSync as existsSync28, renameSync as renameSync9, statSync as statSync19 } from "fs";
18758
+ import { appendFileSync as appendFileSync3, existsSync as existsSync27, renameSync as renameSync9, statSync as statSync19 } from "fs";
18731
18759
  import { join as join38 } from "path";
18732
18760
  var CLIENT_ERRORS_LOG = join38(LOG_DIR, "client-errors.log");
18733
18761
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
@@ -18786,7 +18814,7 @@ function stackHead(stack) {
18786
18814
  }
18787
18815
  function rotateIfNeeded() {
18788
18816
  try {
18789
- if (!existsSync28(CLIENT_ERRORS_LOG)) return;
18817
+ if (!existsSync27(CLIENT_ERRORS_LOG)) return;
18790
18818
  const stats = statSync19(CLIENT_ERRORS_LOG);
18791
18819
  if (stats.size < MAX_LOG_SIZE) return;
18792
18820
  renameSync9(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
@@ -19002,15 +19030,15 @@ function operatorRoleFor(config, userId) {
19002
19030
  async function buildAccountOptionList(accounts, userId) {
19003
19031
  const houseAccount = accounts.find((a) => a.config.role === "house");
19004
19032
  console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
19005
- const resolve52 = async (a) => {
19033
+ const resolve53 = async (a) => {
19006
19034
  const businessName = await fetchAccountName(a.accountId) || void 0;
19007
19035
  return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
19008
19036
  };
19009
19037
  const houseOptions = await Promise.all(
19010
- accounts.filter((a) => a.config.role === "house").map(resolve52)
19038
+ accounts.filter((a) => a.config.role === "house").map(resolve53)
19011
19039
  );
19012
19040
  const nonHouseOptions = await Promise.all(
19013
- accounts.filter((a) => a.config.role !== "house").map(resolve52)
19041
+ accounts.filter((a) => a.config.role !== "house").map(resolve53)
19014
19042
  );
19015
19043
  const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
19016
19044
  nonHouseOptions.sort((x, y) => {
@@ -19152,18 +19180,18 @@ var accounts_default = app18;
19152
19180
  init_dist();
19153
19181
  init_paths();
19154
19182
  init_claude_agent();
19155
- import { existsSync as existsSync30, readdirSync as readdirSync20, readFileSync as readFileSync33, statSync as statSync20 } from "fs";
19156
- import { resolve as resolve23, basename as basename11 } from "path";
19183
+ import { existsSync as existsSync29, readdirSync as readdirSync20, readFileSync as readFileSync33, statSync as statSync20 } from "fs";
19184
+ import { resolve as resolve24, basename as basename11 } from "path";
19157
19185
 
19158
19186
  // app/lib/logs-read-resolve.ts
19159
- import { existsSync as existsSync29 } from "fs";
19187
+ import { existsSync as existsSync28 } from "fs";
19160
19188
  import { join as join39 } from "path";
19161
19189
  function resolveSessionLogPaths(filename, logDirs) {
19162
19190
  const tried = [filename];
19163
19191
  const hits = [];
19164
19192
  for (const dir of logDirs) {
19165
19193
  const fullPath = join39(dir, filename);
19166
- if (existsSync29(fullPath)) {
19194
+ if (existsSync28(fullPath)) {
19167
19195
  hits.push({ path: fullPath, dir });
19168
19196
  }
19169
19197
  }
@@ -19181,13 +19209,13 @@ app19.get("/", async (c) => {
19181
19209
  const sessionIdParam = c.req.query("sessionId");
19182
19210
  const cacheKeyParam = c.req.query("cacheKey");
19183
19211
  const download = c.req.query("download") === "1";
19184
- const logDirs = listValidAccounts().slice().sort((a, b) => a.accountId.localeCompare(b.accountId)).map((a) => resolve23(a.accountDir, "logs"));
19212
+ const logDirs = listValidAccounts().slice().sort((a, b) => a.accountId.localeCompare(b.accountId)).map((a) => resolve24(a.accountDir, "logs"));
19185
19213
  logDirs.push(LOG_DIR);
19186
19214
  if (fileParam) {
19187
19215
  const safe = basename11(fileParam);
19188
19216
  const searched = [];
19189
19217
  for (const dir of logDirs) {
19190
- const filePath = resolve23(dir, safe);
19218
+ const filePath = resolve24(dir, safe);
19191
19219
  searched.push(filePath);
19192
19220
  try {
19193
19221
  const buffer = readFileSync33(filePath);
@@ -19290,7 +19318,7 @@ app19.get("/", async (c) => {
19290
19318
  const seen = /* @__PURE__ */ new Set();
19291
19319
  const logs = {};
19292
19320
  for (const dir of logDirs) {
19293
- if (!existsSync30(dir)) continue;
19321
+ if (!existsSync29(dir)) continue;
19294
19322
  let files;
19295
19323
  try {
19296
19324
  files = readdirSync20(dir).filter((f) => f.endsWith(".log"));
@@ -19299,10 +19327,10 @@ app19.get("/", async (c) => {
19299
19327
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
19300
19328
  continue;
19301
19329
  }
19302
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync20(resolve23(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
19330
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync20(resolve24(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
19303
19331
  seen.add(name);
19304
19332
  try {
19305
- const content = readFileSync33(resolve23(dir, name));
19333
+ const content = readFileSync33(resolve24(dir, name));
19306
19334
  const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
19307
19335
  logs[name] = tail.trim() || "(empty)";
19308
19336
  } catch (err) {
@@ -19355,12 +19383,12 @@ init_claude_agent();
19355
19383
  init_data_path();
19356
19384
  init_attachments();
19357
19385
  import { readFile as readFile6, readdir as readdir2 } from "fs/promises";
19358
- import { existsSync as existsSync31 } from "fs";
19359
- import { resolve as resolve24 } from "path";
19386
+ import { existsSync as existsSync30 } from "fs";
19387
+ import { resolve as resolve25 } from "path";
19360
19388
  var app21 = new Hono();
19361
19389
  var ATTACHMENT_ID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
19362
19390
  function uploadsDirFor(accountId, attachmentId) {
19363
- return resolve24(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
19391
+ return resolve25(DATA_ROOT, "accounts", accountId, "uploads", attachmentId);
19364
19392
  }
19365
19393
  app21.get("/:attachmentId", requireAdminSession, async (c) => {
19366
19394
  const attachmentId = c.req.param("attachmentId");
@@ -19378,12 +19406,12 @@ app21.get("/:attachmentId", requireAdminSession, async (c) => {
19378
19406
  }
19379
19407
  let accountId = pinnedAccountId;
19380
19408
  let dir = uploadsDirFor(accountId, attachmentId);
19381
- let found = existsSync31(dir);
19409
+ let found = existsSync30(dir);
19382
19410
  if (!found) {
19383
19411
  for (const candidate of listValidAccounts()) {
19384
19412
  if (candidate.accountId === pinnedAccountId) continue;
19385
19413
  const candidateDir = uploadsDirFor(candidate.accountId, attachmentId);
19386
- if (existsSync31(candidateDir)) {
19414
+ if (existsSync30(candidateDir)) {
19387
19415
  accountId = candidate.accountId;
19388
19416
  dir = candidateDir;
19389
19417
  found = true;
@@ -19397,8 +19425,8 @@ app21.get("/:attachmentId", requireAdminSession, async (c) => {
19397
19425
  if (!found) {
19398
19426
  return new Response("Not found", { status: 404 });
19399
19427
  }
19400
- const metaPath = resolve24(dir, `${attachmentId}.meta.json`);
19401
- if (!existsSync31(metaPath)) {
19428
+ const metaPath = resolve25(dir, `${attachmentId}.meta.json`);
19429
+ if (!existsSync30(metaPath)) {
19402
19430
  return new Response("Not found", { status: 404 });
19403
19431
  }
19404
19432
  let meta;
@@ -19412,7 +19440,7 @@ app21.get("/:attachmentId", requireAdminSession, async (c) => {
19412
19440
  if (!dataFile) {
19413
19441
  return new Response("Not found", { status: 404 });
19414
19442
  }
19415
- const filePath = resolve24(dir, dataFile);
19443
+ const filePath = resolve25(dir, dataFile);
19416
19444
  const buffer = await readFile6(filePath);
19417
19445
  const inlineSafe = isInlineSafeMime(meta.mimeType);
19418
19446
  const safeName2 = meta.filename.replace(/["\\\r\n]/g, "_");
@@ -19438,7 +19466,7 @@ init_neo4j_store();
19438
19466
  init_data_path();
19439
19467
  init_attachments();
19440
19468
  import { readFile as readFile7 } from "fs/promises";
19441
- import { existsSync as existsSync32, statSync as statSync21 } from "fs";
19469
+ import { existsSync as existsSync31, statSync as statSync21 } from "fs";
19442
19470
  var app22 = new Hono();
19443
19471
  app22.get("/", requireAdminSession, async (c) => {
19444
19472
  const cacheKey = c.var.cacheKey;
@@ -19459,7 +19487,7 @@ app22.get("/", requireAdminSession, async (c) => {
19459
19487
  return c.json({ error: "Not found" }, 404);
19460
19488
  }
19461
19489
  const resolution = resolveClaudeUploadsPath(`${sessionId}/${file}`);
19462
- if (!resolution.ok || !existsSync32(resolution.absolute) || !statSync21(resolution.absolute).isFile()) {
19490
+ if (!resolution.ok || !existsSync31(resolution.absolute) || !statSync21(resolution.absolute).isFile()) {
19463
19491
  console.log(`[session-upload] op=miss session=${short2} file=${file} status=404 reason=absent`);
19464
19492
  return c.json({ error: "Not found" }, 404);
19465
19493
  }
@@ -19485,12 +19513,12 @@ init_helpers();
19485
19513
  init_account_scope();
19486
19514
  init_neo4j_store();
19487
19515
  init_account();
19488
- import { resolve as resolve25 } from "path";
19489
- import { readdirSync as readdirSync22, readFileSync as readFileSync35, existsSync as existsSync34, rmSync as rmSync5, renameSync as renameSync10, mkdirSync as mkdirSync7, writeFileSync as writeFileSync15, chmodSync } from "fs";
19516
+ import { resolve as resolve26 } from "path";
19517
+ import { readdirSync as readdirSync22, readFileSync as readFileSync35, existsSync as existsSync33, rmSync as rmSync5, renameSync as renameSync10, mkdirSync as mkdirSync7, writeFileSync as writeFileSync15, chmodSync } from "fs";
19490
19518
  import { execFileSync as execFileSync6 } from "child_process";
19491
19519
 
19492
19520
  // ../services/claude-session-manager/src/tool-surface.ts
19493
- import { readFileSync as readFileSync34, readdirSync as readdirSync21, statSync as statSync22, existsSync as existsSync33 } from "fs";
19521
+ import { readFileSync as readFileSync34, readdirSync as readdirSync21, statSync as statSync22, existsSync as existsSync32 } from "fs";
19494
19522
  import { createHash as createHash5 } from "crypto";
19495
19523
  import { join as join40 } from "path";
19496
19524
 
@@ -19736,7 +19764,7 @@ function parseMcpBlock(frontmatter, pluginDir) {
19736
19764
  function loadToolSurface(pluginsRoots) {
19737
19765
  const roots = Array.isArray(pluginsRoots) ? pluginsRoots : [pluginsRoots];
19738
19766
  for (const r of roots) {
19739
- if (!existsSync33(r)) throw new ToolSurfaceError("plugins-root-missing", r);
19767
+ if (!existsSync32(r)) throw new ToolSurfaceError("plugins-root-missing", r);
19740
19768
  }
19741
19769
  const admin = /* @__PURE__ */ new Set();
19742
19770
  const pub = /* @__PURE__ */ new Set();
@@ -19752,7 +19780,7 @@ function loadToolSurface(pluginsRoots) {
19752
19780
  return;
19753
19781
  }
19754
19782
  const manifestPath = join40(pluginDir, "PLUGIN.md");
19755
- if (!existsSync33(manifestPath)) return;
19783
+ if (!existsSync32(manifestPath)) return;
19756
19784
  const raw = readFileSync34(manifestPath, "utf-8");
19757
19785
  const frontmatter = extractFrontmatter(raw, plugin);
19758
19786
  const tools = parseToolsBlock(frontmatter, plugin);
@@ -19933,7 +19961,7 @@ function agentRiskClass(tools, riskByTool) {
19933
19961
  // server/routes/admin/agents.ts
19934
19962
  var SLUG_UNSAFE = (s) => s.includes("/") || s.includes("..") || s.includes("\\");
19935
19963
  function subdirs(dir) {
19936
- if (!existsSync34(dir)) return [];
19964
+ if (!existsSync33(dir)) return [];
19937
19965
  try {
19938
19966
  return readdirSync22(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
19939
19967
  } catch {
@@ -19954,7 +19982,7 @@ var SPECIALISTS_DIR = ["specialists", "agents"];
19954
19982
  var QUARANTINE_DIR = ["specialists", "agents-disabled"];
19955
19983
  var DISABLED_STORE = "agents-disabled.json";
19956
19984
  function loadRiskSurface() {
19957
- const roots = [resolve25(PLATFORM_ROOT, "plugins"), resolve25(PLATFORM_ROOT, "..", "premium-plugins")].filter((r) => existsSync34(r));
19985
+ const roots = [resolve26(PLATFORM_ROOT, "plugins"), resolve26(PLATFORM_ROOT, "..", "premium-plugins")].filter((r) => existsSync33(r));
19958
19986
  try {
19959
19987
  return { riskByTool: loadToolSurface(roots).riskByTool, failed: null };
19960
19988
  } catch (err) {
@@ -19965,8 +19993,8 @@ function loadRiskSurface() {
19965
19993
  }
19966
19994
  }
19967
19995
  function readDisabledStoreStrict(accountDir) {
19968
- const p = resolve25(accountDir, DISABLED_STORE);
19969
- if (!existsSync34(p)) return /* @__PURE__ */ new Set();
19996
+ const p = resolve26(accountDir, DISABLED_STORE);
19997
+ if (!existsSync33(p)) return /* @__PURE__ */ new Set();
19970
19998
  const parsed = JSON.parse(readFileSync35(p, "utf-8"));
19971
19999
  if (!Array.isArray(parsed.disabled)) throw new Error("disabled is not an array");
19972
20000
  return new Set(parsed.disabled.filter((x) => typeof x === "string"));
@@ -19980,38 +20008,86 @@ function readDisabledStore(accountDir) {
19980
20008
  return /* @__PURE__ */ new Set();
19981
20009
  }
19982
20010
  }
19983
- function authoredAgentFilenames(accountDir) {
19984
- const pluginsDir = resolve25(accountDir, "plugins");
19985
- const names = /* @__PURE__ */ new Set();
20011
+ function authoredAgentFiles(accountDir) {
20012
+ const pluginsDir = resolve26(accountDir, "plugins");
20013
+ const byName = /* @__PURE__ */ new Map();
19986
20014
  for (const plugin of subdirs(pluginsDir)) {
19987
- const dir = resolve25(pluginsDir, plugin, "agents");
19988
- if (!existsSync34(dir)) continue;
20015
+ const dir = resolve26(pluginsDir, plugin, "agents");
20016
+ if (!existsSync33(dir)) continue;
19989
20017
  try {
19990
- for (const entry2 of readdirSync22(dir)) if (entry2.endsWith(".md")) names.add(entry2);
20018
+ for (const entry2 of readdirSync22(dir)) {
20019
+ if (!entry2.endsWith(".md")) continue;
20020
+ const path = resolve26(dir, entry2);
20021
+ const paths = byName.get(entry2);
20022
+ if (paths) paths.push(path);
20023
+ else byName.set(entry2, [path]);
20024
+ }
19991
20025
  } catch (err) {
19992
20026
  console.error(`[admin/agents] op=authored-scan read-failed plugin=${plugin} error="${err}"`);
19993
20027
  }
19994
20028
  }
19995
- return names;
20029
+ return byName;
19996
20030
  }
19997
20031
  function shippedSourceDirs(accountDir) {
19998
20032
  return [
19999
- resolve25(accountDir, ...SPECIALISTS_DIR),
20000
- resolve25(accountDir, ...QUARANTINE_DIR),
20001
- resolve25(PLATFORM_ROOT, "templates", "specialists", "agents")
20033
+ resolve26(accountDir, ...SPECIALISTS_DIR),
20034
+ resolve26(accountDir, ...QUARANTINE_DIR),
20035
+ resolve26(PLATFORM_ROOT, "templates", "specialists", "agents")
20002
20036
  ];
20003
20037
  }
20038
+ function readRowFields(path) {
20039
+ const { fm } = splitFrontmatter(readFileSync35(path, "utf-8"));
20040
+ return {
20041
+ name: fm.name ?? "",
20042
+ description: fm.description ?? "",
20043
+ tools: new Set(parseToolsLine(fm.tools))
20044
+ };
20045
+ }
20046
+ function divergentFields(a, b) {
20047
+ const out = [];
20048
+ if (a.name !== b.name) out.push("name");
20049
+ if (a.description !== b.description) out.push("description");
20050
+ if (a.tools.size !== b.tools.size || [...a.tools].some((t) => !b.tools.has(t))) out.push("tools");
20051
+ return out;
20052
+ }
20053
+ function compareToAuthored(candidatePath, authoredPaths, filename) {
20054
+ let candidate;
20055
+ try {
20056
+ candidate = readRowFields(candidatePath);
20057
+ } catch (err) {
20058
+ console.error(`[admin/agents] op=list-shipped-compare-failed file=${filename} side=found reason="${err}"`);
20059
+ return { verdict: "unreadable" };
20060
+ }
20061
+ let firstDivergence = null;
20062
+ let anyUnreadable = false;
20063
+ for (const path of authoredPaths) {
20064
+ let authored;
20065
+ try {
20066
+ authored = readRowFields(path);
20067
+ } catch (err) {
20068
+ console.error(`[admin/agents] op=list-shipped-compare-failed file=${filename} side=authored reason="${err}"`);
20069
+ anyUnreadable = true;
20070
+ continue;
20071
+ }
20072
+ const fields = divergentFields(candidate, authored);
20073
+ if (fields.length === 0) return { verdict: "matched" };
20074
+ firstDivergence ??= { authoredPath: path, fields };
20075
+ }
20076
+ if (firstDivergence) return { verdict: "divergent", ...firstDivergence };
20077
+ if (anyUnreadable) return { verdict: "unreadable" };
20078
+ return { verdict: "unreadable" };
20079
+ }
20004
20080
  function writeDisabledStore(accountDir, disabled) {
20005
- const path = resolve25(accountDir, DISABLED_STORE);
20081
+ const path = resolve26(accountDir, DISABLED_STORE);
20006
20082
  writeFileSync15(path, `${JSON.stringify({ disabled: [...disabled].sort() }, null, 2)}
20007
20083
  `, { mode: 384 });
20008
20084
  chmodSync(path, 384);
20009
20085
  }
20010
- function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, authoredFilenames) {
20086
+ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, authoredFiles) {
20011
20087
  const dirs = shippedSourceDirs(accountDir);
20012
20088
  const names = /* @__PURE__ */ new Set();
20013
20089
  for (const dir of dirs) {
20014
- if (!existsSync34(dir)) continue;
20090
+ if (!existsSync33(dir)) continue;
20015
20091
  try {
20016
20092
  for (const entry2 of readdirSync22(dir)) if (entry2.endsWith(".md")) names.add(entry2);
20017
20093
  } catch (err) {
@@ -20021,16 +20097,27 @@ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, author
20021
20097
  const shipped = [];
20022
20098
  let shippedSkipped = 0;
20023
20099
  let deduped = 0;
20100
+ let divergent = 0;
20024
20101
  for (const filename of [...names].sort()) {
20025
- const source = dirs.find((d) => existsSync34(resolve25(d, filename)));
20102
+ const source = dirs.find((d) => existsSync33(resolve26(d, filename)));
20026
20103
  if (!source) continue;
20027
- if ((source === dirs[0] || source === dirs[1]) && authoredFilenames.has(filename)) {
20028
- deduped++;
20029
- console.log(`[admin/agents] op=list-shipped-dedup file=${filename}`);
20030
- continue;
20104
+ const authoredPaths = source === dirs[0] || source === dirs[1] ? authoredFiles.get(filename) : void 0;
20105
+ if (authoredPaths) {
20106
+ const cmp = compareToAuthored(resolve26(source, filename), authoredPaths, filename);
20107
+ if (cmp.verdict === "matched") {
20108
+ deduped++;
20109
+ console.log(`[admin/agents] op=list-shipped-dedup file=${filename}`);
20110
+ continue;
20111
+ }
20112
+ if (cmp.verdict === "divergent") {
20113
+ divergent++;
20114
+ console.log(
20115
+ `[admin/agents] op=list-shipped-divergent file=${filename} found=${resolve26(source, filename)} authored=${cmp.authoredPath} fields=${cmp.fields.join(",")}`
20116
+ );
20117
+ }
20031
20118
  }
20032
20119
  try {
20033
- const { fm } = splitFrontmatter(readFileSync35(resolve25(source, filename), "utf-8"));
20120
+ const { fm } = splitFrontmatter(readFileSync35(resolve26(source, filename), "utf-8"));
20034
20121
  if (!fm.name) {
20035
20122
  shippedSkipped++;
20036
20123
  console.error(`[admin/agents] op=list-shipped-skip file=${filename} reason=no-name`);
@@ -20063,7 +20150,7 @@ function listShipped(accountDir, riskByTool, disabled, riskSurfaceFailed, author
20063
20150
  console.error(`[admin/agents] op=list-shipped-skip file=${filename} error="${err}"`);
20064
20151
  }
20065
20152
  }
20066
- return { shipped, shippedSkipped, deduped };
20153
+ return { shipped, shippedSkipped, deduped, divergent };
20067
20154
  }
20068
20155
  function parseToolsLine(raw) {
20069
20156
  return raw ? raw.split(",").map((t) => t.trim()).filter(Boolean) : [];
@@ -20084,12 +20171,12 @@ function classify(tools, riskByTool, riskSurfaceFailed) {
20084
20171
  return agentRiskClass(tools, riskByTool);
20085
20172
  }
20086
20173
  function listSpecialists(accountDir, riskByTool, riskSurfaceFailed) {
20087
- const pluginsDir = resolve25(accountDir, "plugins");
20174
+ const pluginsDir = resolve26(accountDir, "plugins");
20088
20175
  const specialists = [];
20089
20176
  let specialistsSkipped = 0;
20090
20177
  for (const plugin of subdirs(pluginsDir).sort()) {
20091
- const agentsDirP = resolve25(pluginsDir, plugin, "agents");
20092
- if (!existsSync34(agentsDirP)) continue;
20178
+ const agentsDirP = resolve26(pluginsDir, plugin, "agents");
20179
+ if (!existsSync33(agentsDirP)) continue;
20093
20180
  let entries2;
20094
20181
  try {
20095
20182
  entries2 = readdirSync22(agentsDirP, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
@@ -20099,7 +20186,7 @@ function listSpecialists(accountDir, riskByTool, riskSurfaceFailed) {
20099
20186
  for (const entry2 of entries2) {
20100
20187
  if (!entry2.isFile() || !entry2.name.endsWith(".md")) continue;
20101
20188
  try {
20102
- const { fm } = splitFrontmatter(readFileSync35(resolve25(agentsDirP, entry2.name), "utf-8"));
20189
+ const { fm } = splitFrontmatter(readFileSync35(resolve26(agentsDirP, entry2.name), "utf-8"));
20103
20190
  if (!fm.name) {
20104
20191
  specialistsSkipped++;
20105
20192
  console.error(`[admin/agents] op=list-specialist-skip plugin=${plugin} file=${entry2.name}`);
@@ -20131,7 +20218,7 @@ function listSpecialists(accountDir, riskByTool, riskSurfaceFailed) {
20131
20218
  // have the surface claim an agent is stopped while it is still being
20132
20219
  // spawned. Absence from the live dir alone is also not the test: a
20133
20220
  // specialist that was never activated was never switched off either.
20134
- disabled: existsSync34(resolve25(accountDir, ...QUARANTINE_DIR, entry2.name)) && !existsSync34(resolve25(accountDir, ...SPECIALISTS_DIR, entry2.name))
20221
+ disabled: existsSync33(resolve26(accountDir, ...QUARANTINE_DIR, entry2.name)) && !existsSync33(resolve26(accountDir, ...SPECIALISTS_DIR, entry2.name))
20135
20222
  });
20136
20223
  } catch {
20137
20224
  specialistsSkipped++;
@@ -20158,15 +20245,15 @@ app23.get("/", requireAdminSession, (c) => {
20158
20245
  const disabled = readDisabledStore(account.accountDir);
20159
20246
  const agents = [];
20160
20247
  let skipped = 0;
20161
- const agentsDir = resolve25(account.accountDir, "agents");
20162
- if (existsSync34(agentsDir)) {
20248
+ const agentsDir = resolve26(account.accountDir, "agents");
20249
+ if (existsSync33(agentsDir)) {
20163
20250
  try {
20164
20251
  const entries2 = readdirSync22(agentsDir, { withFileTypes: true });
20165
20252
  for (const entry2 of entries2.sort((a, b) => a.name.localeCompare(b.name))) {
20166
20253
  if (!entry2.isDirectory()) continue;
20167
20254
  if (entry2.name === "admin") continue;
20168
- const configPath3 = resolve25(agentsDir, entry2.name, "config.json");
20169
- if (!existsSync34(configPath3)) continue;
20255
+ const configPath3 = resolve26(agentsDir, entry2.name, "config.json");
20256
+ if (!existsSync33(configPath3)) continue;
20170
20257
  try {
20171
20258
  const config = JSON.parse(readFileSync35(configPath3, "utf-8"));
20172
20259
  agents.push({
@@ -20192,12 +20279,12 @@ app23.get("/", requireAdminSession, (c) => {
20192
20279
  }
20193
20280
  }
20194
20281
  const { specialists, specialistsSkipped } = listSpecialists(account.accountDir, riskByTool, riskSurfaceFailed !== null);
20195
- const { shipped, shippedSkipped, deduped } = listShipped(
20282
+ const { shipped, shippedSkipped, deduped, divergent } = listShipped(
20196
20283
  account.accountDir,
20197
20284
  riskByTool,
20198
20285
  disabled,
20199
20286
  riskSurfaceFailed !== null,
20200
- authoredAgentFilenames(account.accountDir)
20287
+ authoredAgentFiles(account.accountDir)
20201
20288
  );
20202
20289
  const rows = [...agents, ...specialists, ...shipped];
20203
20290
  const acct = account.accountId.slice(0, 8);
@@ -20215,17 +20302,26 @@ app23.get("/", requireAdminSession, (c) => {
20215
20302
  console.log(
20216
20303
  `[agents] op=rule-census account=${acct} rules=${COMBINATION_RULES.length} classified=${classified} fired=${firedRules.size} never=${never.length > 0 ? never.join(",") : "none"}`
20217
20304
  );
20218
- console.log(`[admin/agents] op=list accountId=${acct} agents=${agents.length} specialists=${specialists.length} shipped=${shipped.length} skipped=${skipped} specialistsSkipped=${specialistsSkipped} shippedSkipped=${shippedSkipped} deduped=${deduped}`);
20305
+ console.log(`[admin/agents] op=list accountId=${acct} agents=${agents.length} specialists=${specialists.length} shipped=${shipped.length} skipped=${skipped} specialistsSkipped=${specialistsSkipped} shippedSkipped=${shippedSkipped} deduped=${deduped} divergent=${divergent}`);
20219
20306
  return c.json({
20220
20307
  agents: rows,
20221
20308
  accountId: account.accountId,
20222
20309
  skipped,
20223
20310
  specialistsSkipped,
20224
20311
  shippedSkipped,
20225
- // How many live-directory candidates were dropped as authored duplicates.
20226
- // `shipped + shippedSkipped + deduped` equals the number of distinct `.md`
20227
- // names across the three source directories.
20312
+ // How many live-directory or quarantine-directory candidates were dropped as
20313
+ // authored duplicates meaning the two files agree on the three fields the
20314
+ // row shows. `shipped + shippedSkipped + deduped` equals the number of
20315
+ // distinct `.md` names across the three source directories.
20228
20316
  deduped,
20317
+ // How many candidates were KEPT because both files read and the three
20318
+ // fields DISAGREE. Never a fourth term in the identity above: a kept
20319
+ // candidate is parsed like any other, so it lands in `shipped`, or in
20320
+ // `shippedSkipped` when its own frontmatter carries no `name:`. A candidate
20321
+ // that could not be compared at all is not counted here — that is
20322
+ // `op=list-shipped-compare-failed`, and reporting it as drift would claim a
20323
+ // disagreement nobody read.
20324
+ divergent,
20229
20325
  riskSurfaceFailed: riskSurfaceFailed !== null
20230
20326
  });
20231
20327
  });
@@ -20239,9 +20335,9 @@ app23.get("/:slug", requireAdminSession, (c) => {
20239
20335
  if (SLUG_UNSAFE(slug)) return c.json({ error: "Invalid agent slug" }, 400);
20240
20336
  if (c.req.query("origin") === "shipped") {
20241
20337
  const dirs = shippedSourceDirs(account.accountDir);
20242
- const source = dirs.find((d) => existsSync34(resolve25(d, `${slug}.md`)));
20338
+ const source = dirs.find((d) => existsSync33(resolve26(d, `${slug}.md`)));
20243
20339
  if (!source) return c.json({ error: "Agent not found" }, 404);
20244
- const { fm, body } = splitFrontmatter(readFileSync35(resolve25(source, `${slug}.md`), "utf-8"));
20340
+ const { fm, body } = splitFrontmatter(readFileSync35(resolve26(source, `${slug}.md`), "utf-8"));
20245
20341
  const { riskByTool, failed: failed2 } = loadRiskSurface();
20246
20342
  const tools = parseToolsLine(fm.tools);
20247
20343
  const r = classify(tools, riskByTool, failed2 !== null);
@@ -20271,10 +20367,10 @@ app23.get("/:slug", requireAdminSession, (c) => {
20271
20367
  const pluginParam = c.req.query("plugin");
20272
20368
  if (pluginParam) {
20273
20369
  if (SLUG_UNSAFE(pluginParam)) return c.json({ error: "Invalid plugin" }, 400);
20274
- const file = resolve25(account.accountDir, "plugins", pluginParam, "agents", `${slug}.md`);
20275
- if (!existsSync34(file)) return c.json({ error: "Agent not found" }, 404);
20370
+ const file = resolve26(account.accountDir, "plugins", pluginParam, "agents", `${slug}.md`);
20371
+ if (!existsSync33(file)) return c.json({ error: "Agent not found" }, 404);
20276
20372
  const { fm, body } = splitFrontmatter(readFileSync35(file, "utf-8"));
20277
- const skills = subdirs(resolve25(account.accountDir, "plugins", pluginParam, "skills"));
20373
+ const skills = subdirs(resolve26(account.accountDir, "plugins", pluginParam, "skills"));
20278
20374
  const { riskByTool, failed: failed2 } = loadRiskSurface();
20279
20375
  const tools = parseToolsLine(fm.tools);
20280
20376
  const r = classify(tools, riskByTool, failed2 !== null);
@@ -20301,9 +20397,9 @@ app23.get("/:slug", requireAdminSession, (c) => {
20301
20397
  }
20302
20398
  });
20303
20399
  }
20304
- const agentDir = resolve25(account.accountDir, "agents", slug);
20305
- const configPath3 = resolve25(agentDir, "config.json");
20306
- if (!existsSync34(configPath3)) return c.json({ error: "Agent not found" }, 404);
20400
+ const agentDir = resolve26(account.accountDir, "agents", slug);
20401
+ const configPath3 = resolve26(agentDir, "config.json");
20402
+ if (!existsSync33(configPath3)) return c.json({ error: "Agent not found" }, 404);
20307
20403
  let config;
20308
20404
  try {
20309
20405
  config = JSON.parse(readFileSync35(configPath3, "utf-8"));
@@ -20314,9 +20410,9 @@ app23.get("/:slug", requireAdminSession, (c) => {
20314
20410
  const docs = {};
20315
20411
  const present = {};
20316
20412
  for (const { file, key: key2 } of OWNED_DOCS) {
20317
- const p = resolve25(agentDir, file);
20413
+ const p = resolve26(agentDir, file);
20318
20414
  try {
20319
- if (existsSync34(p)) {
20415
+ if (existsSync33(p)) {
20320
20416
  docs[key2] = readFileSync35(p, "utf-8");
20321
20417
  present[key2] = true;
20322
20418
  } else {
@@ -20365,7 +20461,7 @@ async function resolveWritableAccount(c, op, slug) {
20365
20461
  return account;
20366
20462
  }
20367
20463
  function reconcileRoutingProse(accountDir, accountId, op, slug) {
20368
- const script = resolve25(PLATFORM_ROOT, "scripts", "lib", "agents-md-bootstrap.sh");
20464
+ const script = resolve26(PLATFORM_ROOT, "scripts", "lib", "agents-md-bootstrap.sh");
20369
20465
  try {
20370
20466
  execFileSync6("bash", [script, accountDir], { encoding: "utf-8", timeout: 1e4 });
20371
20467
  return true;
@@ -20376,8 +20472,8 @@ function reconcileRoutingProse(accountDir, accountId, op, slug) {
20376
20472
  }
20377
20473
  }
20378
20474
  function reconcileAuthoredRoutingLine(accountDir, accountId, op, source) {
20379
- const agentsMd = resolve25(accountDir, "agents", "admin", "AGENTS.md");
20380
- if (!existsSync34(agentsMd) || !existsSync34(source)) return false;
20475
+ const agentsMd = resolve26(accountDir, "agents", "admin", "AGENTS.md");
20476
+ if (!existsSync33(agentsMd) || !existsSync33(source)) return false;
20381
20477
  try {
20382
20478
  const { fm } = splitFrontmatter(readFileSync35(source, "utf-8"));
20383
20479
  if (!fm.name) return false;
@@ -20400,18 +20496,18 @@ app23.post("/:slug/disable", async (c) => {
20400
20496
  const resolved = await resolveWritableAccount(c, "disable", slug);
20401
20497
  if ("status" in resolved) return c.json({ error: resolved.error }, resolved.status);
20402
20498
  const filename = `${slug}.md`;
20403
- const live = resolve25(resolved.accountDir, ...SPECIALISTS_DIR, filename);
20404
- const quarantined = resolve25(resolved.accountDir, ...QUARANTINE_DIR, filename);
20405
- if (!authoredAgentFilenames(resolved.accountDir).has(filename)) {
20499
+ const live = resolve26(resolved.accountDir, ...SPECIALISTS_DIR, filename);
20500
+ const quarantined = resolve26(resolved.accountDir, ...QUARANTINE_DIR, filename);
20501
+ if (!authoredAgentFiles(resolved.accountDir).has(filename)) {
20406
20502
  console.error(`[admin/agents] op=disable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} origin=not-authored eligible=false outcome=refused reason=not-user-created`);
20407
20503
  return c.json({ error: "Only an agent you created can be switched off here. A shipped agent is stopped by suspending the routines that dispatch it." }, 404);
20408
20504
  }
20409
- if (!existsSync34(live)) {
20505
+ if (!existsSync33(live)) {
20410
20506
  console.error(`[admin/agents] op=disable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} origin=specialist eligible=true outcome=refused reason=not-dispatchable`);
20411
20507
  return c.json({ error: "This agent is not in the dispatchable set, so there is nothing to switch off." }, 409);
20412
20508
  }
20413
20509
  try {
20414
- mkdirSync7(resolve25(resolved.accountDir, ...QUARANTINE_DIR), { recursive: true });
20510
+ mkdirSync7(resolve26(resolved.accountDir, ...QUARANTINE_DIR), { recursive: true });
20415
20511
  renameSync10(live, quarantined);
20416
20512
  } catch (err) {
20417
20513
  const msg = err instanceof Error ? err.message : String(err);
@@ -20428,28 +20524,28 @@ app23.post("/:slug/enable", async (c) => {
20428
20524
  const resolved = await resolveWritableAccount(c, "enable", slug);
20429
20525
  if ("status" in resolved) return c.json({ error: resolved.error }, resolved.status);
20430
20526
  const filename = `${slug}.md`;
20431
- const live = resolve25(resolved.accountDir, ...SPECIALISTS_DIR, filename);
20432
- const quarantined = resolve25(resolved.accountDir, ...QUARANTINE_DIR, filename);
20433
- const authored = authoredAgentFilenames(resolved.accountDir).has(filename);
20527
+ const live = resolve26(resolved.accountDir, ...SPECIALISTS_DIR, filename);
20528
+ const quarantined = resolve26(resolved.accountDir, ...QUARANTINE_DIR, filename);
20529
+ const authored = authoredAgentFiles(resolved.accountDir).has(filename);
20434
20530
  const origin = authored ? "specialist" : "shipped";
20435
20531
  let restored = false;
20436
20532
  try {
20437
20533
  if (authored) {
20438
- if (!existsSync34(quarantined)) {
20534
+ if (!existsSync33(quarantined)) {
20439
20535
  console.error(`[admin/agents] op=enable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} origin=specialist eligible=true outcome=refused reason=not-disabled`);
20440
20536
  return c.json({ error: "This agent is not disabled" }, 404);
20441
20537
  }
20442
- mkdirSync7(resolve25(resolved.accountDir, ...SPECIALISTS_DIR), { recursive: true });
20538
+ mkdirSync7(resolve26(resolved.accountDir, ...SPECIALISTS_DIR), { recursive: true });
20443
20539
  renameSync10(quarantined, live);
20444
20540
  restored = true;
20445
20541
  } else {
20446
20542
  const disabled = readDisabledStoreStrict(resolved.accountDir);
20447
- if (!existsSync34(quarantined) && !disabled.has(filename)) {
20543
+ if (!existsSync33(quarantined) && !disabled.has(filename)) {
20448
20544
  console.error(`[admin/agents] op=enable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} origin=shipped eligible=true outcome=refused reason=not-disabled`);
20449
20545
  return c.json({ error: "This agent is not disabled" }, 404);
20450
20546
  }
20451
- if (existsSync34(quarantined)) {
20452
- mkdirSync7(resolve25(resolved.accountDir, ...SPECIALISTS_DIR), { recursive: true });
20547
+ if (existsSync33(quarantined)) {
20548
+ mkdirSync7(resolve26(resolved.accountDir, ...SPECIALISTS_DIR), { recursive: true });
20453
20549
  renameSync10(quarantined, live);
20454
20550
  restored = true;
20455
20551
  }
@@ -20490,8 +20586,8 @@ app23.delete("/:slug", async (c) => {
20490
20586
  console.error(`[admin/agents] op=delete rejected reason=${authz.reason} accountId=${account.accountId.slice(0, 8)} slug=${slug}`);
20491
20587
  return c.json({ error: "Not authorized for this account" }, 403);
20492
20588
  }
20493
- const agentDir = resolve25(account.accountDir, "agents", slug);
20494
- if (!existsSync34(agentDir)) {
20589
+ const agentDir = resolve26(account.accountDir, "agents", slug);
20590
+ if (!existsSync33(agentDir)) {
20495
20591
  return c.json({ error: "Agent not found" }, 404);
20496
20592
  }
20497
20593
  try {
@@ -20533,8 +20629,8 @@ app23.post("/:slug/project", async (c) => {
20533
20629
  console.error(`[admin/agents] op=project rejected reason=${authz.reason} accountId=${account.accountId.slice(0, 8)} slug=${slug}`);
20534
20630
  return c.json({ error: "Not authorized for this account" }, 403);
20535
20631
  }
20536
- const agentDir = resolve25(account.accountDir, "agents", slug);
20537
- if (!existsSync34(agentDir)) {
20632
+ const agentDir = resolve26(account.accountDir, "agents", slug);
20633
+ if (!existsSync33(agentDir)) {
20538
20634
  console.error(`[admin/agents] op=project rejected reason=agent-not-on-disk accountId=${account.accountId.slice(0, 8)} slug=${slug} probed=${agentDir}`);
20539
20635
  return c.json({ error: "Agent not found on disk" }, 404);
20540
20636
  }
@@ -20558,7 +20654,7 @@ init_account();
20558
20654
  init_neo4j_store();
20559
20655
  import crypto2 from "crypto";
20560
20656
  import { resolve as resolvePath } from "path";
20561
- import { existsSync as existsSync35, mkdirSync as mkdirSync8, createWriteStream } from "fs";
20657
+ import { existsSync as existsSync34, mkdirSync as mkdirSync8, createWriteStream } from "fs";
20562
20658
 
20563
20659
  // app/lib/admin-conversation-cascade.ts
20564
20660
  init_neo4j_store();
@@ -20726,7 +20822,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
20726
20822
  let reason = null;
20727
20823
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
20728
20824
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
20729
- else if (!existsSync35(a.storagePath)) reason = "missing-file";
20825
+ else if (!existsSync34(a.storagePath)) reason = "missing-file";
20730
20826
  if (reason) {
20731
20827
  invalid++;
20732
20828
  try {
@@ -21259,8 +21355,8 @@ init_claude_agent();
21259
21355
  // app/lib/claude-agent/spawn-context.ts
21260
21356
  init_account();
21261
21357
  init_neo4j_store();
21262
- import { existsSync as existsSync36, readFileSync as readFileSync36, readdirSync as readdirSync23, statSync as statSync23 } from "fs";
21263
- import { dirname as dirname14, resolve as resolve26, join as join41 } from "path";
21358
+ import { existsSync as existsSync35, readFileSync as readFileSync36, readdirSync as readdirSync23, statSync as statSync23 } from "fs";
21359
+ import { dirname as dirname14, resolve as resolve27, join as join41 } from "path";
21264
21360
  async function resolveOwnerProfileBlock(accountId, userId) {
21265
21361
  if (!userId) return { ok: false, reason: "missing-user-id" };
21266
21362
  try {
@@ -21306,7 +21402,7 @@ function extractPluginToolDescriptions(pluginDir) {
21306
21402
  ];
21307
21403
  let raw = null;
21308
21404
  for (const path of candidates) {
21309
- if (!existsSync36(path)) continue;
21405
+ if (!existsSync35(path)) continue;
21310
21406
  try {
21311
21407
  raw = readFileSync36(path, "utf-8");
21312
21408
  break;
@@ -21357,8 +21453,8 @@ function parseSkillPathsFromFrontmatter(fm) {
21357
21453
  }
21358
21454
  function listPluginDirs(accountPluginsDir) {
21359
21455
  const out = /* @__PURE__ */ new Map();
21360
- const platformPlugins = resolve26(PLATFORM_ROOT, "plugins");
21361
- if (existsSync36(platformPlugins)) {
21456
+ const platformPlugins = resolve27(PLATFORM_ROOT, "plugins");
21457
+ if (existsSync35(platformPlugins)) {
21362
21458
  for (const name of readdirSync23(platformPlugins)) {
21363
21459
  const dir = join41(platformPlugins, name);
21364
21460
  try {
@@ -21367,11 +21463,11 @@ function listPluginDirs(accountPluginsDir) {
21367
21463
  }
21368
21464
  }
21369
21465
  }
21370
- const premiumRoot = resolve26(dirname14(PLATFORM_ROOT), "premium-plugins");
21371
- if (existsSync36(premiumRoot)) {
21466
+ const premiumRoot = resolve27(dirname14(PLATFORM_ROOT), "premium-plugins");
21467
+ if (existsSync35(premiumRoot)) {
21372
21468
  for (const bundle of readdirSync23(premiumRoot)) {
21373
21469
  const bundlePlugins = join41(premiumRoot, bundle, "plugins");
21374
- if (!existsSync36(bundlePlugins)) continue;
21470
+ if (!existsSync35(bundlePlugins)) continue;
21375
21471
  try {
21376
21472
  for (const name of readdirSync23(bundlePlugins)) {
21377
21473
  const dir = join41(bundlePlugins, name);
@@ -21384,7 +21480,7 @@ function listPluginDirs(accountPluginsDir) {
21384
21480
  }
21385
21481
  }
21386
21482
  }
21387
- if (accountPluginsDir && existsSync36(accountPluginsDir)) {
21483
+ if (accountPluginsDir && existsSync35(accountPluginsDir)) {
21388
21484
  try {
21389
21485
  for (const name of readdirSync23(accountPluginsDir)) {
21390
21486
  if (out.has(name)) continue;
@@ -21400,10 +21496,10 @@ function listPluginDirs(accountPluginsDir) {
21400
21496
  return out;
21401
21497
  }
21402
21498
  function accountPluginsDirFor(accountId) {
21403
- return resolve26(PLATFORM_ROOT, "..", "data/accounts", accountId, "plugins");
21499
+ return resolve27(PLATFORM_ROOT, "..", "data/accounts", accountId, "plugins");
21404
21500
  }
21405
21501
  function listAccountPluginNames(accountPluginsDir) {
21406
- if (!existsSync36(accountPluginsDir)) return [];
21502
+ if (!existsSync35(accountPluginsDir)) return [];
21407
21503
  try {
21408
21504
  return readdirSync23(accountPluginsDir).filter((name) => {
21409
21505
  try {
@@ -21417,8 +21513,8 @@ function listAccountPluginNames(accountPluginsDir) {
21417
21513
  }
21418
21514
  }
21419
21515
  function readEnabledPlugins(accountId) {
21420
- const accountFile = resolve26(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
21421
- if (!existsSync36(accountFile)) return /* @__PURE__ */ new Set();
21516
+ const accountFile = resolve27(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
21517
+ if (!existsSync35(accountFile)) return /* @__PURE__ */ new Set();
21422
21518
  try {
21423
21519
  const parsed = JSON.parse(readFileSync36(accountFile, "utf-8"));
21424
21520
  return new Set(
@@ -21429,7 +21525,7 @@ function readEnabledPlugins(accountId) {
21429
21525
  }
21430
21526
  }
21431
21527
  function readFrontmatter(path) {
21432
- if (!existsSync36(path)) return null;
21528
+ if (!existsSync35(path)) return null;
21433
21529
  let raw;
21434
21530
  try {
21435
21531
  raw = readFileSync36(path, "utf-8");
@@ -21467,7 +21563,7 @@ ${fm}
21467
21563
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
21468
21564
  );
21469
21565
  if (toolNames.length > 0 && descMap.size === 0) {
21470
- const hasSource = existsSync36(join41(dir, "mcp/dist/index.js")) || existsSync36(join41(dir, "mcp/src/index.ts"));
21566
+ const hasSource = existsSync35(join41(dir, "mcp/dist/index.js")) || existsSync35(join41(dir, "mcp/src/index.ts"));
21471
21567
  if (hasSource) {
21472
21568
  console.warn(
21473
21569
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -21493,8 +21589,8 @@ ${skillFm}
21493
21589
  return out;
21494
21590
  }
21495
21591
  function computeSpecialistDomains(accountId) {
21496
- const specialistsDir = resolve26(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
21497
- if (!existsSync36(specialistsDir)) return [];
21592
+ const specialistsDir = resolve27(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
21593
+ if (!existsSync35(specialistsDir)) return [];
21498
21594
  let entries2;
21499
21595
  try {
21500
21596
  entries2 = readdirSync23(specialistsDir);
@@ -21539,8 +21635,8 @@ ${fm}
21539
21635
  return out;
21540
21636
  }
21541
21637
  function computeDormantPlugins(accountId) {
21542
- const accountFile = resolve26(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
21543
- if (!existsSync36(accountFile)) return [];
21638
+ const accountFile = resolve27(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
21639
+ if (!existsSync35(accountFile)) return [];
21544
21640
  let enabled;
21545
21641
  try {
21546
21642
  const raw = readFileSync36(accountFile, "utf-8");
@@ -21554,8 +21650,8 @@ function computeDormantPlugins(accountId) {
21554
21650
  );
21555
21651
  return [];
21556
21652
  }
21557
- const pluginsDir = resolve26(PLATFORM_ROOT, "plugins");
21558
- if (!existsSync36(pluginsDir)) return [];
21653
+ const pluginsDir = resolve27(PLATFORM_ROOT, "plugins");
21654
+ if (!existsSync35(pluginsDir)) return [];
21559
21655
  let entries2;
21560
21656
  try {
21561
21657
  entries2 = readdirSync23(pluginsDir);
@@ -21565,8 +21661,8 @@ function computeDormantPlugins(accountId) {
21565
21661
  const out = [];
21566
21662
  for (const name of entries2) {
21567
21663
  if (enabled.has(name)) continue;
21568
- const manifestPath = resolve26(pluginsDir, name, "PLUGIN.md");
21569
- if (!existsSync36(manifestPath)) continue;
21664
+ const manifestPath = resolve27(pluginsDir, name, "PLUGIN.md");
21665
+ if (!existsSync35(manifestPath)) continue;
21570
21666
  let manifest;
21571
21667
  try {
21572
21668
  manifest = readFileSync36(manifestPath, "utf-8");
@@ -21584,11 +21680,11 @@ function computeDormantPlugins(accountId) {
21584
21680
 
21585
21681
  // server/routes/admin/claude-sessions.ts
21586
21682
  init_neo4j_store();
21587
- import { existsSync as existsSync37, readFileSync as readFileSync37 } from "fs";
21588
- import { resolve as resolve27 } from "path";
21683
+ import { existsSync as existsSync36, readFileSync as readFileSync37 } from "fs";
21684
+ import { resolve as resolve28 } from "path";
21589
21685
  function readTunnelState(brandConfigDir) {
21590
21686
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
21591
- if (!existsSync37(statePath)) return null;
21687
+ if (!existsSync36(statePath)) return null;
21592
21688
  try {
21593
21689
  const parsed = JSON.parse(readFileSync37(statePath, "utf-8"));
21594
21690
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
@@ -21601,10 +21697,10 @@ function readTunnelState(brandConfigDir) {
21601
21697
  }
21602
21698
  }
21603
21699
  function resolveTunnelUrl() {
21604
- const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve27(process.cwd(), "..");
21700
+ const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? process.env.PLATFORM_ROOT ?? resolve28(process.cwd(), "..");
21605
21701
  let brand;
21606
21702
  try {
21607
- brand = JSON.parse(readFileSync37(resolve27(platformRoot5, "config", "brand.json"), "utf-8"));
21703
+ brand = JSON.parse(readFileSync37(resolve28(platformRoot5, "config", "brand.json"), "utf-8"));
21608
21704
  } catch {
21609
21705
  return null;
21610
21706
  }
@@ -22064,11 +22160,11 @@ init_helpers();
22064
22160
  init_claude_agent();
22065
22161
  init_data_path();
22066
22162
  init_sidebar_sessions();
22067
- import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync38 } from "fs";
22163
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync37 } from "fs";
22068
22164
  import { readdir as readdir4, readFile as readFile9, stat as stat6, mkdir as mkdir3, unlink as unlink3, rename as rename3, rmdir } from "fs/promises";
22069
22165
  import { realpathSync as realpathSync7 } from "fs";
22070
22166
  import { randomUUID as randomUUID7 } from "crypto";
22071
- import { basename as basename13, dirname as dirname15, join as join44, relative as relative6, resolve as resolve29, sep as sep9 } from "path";
22167
+ import { basename as basename13, dirname as dirname15, join as join44, relative as relative6, resolve as resolve30, sep as sep9 } from "path";
22072
22168
  import { Readable as Readable2 } from "stream";
22073
22169
  init_attachments();
22074
22170
 
@@ -22392,7 +22488,7 @@ async function cascadeDeleteDocument(params) {
22392
22488
  init_data_path();
22393
22489
  init_neo4j_store();
22394
22490
  import * as fsp from "fs/promises";
22395
- import { resolve as resolve28, relative as relative5, join as join43, basename as basename12, extname, sep as sep8 } from "path";
22491
+ import { resolve as resolve29, relative as relative5, join as join43, basename as basename12, extname, sep as sep8 } from "path";
22396
22492
  import { tmpdir as tmpdir3 } from "os";
22397
22493
  import { execFile } from "child_process";
22398
22494
  import { promisify } from "util";
@@ -22712,7 +22808,7 @@ async function reconcileFileIndex(accountId, opts) {
22712
22808
  return withSession2(opts, async (session) => {
22713
22809
  const walked = [];
22714
22810
  const subtreeRoots = [
22715
- resolve28(dataRoot, "accounts", accountId)
22811
+ resolve29(dataRoot, "accounts", accountId)
22716
22812
  ];
22717
22813
  let clean = true;
22718
22814
  for (const root of subtreeRoots) {
@@ -22795,7 +22891,7 @@ async function reconcileFileIndexDebounced(accountId, opts) {
22795
22891
  async function indexFile(accountId, relativePath, opts) {
22796
22892
  const dataRoot = opts?.dataRoot ?? DATA_ROOT;
22797
22893
  const embed2 = opts?.embed ?? embed;
22798
- const absolute = resolve28(dataRoot, relativePath);
22894
+ const absolute = resolve29(dataRoot, relativePath);
22799
22895
  await withSession2(opts, async (session) => {
22800
22896
  const st = await fsp.stat(absolute);
22801
22897
  const wf = {
@@ -22944,7 +23040,7 @@ async function readMeta2(absDir, baseName) {
22944
23040
  }
22945
23041
  async function readAccountNames() {
22946
23042
  const map = /* @__PURE__ */ new Map();
22947
- const accountsDir = resolve29(DATA_ROOT, "accounts");
23043
+ const accountsDir = resolve30(DATA_ROOT, "accounts");
22948
23044
  let names;
22949
23045
  try {
22950
23046
  names = await readdir4(accountsDir);
@@ -22953,7 +23049,7 @@ async function readAccountNames() {
22953
23049
  }
22954
23050
  for (const name of names) {
22955
23051
  if (!UUID_RE3.test(name)) continue;
22956
- const configPath3 = resolve29(accountsDir, name, "account.json");
23052
+ const configPath3 = resolve30(accountsDir, name, "account.json");
22957
23053
  try {
22958
23054
  const raw = await readFile9(configPath3, "utf8");
22959
23055
  const parsed = JSON.parse(raw);
@@ -23555,8 +23651,8 @@ async function resolveUploadTarget(c, accountId, uid) {
23555
23651
  return { ok: false, status: 403, error: "Path is outside your account folder" };
23556
23652
  }
23557
23653
  }
23558
- const destDir = relDir === "." ? base.absolute : resolve29(base.absolute, relDir);
23559
- const destPath = resolve29(destDir, finalName);
23654
+ const destDir = relDir === "." ? base.absolute : resolve30(base.absolute, relDir);
23655
+ const destPath = resolve30(destDir, finalName);
23560
23656
  if (relpath) {
23561
23657
  const firstCreated = await mkdir3(destDir, { recursive: true });
23562
23658
  if (firstCreated) console.error(`[data-upload] op=mkdir uid=${uid} token=${token} dir="${destRel}"`);
@@ -23573,7 +23669,7 @@ async function resolveUploadTarget(c, accountId, uid) {
23573
23669
  return { ok: true, destDir, destPath, destRel, finalName, mimeType, relpath, token };
23574
23670
  }
23575
23671
  async function logUploadsTmpCensus(accountId) {
23576
- const tmpDir = resolve29(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23672
+ const tmpDir = resolve30(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23577
23673
  let live = 0;
23578
23674
  try {
23579
23675
  live = (await readdir4(tmpDir)).length;
@@ -23600,9 +23696,9 @@ app29.post("/upload", requireAdminSession, async (c) => {
23600
23696
  if (!body) return c.json({ error: "Empty request body" }, 400);
23601
23697
  console.error(`[data-upload] op=request uid=${uid} account=${accountId} dir="${destRel}" token=${token} rel="${relpath ?? ""}" declaredBytes=${declaredBytes}`);
23602
23698
  const ceiling = dataUploadCeiling();
23603
- const tmpDir = resolve29(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23699
+ const tmpDir = resolve30(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23604
23700
  await mkdir3(tmpDir, { recursive: true });
23605
- const tmpPath = resolve29(tmpDir, `${uid}.part`);
23701
+ const tmpPath = resolve30(tmpDir, `${uid}.part`);
23606
23702
  const out = createWriteStream2(tmpPath);
23607
23703
  const t0 = Date.now();
23608
23704
  let received2 = 0;
@@ -23620,7 +23716,7 @@ app29.post("/upload", requireAdminSession, async (c) => {
23620
23716
  });
23621
23717
  await unlink3(tmpPath).catch(() => {
23622
23718
  });
23623
- const tempRemoved = !existsSync38(tmpPath);
23719
+ const tempRemoved = !existsSync37(tmpPath);
23624
23720
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
23625
23721
  };
23626
23722
  const reader = body.getReader();
@@ -23694,7 +23790,7 @@ async function discardChunkUpload(uploadId, state) {
23694
23790
  });
23695
23791
  await unlink3(state.tmpPath).catch(() => {
23696
23792
  });
23697
- const tempRemoved = !existsSync38(state.tmpPath);
23793
+ const tempRemoved = !existsSync37(state.tmpPath);
23698
23794
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
23699
23795
  }
23700
23796
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -23749,9 +23845,9 @@ async function handleChunkUpload(c, accountId) {
23749
23845
  }
23750
23846
  const target = await resolveUploadTarget(c, accountId, uploadId);
23751
23847
  if (!target.ok) return c.json({ error: target.error }, target.status);
23752
- const tmpDir = resolve29(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23848
+ const tmpDir = resolve30(DATA_ROOT, "accounts", accountId, UPLOAD_TMP_DIR);
23753
23849
  await mkdir3(tmpDir, { recursive: true });
23754
- const tmpPath = resolve29(tmpDir, `${uploadId}.part`);
23850
+ const tmpPath = resolve30(tmpDir, `${uploadId}.part`);
23755
23851
  const out = createWriteStream2(tmpPath);
23756
23852
  const state2 = {
23757
23853
  accountId,
@@ -23857,7 +23953,7 @@ async function evictStaleChunkUploads(ttlMs) {
23857
23953
  return evicted;
23858
23954
  }
23859
23955
  async function sweepStaleUploadTemps() {
23860
- const accountsRoot = resolve29(DATA_ROOT, "accounts");
23956
+ const accountsRoot = resolve30(DATA_ROOT, "accounts");
23861
23957
  let accounts;
23862
23958
  try {
23863
23959
  accounts = await readdir4(accountsRoot, { withFileTypes: true });
@@ -23867,7 +23963,7 @@ async function sweepStaleUploadTemps() {
23867
23963
  let removed = 0;
23868
23964
  for (const acc of accounts) {
23869
23965
  if (!acc.isDirectory()) continue;
23870
- const tmpDir = resolve29(accountsRoot, acc.name, UPLOAD_TMP_DIR);
23966
+ const tmpDir = resolve30(accountsRoot, acc.name, UPLOAD_TMP_DIR);
23871
23967
  let entries2;
23872
23968
  try {
23873
23969
  entries2 = await readdir4(tmpDir);
@@ -23876,7 +23972,7 @@ async function sweepStaleUploadTemps() {
23876
23972
  }
23877
23973
  for (const name of entries2) {
23878
23974
  try {
23879
- await unlink3(resolve29(tmpDir, name));
23975
+ await unlink3(resolve30(tmpDir, name));
23880
23976
  removed++;
23881
23977
  } catch {
23882
23978
  }
@@ -23991,7 +24087,7 @@ app29.post("/folder", requireAdminSession, async (c) => {
23991
24087
  if (!isValidEntryName(name)) return c.json({ error: "Invalid folder name" }, 400);
23992
24088
  const parent = resolveSharedOrOwnAccountWrite(rawPath, accountId, "POST /api/admin/files/folder");
23993
24089
  if (!parent.ok) return c.json({ error: parent.error }, parent.status);
23994
- const newAbs = resolve29(parent.absolute, name);
24090
+ const newAbs = resolve30(parent.absolute, name);
23995
24091
  const newRel = `${parent.relative}/${name}`;
23996
24092
  try {
23997
24093
  const info = await stat6(parent.absolute);
@@ -24030,7 +24126,7 @@ app29.post("/rename", requireAdminSession, async (c) => {
24030
24126
  console.error(`[data] file-rename blocked path="${src.relative}" reason="protected"`);
24031
24127
  return c.json({ error: "Protected entry \u2014 refusing to rename" }, 403);
24032
24128
  }
24033
- const destAbs = resolve29(dirname15(src.absolute), newName);
24129
+ const destAbs = resolve30(dirname15(src.absolute), newName);
24034
24130
  const newRel = `${dirname15(src.relative)}/${newName}`.replace(/^\.\//, "");
24035
24131
  if (isProtectedFromRename(newRel)) {
24036
24132
  console.error(`[data] file-rename blocked path="${newRel}" reason="protected-target"`);
@@ -25063,7 +25159,7 @@ function isHiddenByDefault(label) {
25063
25159
  // server/lib/top-level-labels.ts
25064
25160
  var import_dist8 = __toESM(require_dist6(), 1);
25065
25161
  import { readdirSync as readdirSync24, readFileSync as readFileSync38 } from "fs";
25066
- import { join as join45, resolve as resolve30 } from "path";
25162
+ import { join as join45, resolve as resolve31 } from "path";
25067
25163
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
25068
25164
  /* @__PURE__ */ new Set([
25069
25165
  // Base-schema infra (schema-base.md has no top-level section).
@@ -25169,7 +25265,7 @@ function resolveReferencesDir() {
25169
25265
  if (process.env.MAXY_PLATFORM_ROOT) {
25170
25266
  return join45(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
25171
25267
  }
25172
- return resolve30(import.meta.dirname, "../../../plugins/memory/references");
25268
+ return resolve31(import.meta.dirname, "../../../plugins/memory/references");
25173
25269
  }
25174
25270
  function parseTableTopLevelLabels(referencesDir) {
25175
25271
  const labels = /* @__PURE__ */ new Set();
@@ -26355,8 +26451,8 @@ init_claude_agent();
26355
26451
  init_account();
26356
26452
  init_route_cache();
26357
26453
  import { readdir as readdir5, stat as stat7 } from "fs/promises";
26358
- import { resolve as resolve31, relative as relative7, isAbsolute as isAbsolute4, sep as sep10, basename as basename14 } from "path";
26359
- import { existsSync as existsSync39 } from "fs";
26454
+ import { resolve as resolve32, relative as relative7, isAbsolute as isAbsolute4, sep as sep10, basename as basename14 } from "path";
26455
+ import { existsSync as existsSync38 } from "fs";
26360
26456
  init_neo4j_store();
26361
26457
  init_attachments();
26362
26458
  init_data_path();
@@ -26374,11 +26470,11 @@ app36.get("/", requireAdminSession, async (c) => {
26374
26470
  return c.json({ error: "Account not found for session" }, 401);
26375
26471
  }
26376
26472
  const start = Date.now();
26377
- ensureAccountWatchers(accountId, resolve31(ACCOUNTS_DIR, accountId));
26473
+ ensureAccountWatchers(accountId, resolve32(ACCOUNTS_DIR, accountId));
26378
26474
  const { value, state } = await getOrCompute("sidebar-artefacts", accountId, async () => {
26379
26475
  const accountFiles = await fetchAccountFileArtefacts(accountId);
26380
26476
  if (accountFiles === null) return null;
26381
- const accountDir = resolve31(ACCOUNTS_DIR, accountId);
26477
+ const accountDir = resolve32(ACCOUNTS_DIR, accountId);
26382
26478
  const agents = await fetchAgentTemplateRows(accountDir);
26383
26479
  const artefacts = [...accountFiles, ...agents].sort(
26384
26480
  (a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "")
@@ -26435,8 +26531,8 @@ async function fetchAccountFileArtefacts(accountId) {
26435
26531
  async function fetchAgentTemplateRows(accountDir) {
26436
26532
  const rows = [];
26437
26533
  for (const filename of ADMIN_AGENT_FILES) {
26438
- const overridePath = resolve31(accountDir, "agents", "admin", filename);
26439
- const bundledPath = resolve31(PLATFORM_ROOT, "templates", "agents", "admin", filename);
26534
+ const overridePath = resolve32(accountDir, "agents", "admin", filename);
26535
+ const bundledPath = resolve32(PLATFORM_ROOT, "templates", "agents", "admin", filename);
26440
26536
  const labelStem = filename.replace(/\.md$/, "");
26441
26537
  const row = await readAgentTemplateRow({
26442
26538
  id: `agent-template:admin:${filename}`,
@@ -26449,12 +26545,12 @@ async function fetchAgentTemplateRows(accountDir) {
26449
26545
  });
26450
26546
  if (row) rows.push(row);
26451
26547
  }
26452
- const overrideDir = resolve31(accountDir, "specialists", "agents");
26453
- const bundledDir = resolve31(PLATFORM_ROOT, "templates", "specialists", "agents");
26548
+ const overrideDir = resolve32(accountDir, "specialists", "agents");
26549
+ const bundledDir = resolve32(PLATFORM_ROOT, "templates", "specialists", "agents");
26454
26550
  const specialistNames = await unionSpecialistFilenames(overrideDir, bundledDir);
26455
26551
  for (const filename of specialistNames) {
26456
- const overridePath = resolve31(overrideDir, filename);
26457
- const bundledPath = resolve31(bundledDir, filename);
26552
+ const overridePath = resolve32(overrideDir, filename);
26553
+ const bundledPath = resolve32(bundledDir, filename);
26458
26554
  const row = await readAgentTemplateRow({
26459
26555
  id: `agent-template:specialist:${filename}`,
26460
26556
  displayName: filename.replace(/\.md$/, ""),
@@ -26471,7 +26567,7 @@ async function fetchAgentTemplateRows(accountDir) {
26471
26567
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
26472
26568
  const names = /* @__PURE__ */ new Set();
26473
26569
  for (const dir of [overrideDir, bundledDir]) {
26474
- if (!existsSync39(dir)) continue;
26570
+ if (!existsSync38(dir)) continue;
26475
26571
  try {
26476
26572
  const entries2 = await readdir5(dir);
26477
26573
  for (const entry2 of entries2) {
@@ -26486,7 +26582,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
26486
26582
  }
26487
26583
  async function readAgentTemplateRow(inp) {
26488
26584
  let chosenPath = null;
26489
- if (existsSync39(inp.overridePath)) {
26585
+ if (existsSync38(inp.overridePath)) {
26490
26586
  try {
26491
26587
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
26492
26588
  chosenPath = inp.overridePath;
@@ -26497,7 +26593,7 @@ async function readAgentTemplateRow(inp) {
26497
26593
  );
26498
26594
  return null;
26499
26595
  }
26500
- } else if (existsSync39(inp.bundledPath)) {
26596
+ } else if (existsSync38(inp.bundledPath)) {
26501
26597
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
26502
26598
  console.error(
26503
26599
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -26957,24 +27053,24 @@ init_session_store();
26957
27053
  import { randomUUID as randomUUID9 } from "crypto";
26958
27054
 
26959
27055
  // server/wa-descriptor.ts
26960
- import { resolve as resolve32, join as join46 } from "path";
27056
+ import { resolve as resolve33, join as join46 } from "path";
26961
27057
  function waGatewayUrl() {
26962
27058
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26963
27059
  }
26964
27060
  function waServerPath() {
26965
- return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve32(process.env.MAXY_PLATFORM_ROOT ?? join46(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
27061
+ return process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join46(__dirname, ".."), "services/whatsapp-channel/dist/server.js");
26966
27062
  }
26967
27063
  function waChannelDescriptor(senderId) {
26968
27064
  return { senderId, gatewayUrl: waGatewayUrl(), serverPath: waServerPath() };
26969
27065
  }
26970
27066
 
26971
27067
  // server/telegram-descriptor.ts
26972
- import { resolve as resolve33, join as join47 } from "path";
27068
+ import { resolve as resolve34, join as join47 } from "path";
26973
27069
  function telegramGatewayUrl() {
26974
27070
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26975
27071
  }
26976
27072
  function telegramServerPath() {
26977
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/telegram-channel/dist/server.js");
27073
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join47(__dirname, ".."), "services/telegram-channel/dist/server.js");
26978
27074
  }
26979
27075
  function telegramChannelDescriptor(senderId) {
26980
27076
  return { senderId, gatewayUrl: telegramGatewayUrl(), serverPath: telegramServerPath() };
@@ -27270,23 +27366,23 @@ var system_stats_default = app44;
27270
27366
  // server/routes/admin/health.ts
27271
27367
  init_dist();
27272
27368
  init_neo4j_store();
27273
- import { existsSync as existsSync40, readFileSync as readFileSync39 } from "fs";
27274
- import { resolve as resolve34, join as join48 } from "path";
27275
- var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve34(process.cwd(), "..");
27369
+ import { existsSync as existsSync39, readFileSync as readFileSync39 } from "fs";
27370
+ import { resolve as resolve35, join as join48 } from "path";
27371
+ var PLATFORM_ROOT4 = process.env.MAXY_PLATFORM_ROOT ?? resolve35(process.cwd(), "..");
27276
27372
  var brandHostname = "maxy";
27277
27373
  var brandJsonPath = join48(PLATFORM_ROOT4, "config", "brand.json");
27278
- if (existsSync40(brandJsonPath)) {
27374
+ if (existsSync39(brandJsonPath)) {
27279
27375
  try {
27280
27376
  const brand = JSON.parse(readFileSync39(brandJsonPath, "utf-8"));
27281
27377
  if (brand.hostname) brandHostname = brand.hostname;
27282
27378
  } catch {
27283
27379
  }
27284
27380
  }
27285
- var VERSION_FILE = resolve34(PLATFORM_ROOT4, `config/.${brandHostname}-version`);
27381
+ var VERSION_FILE = resolve35(PLATFORM_ROOT4, `config/.${brandHostname}-version`);
27286
27382
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
27287
27383
  var PROBE_TIMEOUT_MS = 1e3;
27288
27384
  function readVersion() {
27289
- if (!existsSync40(VERSION_FILE)) return "unknown";
27385
+ if (!existsSync39(VERSION_FILE)) return "unknown";
27290
27386
  return readFileSync39(VERSION_FILE, "utf-8").trim() || "unknown";
27291
27387
  }
27292
27388
  async function probeConversationDb() {
@@ -27343,17 +27439,17 @@ import { randomUUID as randomUUID10 } from "crypto";
27343
27439
 
27344
27440
  // ../lib/account-ingest-token/src/index.ts
27345
27441
  import { randomBytes, timingSafeEqual as timingSafeEqual2 } from "crypto";
27346
- import { existsSync as existsSync41, readdirSync as readdirSync25, readFileSync as readFileSync40, writeFileSync as writeFileSync16 } from "fs";
27347
- import { resolve as resolve35 } from "path";
27442
+ import { existsSync as existsSync40, readdirSync as readdirSync25, readFileSync as readFileSync40, writeFileSync as writeFileSync16 } from "fs";
27443
+ import { resolve as resolve36 } from "path";
27348
27444
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27349
27445
  var INGEST_TOKEN_FIELD = "ingestToken";
27350
27446
  var TOKEN_RE = /^[0-9a-f]{64}$/;
27351
27447
  function configPath2(accountsDir, accountId) {
27352
- return resolve35(accountsDir, accountId, "account.json");
27448
+ return resolve36(accountsDir, accountId, "account.json");
27353
27449
  }
27354
27450
  function readConfig2(accountsDir, accountId) {
27355
27451
  const path = configPath2(accountsDir, accountId);
27356
- if (!existsSync41(path)) return null;
27452
+ if (!existsSync40(path)) return null;
27357
27453
  try {
27358
27454
  const parsed = JSON.parse(readFileSync40(path, "utf-8"));
27359
27455
  return parsed !== null && typeof parsed === "object" ? parsed : null;
@@ -27366,7 +27462,7 @@ function readIngestToken(accountsDir, accountId) {
27366
27462
  return typeof value === "string" && TOKEN_RE.test(value) ? value : null;
27367
27463
  }
27368
27464
  function listAccountIdsOnDisk(accountsDir) {
27369
- if (!existsSync41(accountsDir)) return [];
27465
+ if (!existsSync40(accountsDir)) return [];
27370
27466
  let entries2;
27371
27467
  try {
27372
27468
  entries2 = readdirSync25(accountsDir);
@@ -27374,7 +27470,7 @@ function listAccountIdsOnDisk(accountsDir) {
27374
27470
  return [];
27375
27471
  }
27376
27472
  return entries2.filter(
27377
- (name) => UUID_RE4.test(name) && existsSync41(resolve35(accountsDir, name, "account.json"))
27473
+ (name) => UUID_RE4.test(name) && existsSync40(resolve36(accountsDir, name, "account.json"))
27378
27474
  );
27379
27475
  }
27380
27476
  function resolveAccountIdByIngestToken(accountsDir, token) {
@@ -28229,7 +28325,7 @@ init_helpers();
28229
28325
  init_claude_agent();
28230
28326
  init_account_scope();
28231
28327
  init_neo4j_store();
28232
- import { existsSync as existsSync42 } from "fs";
28328
+ import { existsSync as existsSync41 } from "fs";
28233
28329
  import { randomUUID as randomUUID11 } from "crypto";
28234
28330
  import { join as join50 } from "path";
28235
28331
 
@@ -28899,7 +28995,7 @@ app53.get("/booking-link", requireAdminSession, (c) => {
28899
28995
  }
28900
28996
  const id82 = account.accountId.slice(0, 8);
28901
28997
  try {
28902
- if (!existsSync42(join50(account.accountDir, AVAILABILITY_FILENAME))) {
28998
+ if (!existsSync41(join50(account.accountDir, AVAILABILITY_FILENAME))) {
28903
28999
  console.log(`[calendar] op=booking-link accountId=${id82} bookingDomain=none source=availability-config`);
28904
29000
  return c.json({ bookingDomain: null });
28905
29001
  }
@@ -28921,7 +29017,7 @@ var calendar_default = app53;
28921
29017
  init_dist();
28922
29018
  init_helpers();
28923
29019
  init_account_scope();
28924
- import { existsSync as existsSync43, readFileSync as readFileSync42 } from "fs";
29020
+ import { existsSync as existsSync42, readFileSync as readFileSync42 } from "fs";
28925
29021
  import { join as join51 } from "path";
28926
29022
  var app54 = new Hono();
28927
29023
  var PORTAL_FILENAME = "data-portal.json";
@@ -28934,7 +29030,7 @@ app54.get("/portal-link", requireAdminSession, (c) => {
28934
29030
  const id82 = account.accountId.slice(0, 8);
28935
29031
  try {
28936
29032
  const path = join51(account.accountDir, PORTAL_FILENAME);
28937
- if (!existsSync43(path)) {
29033
+ if (!existsSync42(path)) {
28938
29034
  console.log(`[data-portal] op=portal-link accountId=${id82} portalDomain=none source=data-portal-config`);
28939
29035
  return c.json({ portalDomain: null });
28940
29036
  }
@@ -28960,11 +29056,11 @@ init_src2();
28960
29056
  import cronParser from "cron-parser";
28961
29057
  import { int as int2 } from "neo4j-driver";
28962
29058
  import { readFileSync as readFileSync44 } from "fs";
28963
- import { resolve as resolve37 } from "path";
29059
+ import { resolve as resolve38 } from "path";
28964
29060
 
28965
29061
  // ../lib/agent-dispatch-rule/src/index.ts
28966
29062
  import { readFileSync as readFileSync43 } from "fs";
28967
- import { resolve as resolve36 } from "path";
29063
+ import { resolve as resolve37 } from "path";
28968
29064
  function normalizeE1642(value) {
28969
29065
  let candidate = value.trim().replace(/[\s\-().]/g, "");
28970
29066
  candidate = candidate.replace(/^whatsapp:/i, "");
@@ -28981,7 +29077,7 @@ function phonesMatch2(a, b) {
28981
29077
  function readChannelAdmins(accountDir, channel) {
28982
29078
  let config = {};
28983
29079
  try {
28984
- config = JSON.parse(readFileSync43(resolve36(accountDir, "account.json"), "utf-8"));
29080
+ config = JSON.parse(readFileSync43(resolve37(accountDir, "account.json"), "utf-8"));
28985
29081
  } catch {
28986
29082
  config = {};
28987
29083
  }
@@ -29038,7 +29134,7 @@ function boundSubAccountFor(accountDir, destination) {
29038
29134
  }
29039
29135
  function validateAgentDestination(accountsDir, houseAccountId, creatingAccountId, channel, destination) {
29040
29136
  if (channel === "whatsapp") {
29041
- const houseDir = resolve36(accountsDir, houseAccountId);
29137
+ const houseDir = resolve37(accountsDir, houseAccountId);
29042
29138
  const registered = registeredAccountForDestination(houseDir, houseAccountId, destination);
29043
29139
  if (registered === null) return { valid: false, reason: "not-registered" };
29044
29140
  if (creatingAccountId === houseAccountId) return { valid: true };
@@ -29050,7 +29146,7 @@ function validateAgentDestination(accountsDir, houseAccountId, creatingAccountId
29050
29146
  scheduleAccount: creatingAccountId
29051
29147
  };
29052
29148
  }
29053
- const { adminUsers } = readChannelAdmins(resolve36(accountsDir, creatingAccountId), "telegram");
29149
+ const { adminUsers } = readChannelAdmins(resolve37(accountsDir, creatingAccountId), "telegram");
29054
29150
  const asNumber = Number(destination);
29055
29151
  const ok2 = Number.isInteger(asNumber) && adminUsers.includes(asNumber);
29056
29152
  return ok2 ? { valid: true } : { valid: false, reason: "not-registered" };
@@ -29060,7 +29156,7 @@ function listDispatchDestinations(input) {
29060
29156
  const managers = [];
29061
29157
  const admins = [];
29062
29158
  if (houseAccountId !== null) {
29063
- const houseDir = resolve36(accountsDir, houseAccountId);
29159
+ const houseDir = resolve37(accountsDir, houseAccountId);
29064
29160
  const { adminPhones, accountManagers } = readChannelAdmins(houseDir, "whatsapp");
29065
29161
  const seen = /* @__PURE__ */ new Set();
29066
29162
  for (const [phone, subAccountId] of Object.entries(accountManagers)) {
@@ -29078,7 +29174,7 @@ function listDispatchDestinations(input) {
29078
29174
  admins.push({ channel: "whatsapp", destination: phone, label: "House admin" });
29079
29175
  }
29080
29176
  }
29081
- const { byBot: byBot2 } = readChannelAdmins(resolve36(accountsDir, accountId), "telegram");
29177
+ const { byBot: byBot2 } = readChannelAdmins(resolve37(accountsDir, accountId), "telegram");
29082
29178
  const telegram = byBot2.flatMap((b) => b.adminUsers.map((id) => ({ botId: b.botId, id }))).sort((a, b) => a.id - b.id || a.botId.localeCompare(b.botId)).map(({ botId, id }) => ({
29083
29179
  channel: "telegram",
29084
29180
  destination: String(id),
@@ -29135,7 +29231,7 @@ function gateClassification(row) {
29135
29231
  return typeof row.gateWaived === "string" && row.gateWaived.trim() !== "";
29136
29232
  }
29137
29233
  function gateWatermarkPath(eventId) {
29138
- return resolve37(PLATFORM_ROOT, "..", "state", "scheduling-gate", `${eventId}.json`);
29234
+ return resolve38(PLATFORM_ROOT, "..", "state", "scheduling-gate", `${eventId}.json`);
29139
29235
  }
29140
29236
  function readGateLastCommitAt(eventId) {
29141
29237
  try {
@@ -29968,8 +30064,8 @@ init_dist();
29968
30064
  init_helpers();
29969
30065
  init_account_scope();
29970
30066
  init_route_cache();
29971
- import { existsSync as existsSync44, readdirSync as readdirSync26, readFileSync as readFileSync45, rmSync as rmSync6 } from "fs";
29972
- import { resolve as resolve38 } from "path";
30067
+ import { existsSync as existsSync43, readdirSync as readdirSync26, readFileSync as readFileSync45, rmSync as rmSync6 } from "fs";
30068
+ import { resolve as resolve39 } from "path";
29973
30069
  var app56 = new Hono();
29974
30070
  var NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
29975
30071
  function splitSkillMd(text) {
@@ -29992,7 +30088,7 @@ function stripQuotes(s) {
29992
30088
  return s;
29993
30089
  }
29994
30090
  function subdirs2(dir) {
29995
- if (!existsSync44(dir)) return [];
30091
+ if (!existsSync43(dir)) return [];
29996
30092
  try {
29997
30093
  return readdirSync26(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
29998
30094
  } catch {
@@ -30007,19 +30103,19 @@ app56.get("/", requireAdminSession, async (c) => {
30007
30103
  }
30008
30104
  ensureAccountWatchers(acct.accountId, acct.accountDir);
30009
30105
  const { value, state } = await getOrCompute("skills", acct.accountId, async () => {
30010
- const pluginsDir = resolve38(acct.accountDir, "plugins");
30106
+ const pluginsDir = resolve39(acct.accountDir, "plugins");
30011
30107
  const skills = [];
30012
30108
  let pluginCount = 0;
30013
30109
  for (const plugin of subdirs2(pluginsDir)) {
30014
30110
  pluginCount++;
30015
- const skillsDir = resolve38(pluginsDir, plugin, "skills");
30111
+ const skillsDir = resolve39(pluginsDir, plugin, "skills");
30016
30112
  for (const skill of subdirs2(skillsDir)) {
30017
- const skillMd = resolve38(skillsDir, skill, "SKILL.md");
30018
- if (!existsSync44(skillMd)) continue;
30113
+ const skillMd = resolve39(skillsDir, skill, "SKILL.md");
30114
+ if (!existsSync43(skillMd)) continue;
30019
30115
  try {
30020
30116
  const { frontmatter } = splitSkillMd(readFileSync45(skillMd, "utf-8"));
30021
- const refsDir = resolve38(skillsDir, skill, "references");
30022
- const refCount = existsSync44(refsDir) ? readdirSync26(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
30117
+ const refsDir = resolve39(skillsDir, skill, "references");
30118
+ const refCount = existsSync43(refsDir) ? readdirSync26(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).length : 0;
30023
30119
  skills.push({ plugin, skill, description: frontmatter.description, refCount });
30024
30120
  } catch (err) {
30025
30121
  console.error(`[admin:skills] op=list-skip plugin=${plugin} skill=${skill} reason="${err instanceof Error ? err.message : String(err)}"`);
@@ -30041,15 +30137,15 @@ app56.get("/:plugin/:skill", requireAdminSession, async (c) => {
30041
30137
  console.error(`[admin:skills] op=get outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
30042
30138
  return c.json({ error: "Invalid plugin or skill name" }, 400);
30043
30139
  }
30044
- const skillDir = resolve38(acct.accountDir, "plugins", plugin, "skills", skill);
30045
- const skillMd = resolve38(skillDir, "SKILL.md");
30046
- const found = existsSync44(skillMd);
30140
+ const skillDir = resolve39(acct.accountDir, "plugins", plugin, "skills", skill);
30141
+ const skillMd = resolve39(skillDir, "SKILL.md");
30142
+ const found = existsSync43(skillMd);
30047
30143
  console.log(`[admin:skills] op=get plugin=${plugin} skill=${skill} found=${found}`);
30048
30144
  if (!found) return c.json({ error: "Skill not found" }, 404);
30049
30145
  try {
30050
30146
  const { frontmatter, body } = splitSkillMd(readFileSync45(skillMd, "utf-8"));
30051
- const refsDir = resolve38(skillDir, "references");
30052
- const references = existsSync44(refsDir) ? readdirSync26(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
30147
+ const refsDir = resolve39(skillDir, "references");
30148
+ const references = existsSync43(refsDir) ? readdirSync26(refsDir, { withFileTypes: true }).filter((e) => e.isFile()).map((e) => e.name).sort() : [];
30053
30149
  return c.json({ skill: { plugin, skill, frontmatter, body, references } });
30054
30150
  } catch (err) {
30055
30151
  const message = err instanceof Error ? err.message : String(err);
@@ -30066,10 +30162,10 @@ app56.delete("/:plugin/:skill", requireAdminSession, async (c) => {
30066
30162
  console.error(`[admin:skills] op=delete outcome=rejected reason=invalid-name plugin="${plugin}" skill="${skill}"`);
30067
30163
  return c.json({ error: "Invalid plugin or skill name" }, 400);
30068
30164
  }
30069
- const pluginDir = resolve38(acct.accountDir, "plugins", plugin);
30070
- const skillsDir = resolve38(pluginDir, "skills");
30071
- const skillDir = resolve38(skillsDir, skill);
30072
- if (!existsSync44(resolve38(skillDir, "SKILL.md"))) {
30165
+ const pluginDir = resolve39(acct.accountDir, "plugins", plugin);
30166
+ const skillsDir = resolve39(pluginDir, "skills");
30167
+ const skillDir = resolve39(skillsDir, skill);
30168
+ if (!existsSync43(resolve39(skillDir, "SKILL.md"))) {
30073
30169
  console.error(`[admin:skills] op=delete outcome=rejected reason=not-found plugin=${plugin} skill=${skill}`);
30074
30170
  return c.json({ error: "Skill not found" }, 404);
30075
30171
  }
@@ -30077,7 +30173,7 @@ app56.delete("/:plugin/:skill", requireAdminSession, async (c) => {
30077
30173
  rmSync6(skillDir, { recursive: true, force: true });
30078
30174
  const pluginDirRemoved = subdirs2(skillsDir).length === 0;
30079
30175
  if (pluginDirRemoved) rmSync6(pluginDir, { recursive: true, force: true });
30080
- const skillDirGone = !existsSync44(skillDir);
30176
+ const skillDirGone = !existsSync43(skillDir);
30081
30177
  if (!skillDirGone) {
30082
30178
  console.error(`[admin:skills] op=delete plugin=${plugin} skill=${skill} outcome=rejected reason=rm-incomplete skillDirGone=false`);
30083
30179
  return c.json({ error: "Delete did not remove the skill directory" }, 503);
@@ -30721,8 +30817,8 @@ init_neo4j_store();
30721
30817
  // app/lib/admin-roster.ts
30722
30818
  init_account();
30723
30819
  init_neo4j_store();
30724
- import { existsSync as existsSync45, readdirSync as readdirSync27, readFileSync as readFileSync46 } from "fs";
30725
- import { resolve as resolve39 } from "path";
30820
+ import { existsSync as existsSync44, readdirSync as readdirSync27, readFileSync as readFileSync46 } from "fs";
30821
+ import { resolve as resolve40 } from "path";
30726
30822
  function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
30727
30823
  let entries2;
30728
30824
  try {
@@ -30731,8 +30827,8 @@ function readHouseAdminUserIds(accountsDir = ACCOUNTS_DIR) {
30731
30827
  return [];
30732
30828
  }
30733
30829
  for (const entry2 of entries2) {
30734
- const cfgPath = resolve39(accountsDir, entry2, "account.json");
30735
- if (!existsSync45(cfgPath)) continue;
30830
+ const cfgPath = resolve40(accountsDir, entry2, "account.json");
30831
+ if (!existsSync44(cfgPath)) continue;
30736
30832
  try {
30737
30833
  const cfg = JSON.parse(readFileSync46(cfgPath, "utf-8"));
30738
30834
  if (cfg.role !== "house") continue;
@@ -31082,7 +31178,7 @@ init_claude_agent();
31082
31178
  init_account();
31083
31179
  init_neo4j_store();
31084
31180
  init_src2();
31085
- import { resolve as resolve40 } from "path";
31181
+ import { resolve as resolve41 } from "path";
31086
31182
  var TAG49 = "[admin:routines]";
31087
31183
  function scopeFor(d, houseDir, houseAccountId) {
31088
31184
  if (d.channel !== "whatsapp") return null;
@@ -31112,7 +31208,7 @@ app67.get("/", requireAdminSession, async (c) => {
31112
31208
  console.error(`${TAG49} op=destinations account=${accountId.slice(0, 8)} outcome=house-unresolved reason="${message}"`);
31113
31209
  }
31114
31210
  const destinations = listDispatchDestinations({ accountsDir: ACCOUNTS_DIR, houseAccountId, accountId });
31115
- const houseDir = houseAccountId === null ? null : resolve40(ACCOUNTS_DIR, houseAccountId);
31211
+ const houseDir = houseAccountId === null ? null : resolve41(ACCOUNTS_DIR, houseAccountId);
31116
31212
  const byScope = /* @__PURE__ */ new Map();
31117
31213
  for (const d of destinations) {
31118
31214
  const scope = houseDir === null || houseAccountId === null ? null : scopeFor(d, houseDir, houseAccountId);
@@ -31462,9 +31558,9 @@ init_dist();
31462
31558
 
31463
31559
  // app/lib/access-email.ts
31464
31560
  import { spawn as spawn2 } from "child_process";
31465
- import { resolve as resolve41 } from "path";
31466
- var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve41(process.cwd(), "..");
31467
- var SEND_SCRIPT = resolve41(
31561
+ import { resolve as resolve42 } from "path";
31562
+ var PLATFORM_ROOT5 = process.env.MAXY_PLATFORM_ROOT ?? resolve42(process.cwd(), "..");
31563
+ var SEND_SCRIPT = resolve42(
31468
31564
  PLATFORM_ROOT5,
31469
31565
  "plugins",
31470
31566
  "email",
@@ -31608,8 +31704,8 @@ var access_default = app72;
31608
31704
  // server/routes/sites.ts
31609
31705
  init_dist();
31610
31706
  init_claude_agent();
31611
- import { existsSync as existsSync46, readFileSync as readFileSync47, realpathSync as realpathSync8, statSync as statSync25 } from "fs";
31612
- import { resolve as resolve42 } from "path";
31707
+ import { existsSync as existsSync45, readFileSync as readFileSync47, realpathSync as realpathSync8, statSync as statSync25 } from "fs";
31708
+ import { resolve as resolve43 } from "path";
31613
31709
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
31614
31710
  var MIME = {
31615
31711
  ".html": "text/html; charset=utf-8",
@@ -31666,15 +31762,15 @@ app73.get("/:rel{.*}", (c) => {
31666
31762
  }
31667
31763
  segments.push(seg);
31668
31764
  }
31669
- const rootDir = resolve42(account.accountDir, "sites");
31670
- let filePath = segments.length === 0 ? rootDir : resolve42(rootDir, ...segments);
31765
+ const rootDir = resolve43(account.accountDir, "sites");
31766
+ let filePath = segments.length === 0 ? rootDir : resolve43(rootDir, ...segments);
31671
31767
  if (filePath !== rootDir && !filePath.startsWith(rootDir + "/")) {
31672
31768
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
31673
31769
  return c.text("Forbidden", 403);
31674
31770
  }
31675
31771
  let stat11;
31676
31772
  try {
31677
- stat11 = existsSync46(filePath) ? statSync25(filePath) : null;
31773
+ stat11 = existsSync45(filePath) ? statSync25(filePath) : null;
31678
31774
  } catch {
31679
31775
  stat11 = null;
31680
31776
  }
@@ -31687,13 +31783,13 @@ app73.get("/:rel{.*}", (c) => {
31687
31783
  return c.redirect(target, 301);
31688
31784
  }
31689
31785
  if (stat11?.isDirectory()) {
31690
- filePath = resolve42(filePath, "index.html");
31786
+ filePath = resolve43(filePath, "index.html");
31691
31787
  }
31692
31788
  if (!filePath.startsWith(rootDir + "/")) {
31693
31789
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
31694
31790
  return c.text("Forbidden", 403);
31695
31791
  }
31696
- if (!existsSync46(filePath)) {
31792
+ if (!existsSync45(filePath)) {
31697
31793
  console.error(`[sites] not-found path=${reqPath} status=404`);
31698
31794
  return c.text("Not found", 404);
31699
31795
  }
@@ -31833,7 +31929,7 @@ var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
31833
31929
  init_dist();
31834
31930
 
31835
31931
  // app/lib/brand-config.ts
31836
- import { existsSync as existsSync47, readFileSync as readFileSync49 } from "fs";
31932
+ import { existsSync as existsSync46, readFileSync as readFileSync49 } from "fs";
31837
31933
  import { join as join53 } from "path";
31838
31934
  var cached2 = null;
31839
31935
  var cachedAttempted = false;
@@ -31843,7 +31939,7 @@ function readBrandConfig() {
31843
31939
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
31844
31940
  if (!platformRoot5) return null;
31845
31941
  const brandPath = join53(platformRoot5, "config", "brand.json");
31846
- if (!existsSync47(brandPath)) return null;
31942
+ if (!existsSync46(brandPath)) return null;
31847
31943
  try {
31848
31944
  cached2 = JSON.parse(readFileSync49(brandPath, "utf-8"));
31849
31945
  return cached2;
@@ -32348,16 +32444,16 @@ var visitor_event_default = app76;
32348
32444
  // server/routes/session.ts
32349
32445
  init_dist();
32350
32446
  init_claude_agent();
32351
- import { resolve as resolve43 } from "path";
32352
- import { existsSync as existsSync48, writeFileSync as writeFileSync18, mkdirSync as mkdirSync10 } from "fs";
32447
+ import { resolve as resolve44 } from "path";
32448
+ import { existsSync as existsSync47, writeFileSync as writeFileSync18, mkdirSync as mkdirSync10 } from "fs";
32353
32449
  init_neo4j_store();
32354
32450
  init_paths();
32355
32451
  var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
32356
32452
  function writeBrandingCache(accountId, agentSlug, branding) {
32357
32453
  try {
32358
- const cacheDir = resolve43(MAXY_DIR, "branding-cache", accountId);
32454
+ const cacheDir = resolve44(MAXY_DIR, "branding-cache", accountId);
32359
32455
  mkdirSync10(cacheDir, { recursive: true });
32360
- writeFileSync18(resolve43(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
32456
+ writeFileSync18(resolve44(cacheDir, `${agentSlug}.json`), JSON.stringify(branding), "utf-8");
32361
32457
  } catch (err) {
32362
32458
  console.error(`[branding] cache write failed: ${err instanceof Error ? err.message : String(err)}`);
32363
32459
  }
@@ -32438,8 +32534,8 @@ app77.post("/", async (c) => {
32438
32534
  }
32439
32535
  let agentConfig = null;
32440
32536
  if (account) {
32441
- const agentDir = resolve43(account.accountDir, "agents", agentSlug);
32442
- if (!existsSync48(agentDir) || !existsSync48(resolve43(agentDir, "config.json"))) {
32537
+ const agentDir = resolve44(account.accountDir, "agents", agentSlug);
32538
+ if (!existsSync47(agentDir) || !existsSync47(resolve44(agentDir, "config.json"))) {
32443
32539
  return c.json({ error: "Agent not found" }, 404);
32444
32540
  }
32445
32541
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -32623,7 +32719,7 @@ var calendar_public_default = app78;
32623
32719
  init_dist();
32624
32720
  import { createReadStream as createReadStream3 } from "fs";
32625
32721
  import { stat as stat8, readFile as readFile11, realpath } from "fs/promises";
32626
- import { join as join54, resolve as resolve44, sep as sep11 } from "path";
32722
+ import { join as join54, resolve as resolve45, sep as sep11 } from "path";
32627
32723
  import { Readable as Readable3 } from "stream";
32628
32724
  init_data_path();
32629
32725
  init_attachments();
@@ -32678,7 +32774,7 @@ ${expiresAtMs}`)
32678
32774
  return diff2 === 0;
32679
32775
  }
32680
32776
  async function readAccountSecret(accountId) {
32681
- const path = resolve44(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
32777
+ const path = resolve45(DATA_ROOT, "accounts", accountId, "secrets", "data-portal.env");
32682
32778
  let text;
32683
32779
  try {
32684
32780
  text = await readFile11(path, "utf8");
@@ -32714,7 +32810,7 @@ async function resolveFetchTarget(accountDir, relPath, ownerId) {
32714
32810
  const exposeFolders = await readExposeFolders2(accountDir);
32715
32811
  const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
32716
32812
  if (exposed.length === 0 && !ownerId) return { ok: false, reason: "not-exposed" };
32717
- const lexical = resolve44(accountDir, relPath);
32813
+ const lexical = resolve45(accountDir, relPath);
32718
32814
  let root;
32719
32815
  let absolute;
32720
32816
  try {
@@ -32763,7 +32859,7 @@ async function handle(c, headOnly) {
32763
32859
  return c.json({ ok: false, error: "denied" }, 401);
32764
32860
  }
32765
32861
  const target = await resolveFetchTarget(
32766
- resolve44(DATA_ROOT, "accounts", accountId),
32862
+ resolve45(DATA_ROOT, "accounts", accountId),
32767
32863
  relPath,
32768
32864
  owner || void 0
32769
32865
  );
@@ -33496,7 +33592,7 @@ function startGraphHealthTimer() {
33496
33592
  init_loop_registry();
33497
33593
  init_data_path();
33498
33594
  var import_dist11 = __toESM(require_dist(), 1);
33499
- import { existsSync as existsSync49, statSync as statSync27, readdirSync as readdirSync30 } from "fs";
33595
+ import { existsSync as existsSync48, statSync as statSync27, readdirSync as readdirSync30 } from "fs";
33500
33596
  import { join as join57 } from "path";
33501
33597
  var TAG57 = "[shared-census]";
33502
33598
  var WIRED_SURFACES = 3;
@@ -33516,7 +33612,7 @@ function countFiles(dir) {
33516
33612
  }
33517
33613
  function runSharedFolderCensus(dataRoot = DATA_ROOT) {
33518
33614
  const root = (0, import_dist11.sharedRoot)(dataRoot);
33519
- const exists = existsSync49(root);
33615
+ const exists = existsSync48(root);
33520
33616
  let isDir = false;
33521
33617
  if (exists) {
33522
33618
  try {
@@ -33542,7 +33638,7 @@ function startSharedFolderCensus() {
33542
33638
  // app/lib/file-watcher.ts
33543
33639
  init_data_path();
33544
33640
  import * as fsp2 from "fs/promises";
33545
- import { resolve as resolve45, sep as sep12 } from "path";
33641
+ import { resolve as resolve46, sep as sep12 } from "path";
33546
33642
  var ACCOUNT_UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
33547
33643
  var DEFAULT_COALESCE_MS = 500;
33548
33644
  var ROOTS = ["accounts"];
@@ -33561,7 +33657,7 @@ async function startFileWatcher(opts = {}) {
33561
33657
  const dropFn = opts.drop ?? dropFileIndex;
33562
33658
  for (const r of ROOTS) {
33563
33659
  try {
33564
- await fsp2.mkdir(resolve45(dataRoot, r), { recursive: true });
33660
+ await fsp2.mkdir(resolve46(dataRoot, r), { recursive: true });
33565
33661
  } catch (err) {
33566
33662
  console.error(
33567
33663
  `[file-watcher] start-failed root="${r}" err="${err.message}" \u2014 index will be maintained by the 5-min reconcile backstop only`
@@ -33582,7 +33678,7 @@ async function startFileWatcher(opts = {}) {
33582
33678
  timers.set(relativePath, t);
33583
33679
  }
33584
33680
  async function runHook(relativePath, accountId) {
33585
- const absolute = resolve45(dataRoot, relativePath);
33681
+ const absolute = resolve46(dataRoot, relativePath);
33586
33682
  let exists = false;
33587
33683
  try {
33588
33684
  const st = await fsp2.stat(absolute);
@@ -33606,7 +33702,7 @@ async function startFileWatcher(opts = {}) {
33606
33702
  }
33607
33703
  }
33608
33704
  async function watchRoot(rootName) {
33609
- const absRoot = resolve45(dataRoot, rootName);
33705
+ const absRoot = resolve46(dataRoot, rootName);
33610
33706
  try {
33611
33707
  const iter = fsp2.watch(absRoot, { recursive: true, signal: controller.signal });
33612
33708
  for await (const event of iter) {
@@ -33648,7 +33744,7 @@ init_data_path();
33648
33744
  init_neo4j_store();
33649
33745
  init_account();
33650
33746
  import { mkdir as mkdir5, readdir as readdir6, rename as rename4, rm as rm3 } from "fs/promises";
33651
- import { dirname as dirname17, relative as relative8, resolve as resolve46 } from "path";
33747
+ import { dirname as dirname17, relative as relative8, resolve as resolve47 } from "path";
33652
33748
  var ACCOUNT_UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
33653
33749
  async function walkFiles(dir) {
33654
33750
  const out = [];
@@ -33659,7 +33755,7 @@ async function walkFiles(dir) {
33659
33755
  return out;
33660
33756
  }
33661
33757
  for (const e of entries2) {
33662
- const abs = resolve46(dir, e.name);
33758
+ const abs = resolve47(dir, e.name);
33663
33759
  if (e.isDirectory()) {
33664
33760
  out.push(...await walkFiles(abs));
33665
33761
  } else if (e.isFile()) {
@@ -33679,7 +33775,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
33679
33775
  let moved = 0;
33680
33776
  for (const oldAbs of files) {
33681
33777
  const suffix = relative8(srcDir, oldAbs);
33682
- const newAbs = resolve46(destDir, suffix);
33778
+ const newAbs = resolve47(destDir, suffix);
33683
33779
  await mkdir5(dirname17(newAbs), { recursive: true });
33684
33780
  await rename4(oldAbs, newAbs);
33685
33781
  moved++;
@@ -33706,7 +33802,7 @@ async function relocateTree(srcDir, destDir, dataRoot, accountId, session) {
33706
33802
  }
33707
33803
  async function migrateUploads(opts = {}) {
33708
33804
  const dataRoot = opts.dataRoot ?? DATA_ROOT;
33709
- const oldRoot = resolve46(dataRoot, "uploads");
33805
+ const oldRoot = resolve47(dataRoot, "uploads");
33710
33806
  let topEntries;
33711
33807
  try {
33712
33808
  topEntries = await readdir6(oldRoot, { withFileTypes: true });
@@ -33727,8 +33823,8 @@ async function migrateUploads(opts = {}) {
33727
33823
  const name = entry2.name;
33728
33824
  if (ACCOUNT_UUID_RE4.test(name)) {
33729
33825
  moved += await relocateTree(
33730
- resolve46(oldRoot, name),
33731
- resolve46(dataRoot, "accounts", name, "uploads"),
33826
+ resolve47(oldRoot, name),
33827
+ resolve47(dataRoot, "accounts", name, "uploads"),
33732
33828
  dataRoot,
33733
33829
  name,
33734
33830
  session
@@ -33740,8 +33836,8 @@ async function migrateUploads(opts = {}) {
33740
33836
  continue;
33741
33837
  }
33742
33838
  moved += await relocateTree(
33743
- resolve46(oldRoot, "public"),
33744
- resolve46(dataRoot, "accounts", installAccountId, "uploads", "public"),
33839
+ resolve47(oldRoot, "public"),
33840
+ resolve47(dataRoot, "accounts", installAccountId, "uploads", "public"),
33745
33841
  dataRoot,
33746
33842
  null,
33747
33843
  // public uploads carry no graph nodes
@@ -33775,7 +33871,7 @@ init_pin_validator();
33775
33871
  init_account();
33776
33872
  init_neo4j_store();
33777
33873
  import { readdir as readdir7, readFile as readFile12, rename as rename5, writeFile as writeFile5, unlink as unlink4 } from "fs/promises";
33778
- import { existsSync as existsSync50 } from "fs";
33874
+ import { existsSync as existsSync49 } from "fs";
33779
33875
  import { join as join58 } from "path";
33780
33876
  var ADMIN_ROLE2 = "admin";
33781
33877
  var WEBCHAT_CHANNEL2 = "webchat";
@@ -33805,7 +33901,7 @@ async function writeRaw(path, obj) {
33805
33901
  await rename5(tmp, path);
33806
33902
  } catch (err) {
33807
33903
  try {
33808
- if (existsSync50(tmp)) await unlink4(tmp);
33904
+ if (existsSync49(tmp)) await unlink4(tmp);
33809
33905
  } catch {
33810
33906
  }
33811
33907
  throw err;
@@ -33929,7 +34025,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
33929
34025
  // app/lib/migrate-sidecar-account-ids.ts
33930
34026
  init_account();
33931
34027
  import { readdir as readdir8, readFile as readFile13, rename as rename6, writeFile as writeFile6, unlink as unlink5 } from "fs/promises";
33932
- import { existsSync as existsSync51 } from "fs";
34028
+ import { existsSync as existsSync50 } from "fs";
33933
34029
  import { join as join59 } from "path";
33934
34030
  var SESSION_META_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
33935
34031
  function projectSlugForCwd(cwd) {
@@ -33956,7 +34052,7 @@ async function writeRaw2(path, obj) {
33956
34052
  await rename6(tmp, path);
33957
34053
  } catch (err) {
33958
34054
  try {
33959
- if (existsSync51(tmp)) await unlink5(tmp);
34055
+ if (existsSync50(tmp)) await unlink5(tmp);
33960
34056
  } catch {
33961
34057
  }
33962
34058
  throw err;
@@ -35538,7 +35634,7 @@ function createWebchatChannelRoutes(deps) {
35538
35634
  }
35539
35635
 
35540
35636
  // app/lib/webchat/gateway/resolve-turn-answer.ts
35541
- import { existsSync as existsSync52, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, readdirSync as readdirSync31 } from "fs";
35637
+ import { existsSync as existsSync51, openSync as openSync9, readSync as readSync8, closeSync as closeSync9, readdirSync as readdirSync31 } from "fs";
35542
35638
  import { join as join60 } from "path";
35543
35639
  function resolveTurnAnswer(p) {
35544
35640
  if (!SESSION_ID_RE2.test(p.sessionId)) return "";
@@ -35567,7 +35663,7 @@ function resolveTurnAnswer(p) {
35567
35663
  return segmentText(parts.join("\n\n")).join("\n\n");
35568
35664
  }
35569
35665
  function findJsonl(projectsRoot, sessionId) {
35570
- if (!existsSync52(projectsRoot)) return null;
35666
+ if (!existsSync51(projectsRoot)) return null;
35571
35667
  let slugs;
35572
35668
  try {
35573
35669
  slugs = readdirSync31(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
@@ -35576,7 +35672,7 @@ function findJsonl(projectsRoot, sessionId) {
35576
35672
  }
35577
35673
  for (const slug of slugs) {
35578
35674
  const live = join60(projectsRoot, slug, `${sessionId}.jsonl`);
35579
- if (existsSync52(live)) return live;
35675
+ if (existsSync51(live)) return live;
35580
35676
  }
35581
35677
  return null;
35582
35678
  }
@@ -35644,16 +35740,16 @@ var WebchatGateway = class _WebchatGateway {
35644
35740
  * The public /api/chat route awaits this to return the reply on the same SSE
35645
35741
  * response, preserving the pre-756 POST→single-blob browser contract. */
35646
35742
  awaitReply(key2, timeoutMs) {
35647
- return new Promise((resolve52) => {
35743
+ return new Promise((resolve53) => {
35648
35744
  const timer = setTimeout(() => {
35649
35745
  this.replyAwaiters.delete(key2);
35650
- resolve52({ timeout: true });
35746
+ resolve53({ timeout: true });
35651
35747
  }, timeoutMs);
35652
35748
  if (timer.unref) timer.unref();
35653
35749
  this.replyAwaiters.set(key2, (r) => {
35654
35750
  clearTimeout(timer);
35655
35751
  this.replyAwaiters.delete(key2);
35656
- resolve52(r);
35752
+ resolve53(r);
35657
35753
  });
35658
35754
  });
35659
35755
  }
@@ -35664,11 +35760,11 @@ var WebchatGateway = class _WebchatGateway {
35664
35760
  * terminal dialog stays answerable). */
35665
35761
  awaitPermissionVerdict(p, timeoutMs) {
35666
35762
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
35667
- return new Promise((resolve52) => {
35763
+ return new Promise((resolve53) => {
35668
35764
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
35669
35765
  const timer = setTimeout(() => {
35670
35766
  this.pendingPrompts.delete(k);
35671
- resolve52({ timeout: true });
35767
+ resolve53({ timeout: true });
35672
35768
  }, timeoutMs);
35673
35769
  if (timer.unref) timer.unref();
35674
35770
  this.pendingPrompts.set(k, {
@@ -35678,7 +35774,7 @@ var WebchatGateway = class _WebchatGateway {
35678
35774
  clearTimeout(timer);
35679
35775
  this.pendingPrompts.delete(k);
35680
35776
  this.deps.onPointerChange?.(p.key);
35681
- resolve52(r);
35777
+ resolve53(r);
35682
35778
  }
35683
35779
  });
35684
35780
  console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
@@ -36459,7 +36555,7 @@ function parityCensusLines() {
36459
36555
 
36460
36556
  // app/lib/webchat/file-delivery.ts
36461
36557
  import { realpathSync as realpathSync9 } from "fs";
36462
- import { resolve as resolve47 } from "path";
36558
+ import { resolve as resolve48 } from "path";
36463
36559
 
36464
36560
  // app/lib/channel-pty-bridge/file-delivery.ts
36465
36561
  var SEND_USER_FILE = "SendUserFile";
@@ -36560,7 +36656,7 @@ function makeWebchatSendFile(entry2) {
36560
36656
  console.error(`${TAG58} file-delivery reject reason=no-account sender=${entry2.senderId}`);
36561
36657
  return { ok: false, error: "no-account" };
36562
36658
  }
36563
- const accountDir = resolve47(platformRoot2(), "..", "data/accounts", entry2.accountId);
36659
+ const accountDir = resolve48(platformRoot2(), "..", "data/accounts", entry2.accountId);
36564
36660
  try {
36565
36661
  const resolved = realpathSync9(filePath);
36566
36662
  const accountResolved = realpathSync9(accountDir);
@@ -37363,7 +37459,7 @@ function buildTelegramEnsureSession(deps) {
37363
37459
  init_attachments();
37364
37460
  import { realpathSync as realpathSync10 } from "fs";
37365
37461
  import { readFile as readFile14, stat as stat10 } from "fs/promises";
37366
- import { resolve as resolve48, basename as basename16 } from "path";
37462
+ import { resolve as resolve49, basename as basename16 } from "path";
37367
37463
  var TAG61 = "[telegram:outbound]";
37368
37464
  var TELEGRAM_DOCUMENT_MAX_BYTES = 50 * 1024 * 1024;
37369
37465
  async function sendTelegramDocument(input) {
@@ -37374,7 +37470,7 @@ async function sendTelegramDocument(input) {
37374
37470
  if (!maxyAccountId || !platformRoot5) {
37375
37471
  return { ok: false, status: 400, error: "Cannot validate file path: missing account or platform context" };
37376
37472
  }
37377
- const accountDir = resolve48(platformRoot5, "..", "data/accounts", maxyAccountId);
37473
+ const accountDir = resolve49(platformRoot5, "..", "data/accounts", maxyAccountId);
37378
37474
  let accountResolved;
37379
37475
  try {
37380
37476
  accountResolved = realpathSync10(accountDir);
@@ -37962,7 +38058,7 @@ function* walkTelegramSidecars() {
37962
38058
  }
37963
38059
 
37964
38060
  // server/telegram-migrate.ts
37965
- import { readFileSync as readFileSync52, writeFileSync as writeFileSync19, existsSync as existsSync53, renameSync as renameSync11, mkdirSync as mkdirSync11 } from "fs";
38061
+ import { readFileSync as readFileSync52, writeFileSync as writeFileSync19, existsSync as existsSync52, renameSync as renameSync11, mkdirSync as mkdirSync11 } from "fs";
37966
38062
  import { dirname as dirname18, join as join62 } from "path";
37967
38063
  function migrateTelegramTwoSlot(input) {
37968
38064
  const out = [];
@@ -38023,7 +38119,7 @@ function migrateTelegramTwoSlot(input) {
38023
38119
  return out;
38024
38120
  }
38025
38121
  function moveSecret(from, to) {
38026
- if (!existsSync53(from)) return;
38122
+ if (!existsSync52(from)) return;
38027
38123
  mkdirSync11(dirname18(to), { recursive: true, mode: 448 });
38028
38124
  renameSync11(from, to);
38029
38125
  }
@@ -38072,12 +38168,12 @@ function backfillMisfiledRecords(params) {
38072
38168
  init_message_store();
38073
38169
 
38074
38170
  // server/lib/booking-site-accounts.ts
38075
- import { existsSync as existsSync54, readFileSync as readFileSync53 } from "fs";
38076
- import { resolve as resolve49 } from "path";
38171
+ import { existsSync as existsSync53, readFileSync as readFileSync53 } from "fs";
38172
+ import { resolve as resolve50 } from "path";
38077
38173
  function listBookingSiteAccounts(accounts) {
38078
38174
  return accounts.filter((a) => {
38079
- const availPath = resolve49(a.accountDir, "calendar-availability.json");
38080
- if (!existsSync54(availPath)) return false;
38175
+ const availPath = resolve50(a.accountDir, "calendar-availability.json");
38176
+ if (!existsSync53(availPath)) return false;
38081
38177
  try {
38082
38178
  const cfg = JSON.parse(readFileSync53(availPath, "utf-8"));
38083
38179
  return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
@@ -38124,8 +38220,8 @@ init_paths();
38124
38220
 
38125
38221
  // ../lib/entitlement/src/index.ts
38126
38222
  import { createPublicKey, createHash as createHash7, verify as cryptoVerify } from "crypto";
38127
- import { existsSync as existsSync55, readFileSync as readFileSync54, statSync as statSync29 } from "fs";
38128
- import { resolve as resolve50 } from "path";
38223
+ import { existsSync as existsSync54, readFileSync as readFileSync54, statSync as statSync29 } from "fs";
38224
+ import { resolve as resolve51 } from "path";
38129
38225
 
38130
38226
  // ../lib/entitlement/src/canonicalize.ts
38131
38227
  function canonicalize(value) {
@@ -38160,7 +38256,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
38160
38256
  var GRACE_DAYS = 7;
38161
38257
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
38162
38258
  function pubkeyPath(brand) {
38163
- return resolve50(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
38259
+ return resolve51(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
38164
38260
  }
38165
38261
  var memo = null;
38166
38262
  function memoKey(mtimeMs, account) {
@@ -38172,8 +38268,8 @@ function resolveEntitlement(brand, account) {
38172
38268
  if (brand.commercialMode !== true) {
38173
38269
  return logResolved(implicitTrust(account), null);
38174
38270
  }
38175
- const entitlementPath = resolve50(brand.configDir, "entitlement.json");
38176
- if (!existsSync55(entitlementPath)) {
38271
+ const entitlementPath = resolve51(brand.configDir, "entitlement.json");
38272
+ if (!existsSync54(entitlementPath)) {
38177
38273
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
38178
38274
  }
38179
38275
  const stat11 = statSync29(entitlementPath);
@@ -38366,10 +38462,10 @@ installMediaDownloadGuard();
38366
38462
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
38367
38463
  var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join63(PLATFORM_ROOT6, "config", "brand.json") : "";
38368
38464
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
38369
- if (BRAND_JSON_PATH && !existsSync56(BRAND_JSON_PATH)) {
38465
+ if (BRAND_JSON_PATH && !existsSync55(BRAND_JSON_PATH)) {
38370
38466
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
38371
38467
  }
38372
- if (BRAND_JSON_PATH && existsSync56(BRAND_JSON_PATH)) {
38468
+ if (BRAND_JSON_PATH && existsSync55(BRAND_JSON_PATH)) {
38373
38469
  try {
38374
38470
  const parsed = JSON.parse(readFileSync55(BRAND_JSON_PATH, "utf-8"));
38375
38471
  BRAND = { ...BRAND, ...parsed };
@@ -38406,7 +38502,7 @@ var brandLoginOpts = {
38406
38502
  var ALIAS_DOMAINS_PATH = join63(homedir5(), BRAND.configDir, "alias-domains.json");
38407
38503
  function loadAliasDomains() {
38408
38504
  try {
38409
- if (!existsSync56(ALIAS_DOMAINS_PATH)) return null;
38505
+ if (!existsSync55(ALIAS_DOMAINS_PATH)) return null;
38410
38506
  const parsed = JSON.parse(readFileSync55(ALIAS_DOMAINS_PATH, "utf-8"));
38411
38507
  if (!Array.isArray(parsed)) {
38412
38508
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -38488,13 +38584,16 @@ registerLoop({
38488
38584
  return `${lines.length} session(s), ${missing} with a missing answer`;
38489
38585
  }
38490
38586
  });
38491
- var whatsappFanTargets = (accountId, senderId) => adminFanTargets({
38492
- origin: "whatsapp",
38493
- originKey: senderId,
38494
- accountId,
38495
- adminUserId: resolveAdminUserId({ accountId, senderPhone: senderId }),
38496
- deps: adminFanDeps("whatsapp", accountId)
38497
- });
38587
+ var whatsappFanTargets = (accountId, senderId) => {
38588
+ warnNonUuidAccount("fan-out", accountId);
38589
+ return adminFanTargets({
38590
+ origin: "whatsapp",
38591
+ originKey: senderId,
38592
+ accountId,
38593
+ adminUserId: resolveAdminUserId({ accountId, senderPhone: senderId }),
38594
+ deps: adminFanDeps("whatsapp", accountId)
38595
+ });
38596
+ };
38498
38597
  var waGateway = new WaGateway({
38499
38598
  fetchStandingRules: fetchAccountStandingRules,
38500
38599
  // Task 2321 — the account's own `## Instruction` body, read from that
@@ -38521,7 +38620,7 @@ var waGateway = new WaGateway({
38521
38620
  // resolver and `fanTargetsFor` is a constructor dep, not a callable method.
38522
38621
  fanTargetsFor: whatsappFanTargets,
38523
38622
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
38524
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve51(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
38623
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve52(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
38525
38624
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
38526
38625
  // path-validation scope) is the sender's effective SESSION account, resolved
38527
38626
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -38536,7 +38635,7 @@ var waGateway = new WaGateway({
38536
38635
  caption,
38537
38636
  accountId,
38538
38637
  maxyAccountId,
38539
- platformRoot: resolve51(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, ".."))
38638
+ platformRoot: resolve52(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, ".."))
38540
38639
  });
38541
38640
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
38542
38641
  },
@@ -38686,7 +38785,12 @@ var waGateway = new WaGateway({
38686
38785
  role,
38687
38786
  // Task 2521 — resolved per answer, not captured once, so a door that goes
38688
38787
  // live after this session started still receives.
38689
- fanTargets: () => whatsappFanTargets(accountId, senderId),
38788
+ // Task 2531 — `effectiveAccountId`, NOT `accountId`. The reply map is
38789
+ // keyed on the platform UUID (wa-gateway.ts:567) while `accountId` here is
38790
+ // the Baileys credential dirname (see the Task 1850 note above). Passing
38791
+ // the dirname missed every lookup and delivered session 8e5bc4e8's answer
38792
+ // to nothing. `accountId` stays correct on line 718: that is the socket.
38793
+ fanTargets: () => whatsappFanTargets(effectiveAccountId, senderId),
38690
38794
  onClose: () => {
38691
38795
  if (nativeFileFollowers.get(senderId) === ac) nativeFileFollowers.delete(senderId);
38692
38796
  }
@@ -39342,13 +39446,13 @@ app80.get("/agent-assets/:slug/:filename", (c) => {
39342
39446
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
39343
39447
  return c.text("Not found", 404);
39344
39448
  }
39345
- const filePath = resolve51(account.accountDir, "agents", slug, "assets", filename);
39346
- const expectedDir = resolve51(account.accountDir, "agents", slug, "assets");
39449
+ const filePath = resolve52(account.accountDir, "agents", slug, "assets", filename);
39450
+ const expectedDir = resolve52(account.accountDir, "agents", slug, "assets");
39347
39451
  if (!filePath.startsWith(expectedDir + "/")) {
39348
39452
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
39349
39453
  return c.text("Forbidden", 403);
39350
39454
  }
39351
- if (!existsSync56(filePath)) {
39455
+ if (!existsSync55(filePath)) {
39352
39456
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
39353
39457
  return c.text("Not found", 404);
39354
39458
  }
@@ -39372,13 +39476,13 @@ app80.get("/generated/:filename", (c) => {
39372
39476
  console.error(`[generated] serve file=${filename} status=404`);
39373
39477
  return c.text("Not found", 404);
39374
39478
  }
39375
- const filePath = resolve51(account.accountDir, "generated", filename);
39376
- const expectedDir = resolve51(account.accountDir, "generated");
39479
+ const filePath = resolve52(account.accountDir, "generated", filename);
39480
+ const expectedDir = resolve52(account.accountDir, "generated");
39377
39481
  if (!filePath.startsWith(expectedDir + "/")) {
39378
39482
  console.error(`[generated] serve file=${filename} status=403`);
39379
39483
  return c.text("Forbidden", 403);
39380
39484
  }
39381
- if (!existsSync56(filePath)) {
39485
+ if (!existsSync55(filePath)) {
39382
39486
  console.error(`[generated] serve file=${filename} status=404`);
39383
39487
  return c.text("Not found", 404);
39384
39488
  }
@@ -39398,7 +39502,7 @@ app80.route("/v", visitor_consent_default);
39398
39502
  var htmlCache = /* @__PURE__ */ new Map();
39399
39503
  var brandLogoPath = "/brand/maxy-monochrome.png";
39400
39504
  var brandIconPath = "/brand/maxy-monochrome.png";
39401
- if (BRAND_JSON_PATH && existsSync56(BRAND_JSON_PATH)) {
39505
+ if (BRAND_JSON_PATH && existsSync55(BRAND_JSON_PATH)) {
39402
39506
  try {
39403
39507
  const fullBrand = JSON.parse(readFileSync55(BRAND_JSON_PATH, "utf-8"));
39404
39508
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -39427,11 +39531,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
39427
39531
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
39428
39532
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
39429
39533
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
39430
- (p) => existsSync56(resolve51(process.cwd(), "public", p.replace(/^\//, "")))
39534
+ (p) => existsSync55(resolve52(process.cwd(), "public", p.replace(/^\//, "")))
39431
39535
  );
39432
39536
  var SW_SOURCE = (() => {
39433
39537
  try {
39434
- return readFileSync55(resolve51(process.cwd(), "public", "sw.js"), "utf-8");
39538
+ return readFileSync55(resolve52(process.cwd(), "public", "sw.js"), "utf-8");
39435
39539
  } catch {
39436
39540
  return null;
39437
39541
  }
@@ -39440,7 +39544,7 @@ function readInstalledVersion() {
39440
39544
  try {
39441
39545
  if (!PLATFORM_ROOT6) return "unknown";
39442
39546
  const versionFile = join63(PLATFORM_ROOT6, "config", `.${BRAND.hostname}-version`);
39443
- if (!existsSync56(versionFile)) return "unknown";
39547
+ if (!existsSync55(versionFile)) return "unknown";
39444
39548
  const content = readFileSync55(versionFile, "utf-8").trim();
39445
39549
  return content || "unknown";
39446
39550
  } catch {
@@ -39452,7 +39556,7 @@ var versionScript = `<script>window.__MAXY_VERSION__=${JSON.stringify(INSTALLED_
39452
39556
  function cachedHtml(file) {
39453
39557
  let html = htmlCache.get(file);
39454
39558
  if (!html) {
39455
- html = readFileSync55(resolve51(process.cwd(), "public", file), "utf-8");
39559
+ html = readFileSync55(resolve52(process.cwd(), "public", file), "utf-8");
39456
39560
  const productNameEsc = escapeHtml(BRAND.productName);
39457
39561
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
39458
39562
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -39475,7 +39579,7 @@ function loadBrandingCache(agentSlug) {
39475
39579
  const accountId = verdict.kind === "served" ? verdict.owner.accountId : getDefaultAccountId();
39476
39580
  if (!accountId) return null;
39477
39581
  const cachePath = join63(configDir, "branding-cache", accountId, `${agentSlug}.json`);
39478
- if (!existsSync56(cachePath)) return null;
39582
+ if (!existsSync55(cachePath)) return null;
39479
39583
  return JSON.parse(readFileSync55(cachePath, "utf-8"));
39480
39584
  } catch {
39481
39585
  return null;
@@ -39571,7 +39675,7 @@ app80.use("/vnc-popout.html", logViewerFetch);
39571
39675
  app80.get("/vnc-popout.html", (c) => {
39572
39676
  let html = htmlCache.get("vnc-popout.html");
39573
39677
  if (!html) {
39574
- html = readFileSync55(resolve51(process.cwd(), "public", "vnc-popout.html"), "utf-8");
39678
+ html = readFileSync55(resolve52(process.cwd(), "public", "vnc-popout.html"), "utf-8");
39575
39679
  const name = escapeHtml(BRAND.productName);
39576
39680
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
39577
39681
  html = html.replace("</head>", ` ${brandScript}
@@ -39731,9 +39835,9 @@ var httpServer = serve({ fetch: app80.fetch, port, hostname });
39731
39835
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39732
39836
  {
39733
39837
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
39734
- const reconcileScript = resolve51(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
39838
+ const reconcileScript = resolve52(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
39735
39839
  const runReconcile = (ctx) => {
39736
- if (!existsSync56(reconcileScript)) return;
39840
+ if (!existsSync55(reconcileScript)) return;
39737
39841
  try {
39738
39842
  const child = spawn3(process.execPath, [reconcileScript], {
39739
39843
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -39772,14 +39876,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39772
39876
  {
39773
39877
  const DREAM_CYCLE_SWEEP_INTERVAL_MS = 36e5;
39774
39878
  const dreamPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
39775
- const dreamSweepScript = resolve51(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
39879
+ const dreamSweepScript = resolve52(dreamPlatformRoot, "plugins/memory/mcp/dist/scripts/dream-cycle-sweep.js");
39776
39880
  registerLoop({
39777
39881
  name: "dream-cycle-sweep",
39778
39882
  intervalMs: DREAM_CYCLE_SWEEP_INTERVAL_MS,
39779
39883
  firstRunDelayMs: 3e4,
39780
39884
  detached: true,
39781
39885
  run: (ctx) => {
39782
- if (!existsSync56(dreamSweepScript)) return;
39886
+ if (!existsSync55(dreamSweepScript)) return;
39783
39887
  try {
39784
39888
  const child = spawn3(process.execPath, [dreamSweepScript], {
39785
39889
  env: { ...process.env, PLATFORM_ROOT: dreamPlatformRoot },
@@ -39796,10 +39900,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39796
39900
  }
39797
39901
  {
39798
39902
  const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
39799
- const outlookScript = resolve51(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
39903
+ const outlookScript = resolve52(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
39800
39904
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
39801
39905
  const runOutlookComplete = (ctx) => {
39802
- if (!existsSync56(outlookScript)) return;
39906
+ if (!existsSync55(outlookScript)) return;
39803
39907
  try {
39804
39908
  const child = spawn3(process.execPath, [outlookScript], {
39805
39909
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -39822,18 +39926,18 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39822
39926
  }
39823
39927
  {
39824
39928
  const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
39825
- const strandedAccountsDir = resolve51(auditRoot, "..", "data/accounts");
39929
+ const strandedAccountsDir = resolve52(auditRoot, "..", "data/accounts");
39826
39930
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
39827
39931
  const STRANDED_AGE_MS = 16 * 6e4;
39828
39932
  const STRANDED_UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
39829
39933
  const runStrandedAudit = () => {
39830
39934
  try {
39831
- if (!existsSync56(strandedAccountsDir)) return;
39935
+ if (!existsSync55(strandedAccountsDir)) return;
39832
39936
  const now = Date.now();
39833
39937
  for (const name of readdirSync32(strandedAccountsDir)) {
39834
39938
  if (!STRANDED_UUID_RE.test(name)) continue;
39835
- const pendingPath2 = resolve51(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
39836
- if (!existsSync56(pendingPath2)) continue;
39939
+ const pendingPath2 = resolve52(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
39940
+ if (!existsSync55(pendingPath2)) continue;
39837
39941
  const ageMs2 = now - statSync30(pendingPath2).mtimeMs;
39838
39942
  if (ageMs2 > STRANDED_AGE_MS) {
39839
39943
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs2 / 1e3)}`);
@@ -39852,7 +39956,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39852
39956
  }
39853
39957
  {
39854
39958
  const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
39855
- const googleAccountsDir = resolve51(googleRoot, "..", "data/accounts");
39959
+ const googleAccountsDir = resolve52(googleRoot, "..", "data/accounts");
39856
39960
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
39857
39961
  const runGooglePendingAuditSafe = () => {
39858
39962
  try {
@@ -39867,10 +39971,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39867
39971
  firstRunDelayMs: 27e3,
39868
39972
  run: runGooglePendingAuditSafe
39869
39973
  });
39870
- const googleAuditScript = resolve51(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
39974
+ const googleAuditScript = resolve52(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
39871
39975
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
39872
39976
  const runGoogleAccountAudit = (ctx) => {
39873
- if (!existsSync56(googleAuditScript)) return;
39977
+ if (!existsSync55(googleAuditScript)) return;
39874
39978
  try {
39875
39979
  const child = spawn3(process.execPath, [googleAuditScript], {
39876
39980
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -39930,7 +40034,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39930
40034
  for (const o of migrateTelegramTwoSlot({
39931
40035
  accounts: listValidAccounts().map((a) => ({ accountId: a.accountId, accountDir: a.accountDir })),
39932
40036
  secretPathFor: secretPath,
39933
- legacySecretPathFor: (botType, accountId) => resolve51(
40037
+ legacySecretPathFor: (botType, accountId) => resolve52(
39934
40038
  homedir5(),
39935
40039
  configDirName2(),
39936
40040
  `${botType === "admin" ? ".telegram-admin-webhook-secret" : ".telegram-webhook-secret"}.${accountId}`
@@ -39959,7 +40063,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
39959
40063
  }
39960
40064
  const lines = buildTelegramAuditLines({
39961
40065
  accounts,
39962
- secretFileExists: (botId) => existsSync56(secretPath(botId)),
40066
+ secretFileExists: (botId) => existsSync55(secretPath(botId)),
39963
40067
  agentActive: isActiveAgentSlug,
39964
40068
  secretFilesOnDisk,
39965
40069
  lastActivityByBot: (botId) => lastByBot.get(botId) ?? null,
@@ -40098,7 +40202,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
40098
40202
  }
40099
40203
  {
40100
40204
  const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
40101
- const publishScript = resolve51(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
40205
+ const publishScript = resolve52(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
40102
40206
  const PUBLISH_INTERVAL_MS = 3e5;
40103
40207
  const bookingAccounts = () => {
40104
40208
  try {
@@ -40109,7 +40213,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
40109
40213
  }
40110
40214
  };
40111
40215
  const spawnPublish = (account, ctx) => {
40112
- if (!existsSync56(publishScript)) return;
40216
+ if (!existsSync55(publishScript)) return;
40113
40217
  try {
40114
40218
  const child = spawn3(process.execPath, [publishScript], {
40115
40219
  env: {
@@ -40128,19 +40232,19 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
40128
40232
  }
40129
40233
  };
40130
40234
  const auditSnapshotAge = (account) => {
40131
- const availPath = resolve51(account.accountDir, "calendar-availability.json");
40235
+ const availPath = resolve52(account.accountDir, "calendar-availability.json");
40132
40236
  let hasBookingSite = false;
40133
40237
  try {
40134
- if (existsSync56(availPath)) {
40238
+ if (existsSync55(availPath)) {
40135
40239
  const cfg = JSON.parse(readFileSync55(availPath, "utf-8"));
40136
40240
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
40137
40241
  }
40138
40242
  } catch {
40139
40243
  }
40140
40244
  if (!hasBookingSite) return;
40141
- const statePath = resolve51(account.accountDir, "state", "booking-availability", "last-publish.json");
40245
+ const statePath = resolve52(account.accountDir, "state", "booking-availability", "last-publish.json");
40142
40246
  let lastSuccessAt = null;
40143
- if (existsSync56(statePath)) {
40247
+ if (existsSync55(statePath)) {
40144
40248
  try {
40145
40249
  const rec = JSON.parse(readFileSync55(statePath, "utf-8"));
40146
40250
  lastSuccessAt = rec.lastSuccessAt ?? null;
@@ -40178,11 +40282,11 @@ startPlannerDivergence();
40178
40282
  startDispatchFieldCensus(() => getSession());
40179
40283
  {
40180
40284
  const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..");
40181
- const auditScript = resolve51(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
40285
+ const auditScript = resolve52(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
40182
40286
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
40183
40287
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
40184
40288
  const runConnectorAudit = (ctx) => {
40185
- if (!existsSync56(auditScript)) return;
40289
+ if (!existsSync55(auditScript)) return;
40186
40290
  try {
40187
40291
  const child = spawn3(process.execPath, [auditScript], {
40188
40292
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -40304,7 +40408,7 @@ try {
40304
40408
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
40305
40409
  async function runAdminUserReconcileTick() {
40306
40410
  try {
40307
- if (!existsSync56(USERS_FILE)) {
40411
+ if (!existsSync55(USERS_FILE)) {
40308
40412
  console.error("[adminuser-self-heal] skip reason=no-users-file");
40309
40413
  return;
40310
40414
  }
@@ -40391,7 +40495,7 @@ var runIngestAuditTick = () => {
40391
40495
  agentExists: (accountId, slug) => {
40392
40496
  if (!house) return false;
40393
40497
  const dir = isHouseAccountKey(house.accountId, accountId) ? house.accountDir : join63(ACCOUNTS_DIR, accountId);
40394
- return existsSync56(join63(dir, "agents", slug, "config.json"));
40498
+ return existsSync55(join63(dir, "agents", slug, "config.json"));
40395
40499
  }
40396
40500
  });
40397
40501
  } catch (err) {
@@ -40440,7 +40544,7 @@ registerLoop({
40440
40544
  houseAccountId: () => resolveAccount()?.accountId ?? null,
40441
40545
  activeSlugs: () => listValidAccounts().map((a) => {
40442
40546
  const agentsRoot = join63(a.accountDir, "agents");
40443
- if (!existsSync56(agentsRoot)) return { accountId: a.accountId, slugs: [] };
40547
+ if (!existsSync55(agentsRoot)) return { accountId: a.accountId, slugs: [] };
40444
40548
  const slugs = readdirSync32(agentsRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).filter((slug) => isActiveAgentSlug(a.accountDir, slug));
40445
40549
  return { accountId: a.accountId, slugs };
40446
40550
  })
@@ -40454,7 +40558,7 @@ registerLoop({
40454
40558
  });
40455
40559
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
40456
40560
  function countUsersRows() {
40457
- if (!existsSync56(USERS_FILE)) return 0;
40561
+ if (!existsSync55(USERS_FILE)) return 0;
40458
40562
  const raw = readFileSync55(USERS_FILE, "utf-8").trim();
40459
40563
  if (!raw) return 0;
40460
40564
  const users = JSON.parse(raw);
@@ -40623,7 +40727,7 @@ if (bootAccountConfig?.whatsapp) {
40623
40727
  }
40624
40728
  init({
40625
40729
  configDir: configDirForWhatsApp,
40626
- platformRoot: resolve51(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..")),
40730
+ platformRoot: resolve52(process.env.MAXY_PLATFORM_ROOT ?? join63(__dirname, "..")),
40627
40731
  accountConfig: bootAccountConfig,
40628
40732
  // Task 2074 — enrich with the sub-account name and fan out to every open
40629
40733
  // admin SSE stream. Fire-and-forget: the manager's persist path must not