@rubytech/create-maxy-code 0.1.486 → 0.1.488

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 (69) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/cloudflare/PLUGIN.md +3 -3
  3. package/payload/platform/plugins/cloudflare/bin/portal-index-push.mjs +30 -8
  4. package/payload/platform/plugins/cloudflare/bin/schema-exposed-dirs.mjs +22 -2
  5. package/payload/platform/plugins/cloudflare/mcp/__tests__/portal-index-push.test.ts +23 -0
  6. package/payload/platform/plugins/cloudflare/mcp/__tests__/schema-exposed-dirs.test.ts +43 -0
  7. package/payload/platform/plugins/cloudflare/skills/data-portal/SKILL.md +12 -2
  8. package/payload/platform/plugins/memory/PLUGIN.md +1 -0
  9. package/payload/platform/plugins/memory/references/schema-construction.md +13 -0
  10. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/free-busy-url.test.d.ts +2 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/free-busy-url.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/free-busy-url.test.js +12 -0
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/free-busy-url.test.js.map +1 -0
  14. package/payload/platform/plugins/scheduling/mcp/dist/lib/free-busy-url.d.ts +8 -0
  15. package/payload/platform/plugins/scheduling/mcp/dist/lib/free-busy-url.d.ts.map +1 -0
  16. package/payload/platform/plugins/scheduling/mcp/dist/lib/free-busy-url.js +12 -0
  17. package/payload/platform/plugins/scheduling/mcp/dist/lib/free-busy-url.js.map +1 -0
  18. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js +12 -2
  19. package/payload/platform/plugins/scheduling/mcp/dist/scripts/publish-availability.js.map +1 -1
  20. package/payload/platform/plugins/storage-broker/PLUGIN.md +1 -0
  21. package/payload/platform/scripts/__tests__/account-schema-owned-dirs.test.sh +22 -2
  22. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.d.ts.map +1 -1
  23. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js +23 -2
  24. package/payload/platform/services/claude-session-manager/dist/account-dir-schema-reconcile.js.map +1 -1
  25. package/payload/server/public/activity.html +6 -6
  26. package/payload/server/public/assets/{AdminLoginScreens-DF9S5Rca.js → AdminLoginScreens-Dic_fPt6.js} +1 -1
  27. package/payload/server/public/assets/{AdminShell-B0PNDCAb.js → AdminShell-JN7rZ8aG.js} +1 -1
  28. package/payload/server/public/assets/{Checkbox-s5X6dso4.js → Checkbox-CB74kINA.js} +1 -1
  29. package/payload/server/public/assets/{activity-BRBsaalV.js → activity-DbfpHg3i.js} +1 -1
  30. package/payload/server/public/assets/{admin-BoVCP4Mw.js → admin-CThbXaYH.js} +1 -1
  31. package/payload/server/public/assets/{bot-BVO9Uqr_.js → bot-DnuyRsLS.js} +1 -1
  32. package/payload/server/public/assets/{browser-BVW4FFii.js → browser-q4EFqKvR.js} +1 -1
  33. package/payload/server/public/assets/{calendar-CWsD3uLk.js → calendar-C-q9kWmA.js} +1 -1
  34. package/payload/server/public/assets/chat-DcefIV9q.js +1 -0
  35. package/payload/server/public/assets/chevron-down-Blma_CKl.js +1 -0
  36. package/payload/server/public/assets/chevron-left-xeYDxFiC.js +1 -0
  37. package/payload/server/public/assets/chevron-right-BonbtjqJ.js +1 -0
  38. package/payload/server/public/assets/data-D5dp6nj6.js +1 -0
  39. package/payload/server/public/assets/{graph-mJ9ky5dc.js → graph-CNgt7ygi.js} +1 -1
  40. package/payload/server/public/assets/{graph-labels-C8-sIKuv.js → graph-labels-DA48HrRR.js} +1 -1
  41. package/payload/server/public/assets/{maximize-2-yucCepu_.js → maximize-2-k3Fu5hdP.js} +1 -1
  42. package/payload/server/public/assets/{operator-911z_Fy_.js → operator-8NVpNLeD.js} +1 -1
  43. package/payload/server/public/assets/{page-Cv0qUwMG.js → page-Bvx0A2jB.js} +1 -1
  44. package/payload/server/public/assets/{page-CgSgj8Cy.js → page-DhwPG5Zf.js} +1 -1
  45. package/payload/server/public/assets/{public-BzwveFwz.js → public-BJ5Oo2Fw.js} +1 -1
  46. package/payload/server/public/assets/{rotate-ccw-BH51cf2Q.js → rotate-ccw-D-ov5jM4.js} +1 -1
  47. package/payload/server/public/assets/tasks-DHMxTZVD.js +1 -0
  48. package/payload/server/public/assets/{time-entry-format-DPdGkp1C.js → time-entry-format-EmV5lz6o.js} +1 -1
  49. package/payload/server/public/assets/{triangle-alert-DO2rjjfV.js → triangle-alert-CivyPfAL.js} +1 -1
  50. package/payload/server/public/assets/{useCopyFeedback-HMSM7-Ir.js → useCopyFeedback-hbnPS-r9.js} +1 -1
  51. package/payload/server/public/assets/{useSubAccountSwitcher-2ojOOYNo.css → useSubAccountSwitcher-kwhG-aJj.css} +1 -1
  52. package/payload/server/public/assets/{useVoiceRecorder-BcukQIza.js → useVoiceRecorder-QN9_GqB_.js} +1 -1
  53. package/payload/server/public/browser.html +4 -4
  54. package/payload/server/public/calendar.html +6 -6
  55. package/payload/server/public/chat.html +13 -13
  56. package/payload/server/public/data.html +10 -10
  57. package/payload/server/public/graph.html +11 -11
  58. package/payload/server/public/index.html +16 -16
  59. package/payload/server/public/operator.html +15 -15
  60. package/payload/server/public/public.html +13 -13
  61. package/payload/server/public/tasks.html +6 -6
  62. package/payload/server/server.js +155 -103
  63. package/payload/server/public/assets/chat-DKGREuIO.js +0 -1
  64. package/payload/server/public/assets/chevron-down-m581tl1J.js +0 -1
  65. package/payload/server/public/assets/chevron-left-BAY0xfmR.js +0 -1
  66. package/payload/server/public/assets/chevron-right-Dy_REdYZ.js +0 -1
  67. package/payload/server/public/assets/data-CtOxa94P.js +0 -1
  68. package/payload/server/public/assets/tasks-21egY7A6.js +0 -1
  69. /package/payload/server/public/assets/{useSubAccountSwitcher-DLvqvfoc.js → useSubAccountSwitcher-DotTrvX3.js} +0 -0
@@ -1643,10 +1643,10 @@ var serveStatic = (options = { root: "" }) => {
1643
1643
  };
1644
1644
 
1645
1645
  // server/index.ts
1646
- import { readFileSync as readFileSync42, existsSync as existsSync38, watchFile, readdirSync as readdirSync26, statSync as statSync17 } from "fs";
1646
+ import { readFileSync as readFileSync43, existsSync as existsSync39, watchFile, readdirSync as readdirSync26, statSync as statSync17 } from "fs";
1647
1647
  import { spawn as spawn3 } from "child_process";
1648
1648
  import { createHash as createHash7 } from "crypto";
1649
- import { resolve as resolve38, join as join45, basename as basename12 } from "path";
1649
+ import { resolve as resolve39, join as join45, basename as basename12 } from "path";
1650
1650
  import { homedir as homedir4 } from "os";
1651
1651
  import { monitorEventLoopDelay } from "perf_hooks";
1652
1652
 
@@ -2920,7 +2920,7 @@ var credsSaveQueue = Promise.resolve();
2920
2920
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
2921
2921
  console.error(`${TAG6} draining credential save queue\u2026`);
2922
2922
  const timer = new Promise(
2923
- (resolve39) => setTimeout(() => resolve39("timeout"), timeoutMs)
2923
+ (resolve40) => setTimeout(() => resolve40("timeout"), timeoutMs)
2924
2924
  );
2925
2925
  const result = await Promise.race([
2926
2926
  credsSaveQueue.then(() => "drained"),
@@ -3097,11 +3097,11 @@ async function createWaSocket(opts) {
3097
3097
  return sock;
3098
3098
  }
3099
3099
  async function waitForConnection(sock) {
3100
- return new Promise((resolve39, reject) => {
3100
+ return new Promise((resolve40, reject) => {
3101
3101
  const handler = (update) => {
3102
3102
  if (update.connection === "open") {
3103
3103
  sock.ev.off("connection.update", handler);
3104
- resolve39();
3104
+ resolve40();
3105
3105
  }
3106
3106
  if (update.connection === "close") {
3107
3107
  sock.ev.off("connection.update", handler);
@@ -3209,7 +3209,7 @@ function isTimeoutError(err) {
3209
3209
  return Boolean(err?.__maxyTimeout);
3210
3210
  }
3211
3211
  function withTimeout(label, promise, timeoutMs) {
3212
- return new Promise((resolve39, reject) => {
3212
+ return new Promise((resolve40, reject) => {
3213
3213
  const timer = setTimeout(() => {
3214
3214
  const err = new Error(`${label} timed out after ${timeoutMs}ms`);
3215
3215
  err.__maxyTimeout = true;
@@ -3219,7 +3219,7 @@ function withTimeout(label, promise, timeoutMs) {
3219
3219
  promise.then(
3220
3220
  (value) => {
3221
3221
  clearTimeout(timer);
3222
- resolve39(value);
3222
+ resolve40(value);
3223
3223
  },
3224
3224
  (err) => {
3225
3225
  clearTimeout(timer);
@@ -4278,8 +4278,8 @@ async function persistWhatsAppMessage(input) {
4278
4278
  const { givenName, familyName } = splitName(input.pushName);
4279
4279
  const prev = sessionWriteLocks.get(input.cacheKey);
4280
4280
  let release;
4281
- const mine = new Promise((resolve39) => {
4282
- release = resolve39;
4281
+ const mine = new Promise((resolve40) => {
4282
+ release = resolve40;
4283
4283
  });
4284
4284
  const chained = (prev ?? Promise.resolve()).then(() => mine);
4285
4285
  sessionWriteLocks.set(input.cacheKey, chained);
@@ -6016,11 +6016,11 @@ async function connectWithReconnect(conn) {
6016
6016
  console.error(
6017
6017
  `${TAG17} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
6018
6018
  );
6019
- await new Promise((resolve39) => {
6020
- const timer = setTimeout(resolve39, delay);
6019
+ await new Promise((resolve40) => {
6020
+ const timer = setTimeout(resolve40, delay);
6021
6021
  conn.abortController.signal.addEventListener("abort", () => {
6022
6022
  clearTimeout(timer);
6023
- resolve39();
6023
+ resolve40();
6024
6024
  }, { once: true });
6025
6025
  });
6026
6026
  }
@@ -6028,16 +6028,16 @@ async function connectWithReconnect(conn) {
6028
6028
  }
6029
6029
  }
6030
6030
  function waitForDisconnectEvent(conn) {
6031
- return new Promise((resolve39) => {
6031
+ return new Promise((resolve40) => {
6032
6032
  if (!conn.sock) {
6033
- resolve39();
6033
+ resolve40();
6034
6034
  return;
6035
6035
  }
6036
6036
  const sock = conn.sock;
6037
6037
  const handler = (update) => {
6038
6038
  if (update.connection === "close") {
6039
6039
  sock.ev.off("connection.update", handler);
6040
- resolve39();
6040
+ resolve40();
6041
6041
  }
6042
6042
  };
6043
6043
  sock.ev.on("connection.update", handler);
@@ -6511,8 +6511,8 @@ async function handleInboundMessage(conn, msg) {
6511
6511
  const conversationKey = isGroup ? remoteJid : senderPhone;
6512
6512
  const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
6513
6513
  let resolvePending;
6514
- const sttPending = new Promise((resolve39) => {
6515
- resolvePending = resolve39;
6514
+ const sttPending = new Promise((resolve40) => {
6515
+ resolvePending = resolve40;
6516
6516
  });
6517
6517
  if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
6518
6518
  try {
@@ -6901,20 +6901,20 @@ function buildX11Env(chromiumWrapperPath, transport = "vnc") {
6901
6901
 
6902
6902
  // server/routes/health.ts
6903
6903
  function checkPort(port2, timeoutMs = 500) {
6904
- return new Promise((resolve39) => {
6904
+ return new Promise((resolve40) => {
6905
6905
  const socket = createConnection2(port2, "127.0.0.1");
6906
6906
  socket.setTimeout(timeoutMs);
6907
6907
  socket.once("connect", () => {
6908
6908
  socket.destroy();
6909
- resolve39(true);
6909
+ resolve40(true);
6910
6910
  });
6911
6911
  socket.once("error", () => {
6912
6912
  socket.destroy();
6913
- resolve39(false);
6913
+ resolve40(false);
6914
6914
  });
6915
6915
  socket.once("timeout", () => {
6916
6916
  socket.destroy();
6917
- resolve39(false);
6917
+ resolve40(false);
6918
6918
  });
6919
6919
  });
6920
6920
  }
@@ -8245,8 +8245,8 @@ async function startLogin(opts) {
8245
8245
  await clearAuth(authDir);
8246
8246
  let resolveCode = null;
8247
8247
  let rejectCode = null;
8248
- const codePromise = new Promise((resolve39, reject) => {
8249
- resolveCode = resolve39;
8248
+ const codePromise = new Promise((resolve40, reject) => {
8249
+ resolveCode = resolve40;
8250
8250
  rejectCode = reject;
8251
8251
  });
8252
8252
  const codeTimer = setTimeout(
@@ -14681,15 +14681,15 @@ function operatorRoleFor(config, userId) {
14681
14681
  async function buildAccountOptionList(accounts, userId) {
14682
14682
  const houseAccount = accounts.find((a) => a.config.role === "house");
14683
14683
  console.log(`[admin-accounts] op=list count=${accounts.length} house=${houseAccount?.accountId ?? "none"}`);
14684
- const resolve39 = async (a) => {
14684
+ const resolve40 = async (a) => {
14685
14685
  const businessName = await fetchAccountName(a.accountId) || void 0;
14686
14686
  return { accountId: a.accountId, businessName, role: operatorRoleFor(a.config, userId), isHouse: a.config.role === "house" };
14687
14687
  };
14688
14688
  const houseOptions = await Promise.all(
14689
- accounts.filter((a) => a.config.role === "house").map(resolve39)
14689
+ accounts.filter((a) => a.config.role === "house").map(resolve40)
14690
14690
  );
14691
14691
  const nonHouseOptions = await Promise.all(
14692
- accounts.filter((a) => a.config.role !== "house").map(resolve39)
14692
+ accounts.filter((a) => a.config.role !== "house").map(resolve40)
14693
14693
  );
14694
14694
  const sortKey = (o) => (o.businessName || o.accountId).toLowerCase();
14695
14695
  nonHouseOptions.sort((x, y) => {
@@ -19393,16 +19393,23 @@ function parseTableTopLevelLabels(referencesDir) {
19393
19393
  }
19394
19394
  return { labels, contributingFiles };
19395
19395
  }
19396
+ var ADDITIONAL_BASE_LABELS = Object.freeze(
19397
+ /* @__PURE__ */ new Set(["Supplier"])
19398
+ );
19396
19399
  var cached = null;
19397
19400
  function getTopLevelLabelAllowlist(opts = {}) {
19398
19401
  if (!opts.referencesDir && cached) return cached;
19399
19402
  const referencesDir = opts.referencesDir ?? resolveReferencesDir();
19400
19403
  const { labels: derived, contributingFiles } = parseTableTopLevelLabels(referencesDir);
19404
+ const excluded = [];
19405
+ for (const label of ADDITIONAL_BASE_LABELS) {
19406
+ if (derived.delete(label)) excluded.push(label);
19407
+ }
19401
19408
  const derivedCount = derived.size;
19402
19409
  for (const label of STATIC_TOP_LEVEL_LABELS) derived.add(label);
19403
19410
  const result = Object.freeze(derived);
19404
19411
  process.stderr.write(
19405
- `[graph-page] op=top-level-labels source=ontology count=${derived.size} files=${contributingFiles.join("|") || "none"} derived=${derivedCount} static=${STATIC_TOP_LEVEL_LABELS.size}
19412
+ `[graph-page] op=top-level-labels source=ontology count=${derived.size} files=${contributingFiles.join("|") || "none"} derived=${derivedCount} static=${STATIC_TOP_LEVEL_LABELS.size} excluded=${excluded.join(",") || "none"}
19406
19413
  `
19407
19414
  );
19408
19415
  if (!opts.referencesDir) cached = result;
@@ -24494,7 +24501,17 @@ app62.get("/free-busy", async (c) => {
24494
24501
  if (Number.isNaN(Date.parse(from)) || Number.isNaN(Date.parse(to))) {
24495
24502
  return c.json({ error: "from and to must be parseable ISO timestamps" }, 400);
24496
24503
  }
24497
- const account = resolveAccount();
24504
+ const accountParam = c.req.query("account");
24505
+ let account;
24506
+ if (accountParam) {
24507
+ account = listValidAccounts().find((a) => a.accountId === accountParam) ?? null;
24508
+ if (!account) {
24509
+ console.error(`[calendar] op=free-busy-unknown-account account="${accountParam}"`);
24510
+ return c.json({ error: "Availability not configured" }, 404);
24511
+ }
24512
+ } else {
24513
+ account = resolveAccount();
24514
+ }
24498
24515
  if (!account) return c.json({ error: "No account configured" }, 500);
24499
24516
  let config;
24500
24517
  try {
@@ -24546,6 +24563,8 @@ var ONT_END = "<!-- ontology-buckets:end -->";
24546
24563
  var OWNED_START = "<!-- plugin-owned-dirs:start -->";
24547
24564
  var OWNED_END = "<!-- plugin-owned-dirs:end -->";
24548
24565
  var ALWAYS_EXPOSED = "output";
24566
+ var SYSTEM_DIRS = /* @__PURE__ */ new Set(["agents", "secrets", "specialists", "state", "memory", "cache", "logs", "tmp"]);
24567
+ var SAFE_FOLDER = /^[A-Za-z0-9_-]+$/;
24549
24568
  var DOMAIN_LINE = /^- `([^`/]+)\/` - one folder per /;
24550
24569
  var OWNED_LINE = /^- `([^`/]+)\/` — /;
24551
24570
  function region(text, start, end) {
@@ -24565,7 +24584,7 @@ function allowedBlockOrNull(text) {
24565
24584
  }
24566
24585
  return null;
24567
24586
  }
24568
- function resolveExposedDirs(schemaText) {
24587
+ function resolveExposedDirs(schemaText, exposeFolders = []) {
24569
24588
  const empty = {
24570
24589
  schemaPresent: false,
24571
24590
  allowed: (
@@ -24607,7 +24626,11 @@ function resolveExposedDirs(schemaText) {
24607
24626
  const pluginOwned = dirsIn(owned, OWNED_LINE);
24608
24627
  const collisions = domainBuckets.filter((d) => pluginOwned.includes(d));
24609
24628
  const candidates = [ALWAYS_EXPOSED, ...domainBuckets.filter((d) => !collisions.includes(d))];
24610
- const exposed = [...new Set(candidates)].filter((d) => allowed.includes(d)).sort();
24629
+ const ontologyExposed = [...new Set(candidates)].filter((d) => allowed.includes(d));
24630
+ const extras = (Array.isArray(exposeFolders) ? exposeFolders : []).filter(
24631
+ (f) => typeof f === "string" && SAFE_FOLDER.test(f) && !SYSTEM_DIRS.has(f)
24632
+ );
24633
+ const exposed = [.../* @__PURE__ */ new Set([...ontologyExposed, ...extras])].sort();
24611
24634
  return { schemaPresent: true, allowed, domainBuckets, pluginOwned, collisions, exposed };
24612
24635
  }
24613
24636
 
@@ -24656,6 +24679,14 @@ async function readAccountSecret(accountId) {
24656
24679
  function isValidAccountId2(value) {
24657
24680
  return /^[A-Za-z0-9-]+$/.test(value);
24658
24681
  }
24682
+ async function readExposeFolders(accountDir) {
24683
+ try {
24684
+ const cfg = JSON.parse(await readFile6(join42(accountDir, "data-portal.json"), "utf8"));
24685
+ return Array.isArray(cfg?.exposeFolders) ? cfg.exposeFolders.filter((f) => typeof f === "string") : [];
24686
+ } catch {
24687
+ return [];
24688
+ }
24689
+ }
24659
24690
  async function resolveFetchTarget(accountDir, relPath) {
24660
24691
  let schemaText = null;
24661
24692
  try {
@@ -24663,7 +24694,8 @@ async function resolveFetchTarget(accountDir, relPath) {
24663
24694
  } catch {
24664
24695
  schemaText = null;
24665
24696
  }
24666
- const { exposed } = resolveExposedDirs(schemaText);
24697
+ const exposeFolders = await readExposeFolders(accountDir);
24698
+ const { exposed } = resolveExposedDirs(schemaText, exposeFolders);
24667
24699
  if (exposed.length === 0) return { ok: false, reason: "not-exposed" };
24668
24700
  const lexical = resolve32(accountDir, relPath);
24669
24701
  let root;
@@ -26484,16 +26516,16 @@ var WebchatGateway = class _WebchatGateway {
26484
26516
  * The public /api/chat route awaits this to return the reply on the same SSE
26485
26517
  * response, preserving the pre-756 POST→single-blob browser contract. */
26486
26518
  awaitReply(key, timeoutMs) {
26487
- return new Promise((resolve39) => {
26519
+ return new Promise((resolve40) => {
26488
26520
  const timer = setTimeout(() => {
26489
26521
  this.replyAwaiters.delete(key);
26490
- resolve39({ timeout: true });
26522
+ resolve40({ timeout: true });
26491
26523
  }, timeoutMs);
26492
26524
  if (timer.unref) timer.unref();
26493
26525
  this.replyAwaiters.set(key, (r) => {
26494
26526
  clearTimeout(timer);
26495
26527
  this.replyAwaiters.delete(key);
26496
- resolve39(r);
26528
+ resolve40(r);
26497
26529
  });
26498
26530
  });
26499
26531
  }
@@ -26504,11 +26536,11 @@ var WebchatGateway = class _WebchatGateway {
26504
26536
  * terminal dialog stays answerable). */
26505
26537
  awaitPermissionVerdict(p, timeoutMs) {
26506
26538
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
26507
- return new Promise((resolve39) => {
26539
+ return new Promise((resolve40) => {
26508
26540
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
26509
26541
  const timer = setTimeout(() => {
26510
26542
  this.pendingPrompts.delete(k);
26511
- resolve39({ timeout: true });
26543
+ resolve40({ timeout: true });
26512
26544
  }, timeoutMs);
26513
26545
  if (timer.unref) timer.unref();
26514
26546
  this.pendingPrompts.set(k, {
@@ -26517,7 +26549,7 @@ var WebchatGateway = class _WebchatGateway {
26517
26549
  resolve: (r) => {
26518
26550
  clearTimeout(timer);
26519
26551
  this.pendingPrompts.delete(k);
26520
- resolve39(r);
26552
+ resolve40(r);
26521
26553
  }
26522
26554
  });
26523
26555
  console.error(`[webchat:perm] op=open key=${keyDisplay(p.key)} id=${p.requestId} tool=${p.toolName}`);
@@ -28141,6 +28173,22 @@ function warnOnChannelAdminBindingDrift() {
28141
28173
  }
28142
28174
  }
28143
28175
 
28176
+ // server/lib/booking-site-accounts.ts
28177
+ import { existsSync as existsSync37, readFileSync as readFileSync41 } from "fs";
28178
+ import { resolve as resolve37 } from "path";
28179
+ function listBookingSiteAccounts(accounts) {
28180
+ return accounts.filter((a) => {
28181
+ const availPath = resolve37(a.accountDir, "calendar-availability.json");
28182
+ if (!existsSync37(availPath)) return false;
28183
+ try {
28184
+ const cfg = JSON.parse(readFileSync41(availPath, "utf-8"));
28185
+ return typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
28186
+ } catch {
28187
+ return false;
28188
+ }
28189
+ });
28190
+ }
28191
+
28144
28192
  // app/lib/admin-sse-registry.ts
28145
28193
  var activeAdminSSEControllers = /* @__PURE__ */ new Set();
28146
28194
  function broadcastAdminShutdown(reason) {
@@ -28171,8 +28219,8 @@ function broadcastAdminShutdown(reason) {
28171
28219
 
28172
28220
  // ../lib/entitlement/src/index.ts
28173
28221
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
28174
- import { existsSync as existsSync37, readFileSync as readFileSync41, statSync as statSync16 } from "fs";
28175
- import { resolve as resolve37 } from "path";
28222
+ import { existsSync as existsSync38, readFileSync as readFileSync42, statSync as statSync16 } from "fs";
28223
+ import { resolve as resolve38 } from "path";
28176
28224
 
28177
28225
  // ../lib/entitlement/src/canonicalize.ts
28178
28226
  function canonicalize(value) {
@@ -28207,7 +28255,7 @@ var PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d9
28207
28255
  var GRACE_DAYS = 7;
28208
28256
  var GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1e3;
28209
28257
  function pubkeyPath(brand) {
28210
- return resolve37(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
28258
+ return resolve38(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
28211
28259
  }
28212
28260
  var memo = null;
28213
28261
  function memoKey(mtimeMs, account) {
@@ -28219,8 +28267,8 @@ function resolveEntitlement(brand, account) {
28219
28267
  if (brand.commercialMode !== true) {
28220
28268
  return logResolved(implicitTrust(account), null);
28221
28269
  }
28222
- const entitlementPath = resolve37(brand.configDir, "entitlement.json");
28223
- if (!existsSync37(entitlementPath)) {
28270
+ const entitlementPath = resolve38(brand.configDir, "entitlement.json");
28271
+ if (!existsSync38(entitlementPath)) {
28224
28272
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
28225
28273
  }
28226
28274
  const stat9 = statSync16(entitlementPath);
@@ -28235,7 +28283,7 @@ function resolveEntitlement(brand, account) {
28235
28283
  function verifyAndResolve(brand, entitlementPath, account) {
28236
28284
  let pubkeyPem;
28237
28285
  try {
28238
- pubkeyPem = readFileSync41(pubkeyPath(brand), "utf-8");
28286
+ pubkeyPem = readFileSync42(pubkeyPath(brand), "utf-8");
28239
28287
  } catch (err) {
28240
28288
  return logResolved(anonymousFallback("pubkey-missing"), {
28241
28289
  reason: "pubkey-missing"
@@ -28249,7 +28297,7 @@ function verifyAndResolve(brand, entitlementPath, account) {
28249
28297
  }
28250
28298
  let envelope;
28251
28299
  try {
28252
- envelope = JSON.parse(readFileSync41(entitlementPath, "utf-8"));
28300
+ envelope = JSON.parse(readFileSync42(entitlementPath, "utf-8"));
28253
28301
  } catch {
28254
28302
  return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
28255
28303
  }
@@ -28413,12 +28461,12 @@ installMediaDownloadGuard();
28413
28461
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
28414
28462
  var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join45(PLATFORM_ROOT8, "config", "brand.json") : "";
28415
28463
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
28416
- if (BRAND_JSON_PATH && !existsSync38(BRAND_JSON_PATH)) {
28464
+ if (BRAND_JSON_PATH && !existsSync39(BRAND_JSON_PATH)) {
28417
28465
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
28418
28466
  }
28419
- if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
28467
+ if (BRAND_JSON_PATH && existsSync39(BRAND_JSON_PATH)) {
28420
28468
  try {
28421
- const parsed = JSON.parse(readFileSync42(BRAND_JSON_PATH, "utf-8"));
28469
+ const parsed = JSON.parse(readFileSync43(BRAND_JSON_PATH, "utf-8"));
28422
28470
  BRAND = { ...BRAND, ...parsed };
28423
28471
  } catch (err) {
28424
28472
  console.error(`[brand] Failed to parse brand.json: ${err.message}`);
@@ -28453,8 +28501,8 @@ var brandLoginOpts = {
28453
28501
  var ALIAS_DOMAINS_PATH = join45(homedir4(), BRAND.configDir, "alias-domains.json");
28454
28502
  function loadAliasDomains() {
28455
28503
  try {
28456
- if (!existsSync38(ALIAS_DOMAINS_PATH)) return null;
28457
- const parsed = JSON.parse(readFileSync42(ALIAS_DOMAINS_PATH, "utf-8"));
28504
+ if (!existsSync39(ALIAS_DOMAINS_PATH)) return null;
28505
+ const parsed = JSON.parse(readFileSync43(ALIAS_DOMAINS_PATH, "utf-8"));
28458
28506
  if (!Array.isArray(parsed)) {
28459
28507
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
28460
28508
  return null;
@@ -28527,7 +28575,7 @@ var waGateway = new WaGateway({
28527
28575
  fetchStandingRules: fetchAccountStandingRules,
28528
28576
  resolveSessionOverride: (accountId, senderId) => resolveChannelOverride(accountId, "whatsapp", senderId),
28529
28577
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
28530
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve38(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
28578
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve39(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
28531
28579
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
28532
28580
  // path-validation scope) is the sender's effective SESSION account, resolved
28533
28581
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -28542,7 +28590,7 @@ var waGateway = new WaGateway({
28542
28590
  caption,
28543
28591
  accountId,
28544
28592
  maxyAccountId,
28545
- platformRoot: resolve38(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, ".."))
28593
+ platformRoot: resolve39(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, ".."))
28546
28594
  });
28547
28595
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
28548
28596
  },
@@ -29218,20 +29266,20 @@ app64.get("/agent-assets/:slug/:filename", (c) => {
29218
29266
  console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
29219
29267
  return c.text("Not found", 404);
29220
29268
  }
29221
- const filePath = resolve38(account.accountDir, "agents", slug, "assets", filename);
29222
- const expectedDir = resolve38(account.accountDir, "agents", slug, "assets");
29269
+ const filePath = resolve39(account.accountDir, "agents", slug, "assets", filename);
29270
+ const expectedDir = resolve39(account.accountDir, "agents", slug, "assets");
29223
29271
  if (!filePath.startsWith(expectedDir + "/")) {
29224
29272
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
29225
29273
  return c.text("Forbidden", 403);
29226
29274
  }
29227
- if (!existsSync38(filePath)) {
29275
+ if (!existsSync39(filePath)) {
29228
29276
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
29229
29277
  return c.text("Not found", 404);
29230
29278
  }
29231
29279
  const ext = "." + filename.split(".").pop()?.toLowerCase();
29232
29280
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
29233
29281
  console.log(`[agent-assets] serve slug=${slug} file=${filename} status=200`);
29234
- const body = readFileSync42(filePath);
29282
+ const body = readFileSync43(filePath);
29235
29283
  return c.body(body, 200, {
29236
29284
  "Content-Type": contentType,
29237
29285
  "Cache-Control": "public, max-age=3600"
@@ -29248,20 +29296,20 @@ app64.get("/generated/:filename", (c) => {
29248
29296
  console.error(`[generated] serve file=${filename} status=404`);
29249
29297
  return c.text("Not found", 404);
29250
29298
  }
29251
- const filePath = resolve38(account.accountDir, "generated", filename);
29252
- const expectedDir = resolve38(account.accountDir, "generated");
29299
+ const filePath = resolve39(account.accountDir, "generated", filename);
29300
+ const expectedDir = resolve39(account.accountDir, "generated");
29253
29301
  if (!filePath.startsWith(expectedDir + "/")) {
29254
29302
  console.error(`[generated] serve file=${filename} status=403`);
29255
29303
  return c.text("Forbidden", 403);
29256
29304
  }
29257
- if (!existsSync38(filePath)) {
29305
+ if (!existsSync39(filePath)) {
29258
29306
  console.error(`[generated] serve file=${filename} status=404`);
29259
29307
  return c.text("Not found", 404);
29260
29308
  }
29261
29309
  const ext = "." + filename.split(".").pop()?.toLowerCase();
29262
29310
  const contentType = IMAGE_MIME[ext] || "application/octet-stream";
29263
29311
  console.log(`[generated] serve file=${filename} status=200`);
29264
- const body = readFileSync42(filePath);
29312
+ const body = readFileSync43(filePath);
29265
29313
  return c.body(body, 200, {
29266
29314
  "Content-Type": contentType,
29267
29315
  "Cache-Control": "public, max-age=86400"
@@ -29274,9 +29322,9 @@ app64.route("/v", visitor_consent_default);
29274
29322
  var htmlCache = /* @__PURE__ */ new Map();
29275
29323
  var brandLogoPath = "/brand/maxy-monochrome.png";
29276
29324
  var brandIconPath = "/brand/maxy-monochrome.png";
29277
- if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
29325
+ if (BRAND_JSON_PATH && existsSync39(BRAND_JSON_PATH)) {
29278
29326
  try {
29279
- const fullBrand = JSON.parse(readFileSync42(BRAND_JSON_PATH, "utf-8"));
29327
+ const fullBrand = JSON.parse(readFileSync43(BRAND_JSON_PATH, "utf-8"));
29280
29328
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
29281
29329
  brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
29282
29330
  } catch {
@@ -29303,11 +29351,11 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
29303
29351
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
29304
29352
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
29305
29353
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
29306
- (p) => existsSync38(resolve38(process.cwd(), "public", p.replace(/^\//, "")))
29354
+ (p) => existsSync39(resolve39(process.cwd(), "public", p.replace(/^\//, "")))
29307
29355
  );
29308
29356
  var SW_SOURCE = (() => {
29309
29357
  try {
29310
- return readFileSync42(resolve38(process.cwd(), "public", "sw.js"), "utf-8");
29358
+ return readFileSync43(resolve39(process.cwd(), "public", "sw.js"), "utf-8");
29311
29359
  } catch {
29312
29360
  return null;
29313
29361
  }
@@ -29316,8 +29364,8 @@ function readInstalledVersion() {
29316
29364
  try {
29317
29365
  if (!PLATFORM_ROOT8) return "unknown";
29318
29366
  const versionFile = join45(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
29319
- if (!existsSync38(versionFile)) return "unknown";
29320
- const content = readFileSync42(versionFile, "utf-8").trim();
29367
+ if (!existsSync39(versionFile)) return "unknown";
29368
+ const content = readFileSync43(versionFile, "utf-8").trim();
29321
29369
  return content || "unknown";
29322
29370
  } catch {
29323
29371
  return "unknown";
@@ -29358,7 +29406,7 @@ var clientErrorReporterScript = `<script>
29358
29406
  function cachedHtml(file) {
29359
29407
  let html = htmlCache.get(file);
29360
29408
  if (!html) {
29361
- html = readFileSync42(resolve38(process.cwd(), "public", file), "utf-8");
29409
+ html = readFileSync43(resolve39(process.cwd(), "public", file), "utf-8");
29362
29410
  const productNameEsc = escapeHtml(BRAND.productName);
29363
29411
  html = html.replace(/<title>([^<]*)<\/title>/, (_match, inner) => `<title>${escapeHtml(inner).replace(/Maxy/g, productNameEsc)}</title>`);
29364
29412
  html = html.replace('href="/favicon.ico"', `href="${escapeHtml(brandFaviconPath)}"`);
@@ -29380,8 +29428,8 @@ function loadBrandingCache(agentSlug) {
29380
29428
  const accountId = getDefaultAccountId();
29381
29429
  if (!accountId) return null;
29382
29430
  const cachePath = join45(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
29383
- if (!existsSync38(cachePath)) return null;
29384
- return JSON.parse(readFileSync42(cachePath, "utf-8"));
29431
+ if (!existsSync39(cachePath)) return null;
29432
+ return JSON.parse(readFileSync43(cachePath, "utf-8"));
29385
29433
  } catch {
29386
29434
  return null;
29387
29435
  }
@@ -29476,7 +29524,7 @@ app64.use("/vnc-popout.html", logViewerFetch);
29476
29524
  app64.get("/vnc-popout.html", (c) => {
29477
29525
  let html = htmlCache.get("vnc-popout.html");
29478
29526
  if (!html) {
29479
- html = readFileSync42(resolve38(process.cwd(), "public", "vnc-popout.html"), "utf-8");
29527
+ html = readFileSync43(resolve39(process.cwd(), "public", "vnc-popout.html"), "utf-8");
29480
29528
  const name = escapeHtml(BRAND.productName);
29481
29529
  html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
29482
29530
  html = html.replace("</head>", ` ${brandScript}
@@ -29614,10 +29662,10 @@ var httpServer = serve({ fetch: app64.fetch, port, hostname });
29614
29662
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29615
29663
  {
29616
29664
  const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29617
- const reconcileScript = resolve38(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
29665
+ const reconcileScript = resolve39(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
29618
29666
  const RECONCILE_INTERVAL_MS = 12e4;
29619
29667
  const runReconcile = (ctx) => {
29620
- if (!existsSync38(reconcileScript)) return;
29668
+ if (!existsSync39(reconcileScript)) return;
29621
29669
  try {
29622
29670
  const child = spawn3(process.execPath, [reconcileScript], {
29623
29671
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -29640,10 +29688,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29640
29688
  }
29641
29689
  {
29642
29690
  const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29643
- const outlookScript = resolve38(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
29691
+ const outlookScript = resolve39(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
29644
29692
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
29645
29693
  const runOutlookComplete = (ctx) => {
29646
- if (!existsSync38(outlookScript)) return;
29694
+ if (!existsSync39(outlookScript)) return;
29647
29695
  try {
29648
29696
  const child = spawn3(process.execPath, [outlookScript], {
29649
29697
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -29666,18 +29714,18 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29666
29714
  }
29667
29715
  {
29668
29716
  const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29669
- const strandedAccountsDir = resolve38(auditRoot, "..", "data/accounts");
29717
+ const strandedAccountsDir = resolve39(auditRoot, "..", "data/accounts");
29670
29718
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
29671
29719
  const STRANDED_AGE_MS = 16 * 6e4;
29672
29720
  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;
29673
29721
  const runStrandedAudit = () => {
29674
29722
  try {
29675
- if (!existsSync38(strandedAccountsDir)) return;
29723
+ if (!existsSync39(strandedAccountsDir)) return;
29676
29724
  const now = Date.now();
29677
29725
  for (const name of readdirSync26(strandedAccountsDir)) {
29678
29726
  if (!STRANDED_UUID_RE.test(name)) continue;
29679
- const pendingPath2 = resolve38(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
29680
- if (!existsSync38(pendingPath2)) continue;
29727
+ const pendingPath2 = resolve39(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
29728
+ if (!existsSync39(pendingPath2)) continue;
29681
29729
  const ageMs = now - statSync17(pendingPath2).mtimeMs;
29682
29730
  if (ageMs > STRANDED_AGE_MS) {
29683
29731
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs / 1e3)}`);
@@ -29696,7 +29744,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29696
29744
  }
29697
29745
  {
29698
29746
  const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29699
- const googleAccountsDir = resolve38(googleRoot, "..", "data/accounts");
29747
+ const googleAccountsDir = resolve39(googleRoot, "..", "data/accounts");
29700
29748
  const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
29701
29749
  const runGooglePendingAuditSafe = () => {
29702
29750
  try {
@@ -29711,10 +29759,10 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29711
29759
  firstRunDelayMs: 27e3,
29712
29760
  run: runGooglePendingAuditSafe
29713
29761
  });
29714
- const googleAuditScript = resolve38(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
29762
+ const googleAuditScript = resolve39(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
29715
29763
  const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
29716
29764
  const runGoogleAccountAudit = (ctx) => {
29717
- if (!existsSync38(googleAuditScript)) return;
29765
+ if (!existsSync39(googleAuditScript)) return;
29718
29766
  try {
29719
29767
  const child = spawn3(process.execPath, [googleAuditScript], {
29720
29768
  env: { ...process.env, PLATFORM_ROOT: googleRoot },
@@ -29774,18 +29822,18 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29774
29822
  }
29775
29823
  {
29776
29824
  const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29777
- const publishScript = resolve38(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
29825
+ const publishScript = resolve39(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
29778
29826
  const PUBLISH_INTERVAL_MS = 3e5;
29779
- const currentAccount = () => {
29827
+ const bookingAccounts = () => {
29780
29828
  try {
29781
- return resolveAccount();
29829
+ return listBookingSiteAccounts(listValidAccounts());
29782
29830
  } catch (err) {
29783
- console.error(`[calendar-availability] op=publish result=error reason=account-resolve-failed err="${err.message}"`);
29784
- return null;
29831
+ console.error(`[calendar-availability] op=publish result=error reason=enumerate-failed err="${err.message}"`);
29832
+ return [];
29785
29833
  }
29786
29834
  };
29787
29835
  const spawnPublish = (account, ctx) => {
29788
- if (!existsSync38(publishScript)) return;
29836
+ if (!existsSync39(publishScript)) return;
29789
29837
  try {
29790
29838
  const child = spawn3(process.execPath, [publishScript], {
29791
29839
  env: {
@@ -29804,21 +29852,21 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29804
29852
  }
29805
29853
  };
29806
29854
  const auditSnapshotAge = (account) => {
29807
- const availPath = resolve38(account.accountDir, "calendar-availability.json");
29855
+ const availPath = resolve39(account.accountDir, "calendar-availability.json");
29808
29856
  let hasBookingSite = false;
29809
29857
  try {
29810
- if (existsSync38(availPath)) {
29811
- const cfg = JSON.parse(readFileSync42(availPath, "utf-8"));
29858
+ if (existsSync39(availPath)) {
29859
+ const cfg = JSON.parse(readFileSync43(availPath, "utf-8"));
29812
29860
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
29813
29861
  }
29814
29862
  } catch {
29815
29863
  }
29816
29864
  if (!hasBookingSite) return;
29817
- const statePath = resolve38(account.accountDir, "state", "booking-availability", "last-publish.json");
29865
+ const statePath = resolve39(account.accountDir, "state", "booking-availability", "last-publish.json");
29818
29866
  let lastSuccessAt = null;
29819
- if (existsSync38(statePath)) {
29867
+ if (existsSync39(statePath)) {
29820
29868
  try {
29821
- const rec = JSON.parse(readFileSync42(statePath, "utf-8"));
29869
+ const rec = JSON.parse(readFileSync43(statePath, "utf-8"));
29822
29870
  lastSuccessAt = rec.lastSuccessAt ?? null;
29823
29871
  } catch {
29824
29872
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=na reason=bad-state-file`);
@@ -29830,10 +29878,14 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
29830
29878
  console.error(`[calendar-availability] op=audit accountId=${account.accountId} snapshotAgeMs=${ageMs ?? "na"}`);
29831
29879
  };
29832
29880
  const publishTick = (ctx) => {
29833
- const account = currentAccount();
29834
- if (!account) return;
29835
- spawnPublish(account, ctx);
29836
- auditSnapshotAge(account);
29881
+ for (const account of bookingAccounts()) {
29882
+ try {
29883
+ spawnPublish(account, ctx);
29884
+ auditSnapshotAge(account);
29885
+ } catch (err) {
29886
+ console.error(`[calendar-availability] op=publish accountId=${account.accountId} result=error reason=tick-failed err="${err.message}"`);
29887
+ }
29888
+ }
29837
29889
  };
29838
29890
  registerLoop({
29839
29891
  name: "calendar-availability-publish",
@@ -29847,11 +29899,11 @@ startTimeEntryCensus(() => getSession());
29847
29899
  startLedgerCensus(() => getSession());
29848
29900
  {
29849
29901
  const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..");
29850
- const auditScript = resolve38(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
29902
+ const auditScript = resolve39(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
29851
29903
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
29852
29904
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
29853
29905
  const runConnectorAudit = (ctx) => {
29854
- if (!existsSync38(auditScript)) return;
29906
+ if (!existsSync39(auditScript)) return;
29855
29907
  try {
29856
29908
  const child = spawn3(process.execPath, [auditScript], {
29857
29909
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -29971,11 +30023,11 @@ try {
29971
30023
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
29972
30024
  async function runAdminUserReconcileTick() {
29973
30025
  try {
29974
- if (!existsSync38(USERS_FILE)) {
30026
+ if (!existsSync39(USERS_FILE)) {
29975
30027
  console.error("[adminuser-self-heal] skip reason=no-users-file");
29976
30028
  return;
29977
30029
  }
29978
- const usersRaw = readFileSync42(USERS_FILE, "utf-8").trim();
30030
+ const usersRaw = readFileSync43(USERS_FILE, "utf-8").trim();
29979
30031
  if (!usersRaw) {
29980
30032
  console.error("[adminuser-self-heal] skip reason=empty-users-file");
29981
30033
  return;
@@ -30022,8 +30074,8 @@ registerLoop({
30022
30074
  });
30023
30075
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
30024
30076
  function countUsersRows() {
30025
- if (!existsSync38(USERS_FILE)) return 0;
30026
- const raw = readFileSync42(USERS_FILE, "utf-8").trim();
30077
+ if (!existsSync39(USERS_FILE)) return 0;
30078
+ const raw = readFileSync43(USERS_FILE, "utf-8").trim();
30027
30079
  if (!raw) return 0;
30028
30080
  const users = JSON.parse(raw);
30029
30081
  return users.filter((u) => typeof u.userId === "string").length;
@@ -30156,7 +30208,7 @@ if (bootAccountConfig?.whatsapp) {
30156
30208
  }
30157
30209
  init({
30158
30210
  configDir: configDirForWhatsApp,
30159
- platformRoot: resolve38(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..")),
30211
+ platformRoot: resolve39(process.env.MAXY_PLATFORM_ROOT ?? join45(__dirname, "..")),
30160
30212
  accountConfig: bootAccountConfig,
30161
30213
  onMessage: async (msg) => {
30162
30214
  if (isObserveAccount(msg.accountId)) {