@rubytech/create-maxy-code 0.1.474 → 0.1.476

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 (138) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/lib/storage-broker/dist/cf-exec.d.ts.map +1 -1
  3. package/payload/platform/lib/storage-broker/dist/cf-exec.js +3 -2
  4. package/payload/platform/lib/storage-broker/dist/cf-exec.js.map +1 -1
  5. package/payload/platform/lib/storage-broker/src/cf-exec.ts +3 -2
  6. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +18 -9
  7. package/payload/platform/plugins/cloudflare/skills/calendar-site/template/schema.sql +13 -3
  8. package/payload/platform/plugins/docs/references/calendar-booking.md +2 -2
  9. package/payload/platform/plugins/docs/references/google-guide.md +15 -6
  10. package/payload/platform/plugins/google/.claude-plugin/plugin.json +1 -1
  11. package/payload/platform/plugins/google/PLUGIN.md +60 -12
  12. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.d.ts +2 -0
  13. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.d.ts.map +1 -0
  14. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.js +229 -0
  15. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.js.map +1 -0
  16. package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js +9 -9
  17. package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js.map +1 -1
  18. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.d.ts +2 -0
  19. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.d.ts.map +1 -0
  20. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.js +17 -0
  21. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.js.map +1 -0
  22. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.d.ts +2 -0
  23. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.d.ts.map +1 -0
  24. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.js +146 -0
  25. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.js.map +1 -0
  26. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.d.ts +2 -0
  27. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.d.ts.map +1 -0
  28. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.js +19 -0
  29. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.js.map +1 -0
  30. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.d.ts +2 -0
  31. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.d.ts.map +1 -0
  32. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.js +41 -0
  33. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.js.map +1 -0
  34. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.d.ts +44 -0
  35. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.d.ts.map +1 -0
  36. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.js +112 -0
  37. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.js.map +1 -0
  38. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.d.ts +17 -0
  39. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.d.ts.map +1 -0
  40. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.js +143 -0
  41. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.js.map +1 -0
  42. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts +9 -0
  43. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts.map +1 -1
  44. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.js.map +1 -1
  45. package/payload/platform/plugins/google/mcp/dist/index.js +73 -5
  46. package/payload/platform/plugins/google/mcp/dist/index.js.map +1 -1
  47. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.d.ts +2 -0
  48. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.d.ts.map +1 -0
  49. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.js +37 -0
  50. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.js.map +1 -0
  51. package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts +20 -4
  52. package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts.map +1 -1
  53. package/payload/platform/plugins/google/mcp/dist/tools/account-register.js +19 -9
  54. package/payload/platform/plugins/google/mcp/dist/tools/account-register.js.map +1 -1
  55. package/payload/platform/plugins/google/references/auth.md +93 -14
  56. package/payload/platform/plugins/scheduling/PLUGIN.md +2 -2
  57. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js +158 -23
  58. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-reconcile.test.js.map +1 -1
  59. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-schema-migration.test.d.ts +2 -0
  60. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-schema-migration.test.d.ts.map +1 -0
  61. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-schema-migration.test.js +200 -0
  62. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-schema-migration.test.js.map +1 -0
  63. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.d.ts +2 -0
  64. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.d.ts.map +1 -0
  65. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js +309 -0
  66. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/connector-sync-provision.test.js.map +1 -0
  67. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.js +219 -19
  68. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/d1-command.test.js.map +1 -1
  69. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +94 -11
  70. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  71. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +106 -22
  72. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  73. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.d.ts +109 -0
  74. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.d.ts.map +1 -0
  75. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js +213 -0
  76. package/payload/platform/plugins/scheduling/mcp/dist/lib/connector-sync-provision.js.map +1 -0
  77. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.d.ts +80 -8
  78. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.d.ts.map +1 -1
  79. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.js +202 -8
  80. package/payload/platform/plugins/scheduling/mcp/dist/lib/d1-command.js.map +1 -1
  81. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts +6 -4
  82. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.d.ts.map +1 -1
  83. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +334 -142
  84. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  85. package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts +21 -3
  86. package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts.map +1 -1
  87. package/payload/platform/services/claude-session-manager/dist/activity-rows.js +6 -2
  88. package/payload/platform/services/claude-session-manager/dist/activity-rows.js.map +1 -1
  89. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  90. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +43 -5
  91. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  92. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +9 -0
  93. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
  94. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +78 -0
  95. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
  96. package/payload/server/{chunk-Y6V45R6M.js → chunk-LBCMFD4O.js} +173 -29
  97. package/payload/server/maxy-edge.js +1 -1
  98. package/payload/server/public/activity.html +6 -6
  99. package/payload/server/public/assets/{AdminLoginScreens-B44KbEuC.js → AdminLoginScreens-DximwPlS.js} +1 -1
  100. package/payload/server/public/assets/{AdminShell-BjxV2qkb.js → AdminShell-BehbH-Oa.js} +1 -1
  101. package/payload/server/public/assets/{Checkbox-DSeZNGNA.js → Checkbox-DM-eHqOS.js} +1 -1
  102. package/payload/server/public/assets/activity-hDwUeQd6.js +1 -0
  103. package/payload/server/public/assets/{admin-B4LpTCur.js → admin-CAkDnGdk.js} +1 -1
  104. package/payload/server/public/assets/{browser-CEFvaWwI.js → browser-DXl8hOoi.js} +1 -1
  105. package/payload/server/public/assets/{calendar-B3zo6V34.js → calendar-DP6hn4-6.js} +1 -1
  106. package/payload/server/public/assets/chat-DhOfVGYM.js +1 -0
  107. package/payload/server/public/assets/chevron-left-DYNBoLii.js +1 -0
  108. package/payload/server/public/assets/data-bq8fTo_s.js +1 -0
  109. package/payload/server/public/assets/{graph-RaOrnSf2.js → graph-CHcYoEJ5.js} +1 -1
  110. package/payload/server/public/assets/{graph-labels-GlTEIYJj.js → graph-labels-CZykslZM.js} +1 -1
  111. package/payload/server/public/assets/{maximize-2-CHDa8p5h.js → maximize-2-31AZEcMS.js} +1 -1
  112. package/payload/server/public/assets/{operator-DtqHY4jV.js → operator-BGGpdsO_.js} +1 -1
  113. package/payload/server/public/assets/{page-CkhFj8GQ.js → page-BloC6ygA.js} +1 -1
  114. package/payload/server/public/assets/{page-DxnWgPtd.js → page-DOeiiqbR.js} +1 -1
  115. package/payload/server/public/assets/{public-D5TUfQ3I.js → public-CGgO6IZv.js} +1 -1
  116. package/payload/server/public/assets/{rotate-ccw-BJjVAQQY.js → rotate-ccw-BlAi6iFg.js} +1 -1
  117. package/payload/server/public/assets/{tasks-CM9pYYG1.js → tasks-C1giFRRL.js} +1 -1
  118. package/payload/server/public/assets/{time-entry-format-C5RYEYjM.js → time-entry-format-CiUUQdq7.js} +1 -1
  119. package/payload/server/public/assets/{triangle-alert-DLfIsuo_.js → triangle-alert-CVqKuLoa.js} +1 -1
  120. package/payload/server/public/assets/{useCopyFeedback-7yKeiAzV.js → useCopyFeedback-ksyUe_g1.js} +1 -1
  121. package/payload/server/public/assets/{useSelectionMode-CWlh6AEq.js → useSelectionMode-BPrBkdTd.js} +1 -1
  122. package/payload/server/public/assets/{useSubAccountSwitcher-B2n9QPVI.css → useSubAccountSwitcher-K4kYeN6i.css} +1 -1
  123. package/payload/server/public/assets/{useVoiceRecorder-j3ZArZ2H.js → useVoiceRecorder-CTXP8oTW.js} +1 -1
  124. package/payload/server/public/browser.html +5 -5
  125. package/payload/server/public/calendar.html +6 -6
  126. package/payload/server/public/chat.html +12 -12
  127. package/payload/server/public/data.html +11 -11
  128. package/payload/server/public/graph.html +11 -11
  129. package/payload/server/public/index.html +14 -14
  130. package/payload/server/public/operator.html +14 -14
  131. package/payload/server/public/public.html +12 -12
  132. package/payload/server/public/tasks.html +5 -5
  133. package/payload/server/server.js +547 -423
  134. package/payload/server/public/assets/activity-CdipMTDp.js +0 -1
  135. package/payload/server/public/assets/chat-5tJdo9i_.js +0 -1
  136. package/payload/server/public/assets/chevron-left-BJllrPBj.js +0 -1
  137. package/payload/server/public/assets/data-Du79EgR-.js +0 -1
  138. /package/payload/server/public/assets/{useSubAccountSwitcher-CBlKgwms.js → useSubAccountSwitcher-DzgzTRRn.js} +0 -0
@@ -28,6 +28,7 @@ import {
28
28
  VNC_DISPLAY,
29
29
  WEBSOCKIFY_PORT,
30
30
  accessPasswordCollides,
31
+ armedCount,
31
32
  autoDeliverPremiumPlugins,
32
33
  canAccessAdmin,
33
34
  checkRateLimit,
@@ -71,6 +72,7 @@ import {
71
72
  isValidAccountId,
72
73
  linkConversationTranscript,
73
74
  listAdminSessions,
75
+ listLoops,
74
76
  listValidAccounts,
75
77
  loadAdminUserName,
76
78
  loadPersonNameByElementId,
@@ -81,6 +83,7 @@ import {
81
83
  projectAgent,
82
84
  reconcileEnabledPluginsForAccounts,
83
85
  recordFailedAttempt,
86
+ registerLoop,
84
87
  registerSession,
85
88
  renameConversation,
86
89
  renderLoginPage,
@@ -112,7 +115,7 @@ import {
112
115
  vncLog,
113
116
  walkPremiumBundles,
114
117
  writeAdminUserAndPerson
115
- } from "./chunk-Y6V45R6M.js";
118
+ } from "./chunk-LBCMFD4O.js";
116
119
  import {
117
120
  D1_MAX_SQL_STATEMENT_BYTES,
118
121
  D1_QUERY_MAX_BODY_BYTES,
@@ -1534,10 +1537,10 @@ var serveStatic = (options = { root: "" }) => {
1534
1537
  };
1535
1538
 
1536
1539
  // server/index.ts
1537
- import { readFileSync as readFileSync41, existsSync as existsSync37, watchFile, readdirSync as readdirSync25, statSync as statSync16 } from "fs";
1540
+ import { readFileSync as readFileSync41, existsSync as existsSync38, watchFile, readdirSync as readdirSync26, statSync as statSync17 } from "fs";
1538
1541
  import { spawn as spawn3 } from "child_process";
1539
1542
  import { createHash as createHash7 } from "crypto";
1540
- import { resolve as resolve36, join as join41, basename as basename12 } from "path";
1543
+ import { resolve as resolve36, join as join42, basename as basename12 } from "path";
1541
1544
  import { homedir as homedir4 } from "os";
1542
1545
  import { monitorEventLoopDelay } from "perf_hooks";
1543
1546
 
@@ -2391,12 +2394,12 @@ function startAuthHealthHeartbeat(intervalMs = 5 * 60 * 1e3) {
2391
2394
  ticking = false;
2392
2395
  }
2393
2396
  };
2394
- void tick();
2395
- const handle = setInterval(() => {
2396
- void tick();
2397
- }, intervalMs);
2398
- if (typeof handle.unref === "function") handle.unref();
2399
- return () => clearInterval(handle);
2397
+ return registerLoop({
2398
+ name: "auth-health",
2399
+ intervalMs,
2400
+ firstRunDelayMs: 0,
2401
+ run: tick
2402
+ });
2400
2403
  }
2401
2404
  async function ensureAuth() {
2402
2405
  const health = assessAuthHealth();
@@ -2809,12 +2812,12 @@ function createBaileysLogger(bindings = {}, authDir) {
2809
2812
  var credsSaveQueue = Promise.resolve();
2810
2813
  async function drainCredsSaveQueue(timeoutMs = 5e3) {
2811
2814
  console.error(`${TAG6} draining credential save queue\u2026`);
2812
- const timer2 = new Promise(
2815
+ const timer = new Promise(
2813
2816
  (resolve37) => setTimeout(() => resolve37("timeout"), timeoutMs)
2814
2817
  );
2815
2818
  const result = await Promise.race([
2816
2819
  credsSaveQueue.then(() => "drained"),
2817
- timer2
2820
+ timer
2818
2821
  ]);
2819
2822
  if (result === "timeout") {
2820
2823
  console.error(`${TAG6} credential save queue drain timed out after ${timeoutMs}ms`);
@@ -3100,19 +3103,19 @@ function isTimeoutError(err) {
3100
3103
  }
3101
3104
  function withTimeout(label, promise, timeoutMs) {
3102
3105
  return new Promise((resolve37, reject) => {
3103
- const timer2 = setTimeout(() => {
3106
+ const timer = setTimeout(() => {
3104
3107
  const err = new Error(`${label} timed out after ${timeoutMs}ms`);
3105
3108
  err.__maxyTimeout = true;
3106
3109
  reject(err);
3107
3110
  }, timeoutMs);
3108
- timer2.unref?.();
3111
+ timer.unref?.();
3109
3112
  promise.then(
3110
3113
  (value) => {
3111
- clearTimeout(timer2);
3114
+ clearTimeout(timer);
3112
3115
  resolve37(value);
3113
3116
  },
3114
3117
  (err) => {
3115
- clearTimeout(timer2);
3118
+ clearTimeout(timer);
3116
3119
  reject(err);
3117
3120
  }
3118
3121
  );
@@ -5197,10 +5200,10 @@ function createInboundDebouncer(opts) {
5197
5200
  flushKey(key).catch(onError);
5198
5201
  }, debounceMs);
5199
5202
  } else {
5200
- const timer2 = setTimeout(() => {
5203
+ const timer = setTimeout(() => {
5201
5204
  flushKey(key).catch(onError);
5202
5205
  }, debounceMs);
5203
- pending.set(key, { entries: [msg], timer: timer2 });
5206
+ pending.set(key, { entries: [msg], timer });
5204
5207
  }
5205
5208
  }
5206
5209
  function registerPending(key, promise) {
@@ -5855,9 +5858,9 @@ async function connectWithReconnect(conn) {
5855
5858
  `${TAG17} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
5856
5859
  );
5857
5860
  await new Promise((resolve37) => {
5858
- const timer2 = setTimeout(resolve37, delay);
5861
+ const timer = setTimeout(resolve37, delay);
5859
5862
  conn.abortController.signal.addEventListener("abort", () => {
5860
- clearTimeout(timer2);
5863
+ clearTimeout(timer);
5861
5864
  resolve37();
5862
5865
  }, { once: true });
5863
5866
  });
@@ -9687,46 +9690,74 @@ async function runPagesAudit(root) {
9687
9690
  }
9688
9691
  }
9689
9692
 
9693
+ // server/google-pending-audit.ts
9694
+ import { existsSync as existsSync10, readdirSync as readdirSync9, statSync as statSync4 } from "fs";
9695
+ import { join as join14 } from "path";
9696
+ var GOOGLE_PENDING_LIFETIME_SEC = 600;
9697
+ var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9698
+ function runGooglePendingAudit(accountsDir, nowMs, emit, readMtimeMs = (path3) => statSync4(path3).mtimeMs) {
9699
+ let scanned = 0;
9700
+ let stranded = 0;
9701
+ if (existsSync10(accountsDir)) {
9702
+ for (const accountId of readdirSync9(accountsDir)) {
9703
+ if (!UUID_RE2.test(accountId)) continue;
9704
+ const pendingPath2 = join14(accountsDir, accountId, "secrets", "google", "pending-oauth.enc");
9705
+ try {
9706
+ if (!existsSync10(pendingPath2)) continue;
9707
+ const ageSec = Math.max(0, Math.floor((nowMs - readMtimeMs(pendingPath2)) / 1e3));
9708
+ scanned += 1;
9709
+ if (ageSec >= GOOGLE_PENDING_LIFETIME_SEC) {
9710
+ stranded += 1;
9711
+ emit(`[google-oauth] op=pending-stranded account=${accountId} ageSec=${ageSec}`);
9712
+ }
9713
+ } catch {
9714
+ }
9715
+ }
9716
+ }
9717
+ emit(`[google-oauth] op=pending-audit scanned=${scanned} stranded=${stranded}`);
9718
+ return { scanned, stranded };
9719
+ }
9720
+
9690
9721
  // server/routes/whatsapp-reader.ts
9691
- import { readFileSync as readFileSync19, watch, statSync as statSync6, openSync, readSync, closeSync, existsSync as existsSync12, readdirSync as readdirSync13, realpathSync as realpathSync5 } from "fs";
9692
- import { basename as basename4, dirname as dirname5, isAbsolute, join as join18, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
9722
+ import { readFileSync as readFileSync19, watch, statSync as statSync7, openSync, readSync, closeSync, existsSync as existsSync13, readdirSync as readdirSync14, realpathSync as realpathSync5 } from "fs";
9723
+ import { basename as basename4, dirname as dirname5, isAbsolute, join as join19, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
9693
9724
 
9694
9725
  // server/routes/admin/sidebar-sessions.ts
9695
- import { readdirSync as readdirSync11, readFileSync as readFileSync17, statSync as statSync5 } from "fs";
9696
- import { dirname as dirname4, join as join16, resolve as resolve12 } from "path";
9726
+ import { readdirSync as readdirSync12, readFileSync as readFileSync17, statSync as statSync6 } from "fs";
9727
+ import { dirname as dirname4, join as join17, resolve as resolve12 } from "path";
9697
9728
 
9698
9729
  // ../services/claude-session-manager/src/jsonl-path.ts
9699
- import { existsSync as existsSync10, readdirSync as readdirSync9 } from "fs";
9730
+ import { existsSync as existsSync11, readdirSync as readdirSync10 } from "fs";
9700
9731
  import { homedir } from "os";
9701
- import { join as join14 } from "path";
9732
+ import { join as join15 } from "path";
9702
9733
  function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
9703
- const projectsRoot = join14(claudeConfigDir2, "projects");
9704
- if (!existsSync10(projectsRoot)) return null;
9734
+ const projectsRoot = join15(claudeConfigDir2, "projects");
9735
+ if (!existsSync11(projectsRoot)) return null;
9705
9736
  let slugs;
9706
9737
  try {
9707
- slugs = readdirSync9(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9738
+ slugs = readdirSync10(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9708
9739
  } catch {
9709
9740
  return null;
9710
9741
  }
9711
9742
  const basename13 = `${sessionId}.jsonl`;
9712
9743
  for (const slug of slugs) {
9713
- const live = join14(projectsRoot, slug, basename13);
9714
- if (existsSync10(live)) return live;
9715
- const archived = join14(projectsRoot, slug, "archive", basename13);
9716
- if (existsSync10(archived)) return archived;
9744
+ const live = join15(projectsRoot, slug, basename13);
9745
+ if (existsSync11(live)) return live;
9746
+ const archived = join15(projectsRoot, slug, "archive", basename13);
9747
+ if (existsSync11(archived)) return archived;
9717
9748
  }
9718
9749
  return null;
9719
9750
  }
9720
9751
 
9721
9752
  // app/lib/admin-identity/pin-validator.ts
9722
9753
  import { createHash as createHash3 } from "crypto";
9723
- import { existsSync as existsSync11, readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync4 } from "fs";
9724
- import { join as join15 } from "path";
9754
+ import { existsSync as existsSync12, readFileSync as readFileSync16, readdirSync as readdirSync11, statSync as statSync5 } from "fs";
9755
+ import { join as join16 } from "path";
9725
9756
  function hashPin(pin) {
9726
9757
  return createHash3("sha256").update(pin).digest("hex");
9727
9758
  }
9728
9759
  function readUsersFile(usersFilePath) {
9729
- if (!existsSync11(usersFilePath)) return null;
9760
+ if (!existsSync12(usersFilePath)) return null;
9730
9761
  const raw = readFileSync16(usersFilePath, "utf-8").trim();
9731
9762
  if (!raw) return [];
9732
9763
  return JSON.parse(raw);
@@ -9846,16 +9877,16 @@ function enumerateJsonls(projectsRoot) {
9846
9877
  const out = [];
9847
9878
  let slugs;
9848
9879
  try {
9849
- slugs = readdirSync11(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9880
+ slugs = readdirSync12(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9850
9881
  } catch (err) {
9851
9882
  if (err.code === "ENOENT") return out;
9852
9883
  throw err;
9853
9884
  }
9854
9885
  for (const slug of slugs) {
9855
- const slugDir = join16(projectsRoot, slug);
9886
+ const slugDir = join17(projectsRoot, slug);
9856
9887
  let entries;
9857
9888
  try {
9858
- entries = readdirSync11(slugDir, { withFileTypes: true });
9889
+ entries = readdirSync12(slugDir, { withFileTypes: true });
9859
9890
  } catch (err) {
9860
9891
  const code = err.code ?? "unknown";
9861
9892
  console.error(`[admin-sessions-list] slug-skipped slug=${slug} code=${code}`);
@@ -9863,12 +9894,12 @@ function enumerateJsonls(projectsRoot) {
9863
9894
  }
9864
9895
  for (const entry of entries) {
9865
9896
  if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
9866
- out.push({ path: join16(slugDir, entry.name), isSubagent: false, archived: false });
9897
+ out.push({ path: join17(slugDir, entry.name), isSubagent: false, archived: false });
9867
9898
  } else if (entry.isDirectory() && entry.name === "subagents") {
9868
- const subDir = join16(slugDir, entry.name);
9899
+ const subDir = join17(slugDir, entry.name);
9869
9900
  let subEntries;
9870
9901
  try {
9871
- subEntries = readdirSync11(subDir, { withFileTypes: true });
9902
+ subEntries = readdirSync12(subDir, { withFileTypes: true });
9872
9903
  } catch (err) {
9873
9904
  const code = err.code ?? "unknown";
9874
9905
  console.error(`[admin-sessions-list] subagents-skipped slug=${slug} code=${code}`);
@@ -9876,14 +9907,14 @@ function enumerateJsonls(projectsRoot) {
9876
9907
  }
9877
9908
  for (const sub of subEntries) {
9878
9909
  if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
9879
- out.push({ path: join16(subDir, sub.name), isSubagent: true, archived: false });
9910
+ out.push({ path: join17(subDir, sub.name), isSubagent: true, archived: false });
9880
9911
  }
9881
9912
  }
9882
9913
  } else if (entry.isDirectory() && entry.name === "archive") {
9883
- const archiveDir = join16(slugDir, entry.name);
9914
+ const archiveDir = join17(slugDir, entry.name);
9884
9915
  let archiveEntries;
9885
9916
  try {
9886
- archiveEntries = readdirSync11(archiveDir, { withFileTypes: true });
9917
+ archiveEntries = readdirSync12(archiveDir, { withFileTypes: true });
9887
9918
  } catch (err) {
9888
9919
  const code = err.code ?? "unknown";
9889
9920
  console.error(`[admin-sessions-list] archive-skipped slug=${slug} code=${code}`);
@@ -9891,7 +9922,7 @@ function enumerateJsonls(projectsRoot) {
9891
9922
  }
9892
9923
  for (const arc of archiveEntries) {
9893
9924
  if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
9894
- out.push({ path: join16(archiveDir, arc.name), isSubagent: false, archived: true });
9925
+ out.push({ path: join17(archiveDir, arc.name), isSubagent: false, archived: true });
9895
9926
  }
9896
9927
  }
9897
9928
  }
@@ -9924,7 +9955,7 @@ async function fetchLiveSessions() {
9924
9955
  function loadUserTitles(accountDir) {
9925
9956
  const out = /* @__PURE__ */ new Map();
9926
9957
  if (!accountDir) return out;
9927
- const path3 = join16(accountDir, "session-titles.json");
9958
+ const path3 = join17(accountDir, "session-titles.json");
9928
9959
  let raw;
9929
9960
  try {
9930
9961
  raw = readFileSync17(path3, "utf8");
@@ -10051,7 +10082,7 @@ app4.get("/", requireAdminSession, async (c) => {
10051
10082
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
10052
10083
  return c.json({ sessions: [], accountId: scopeAccountId });
10053
10084
  }
10054
- const projectsRoot = join16(configDir2, "projects");
10085
+ const projectsRoot = join17(configDir2, "projects");
10055
10086
  const jsonls = enumerateJsonls(projectsRoot);
10056
10087
  const liveSessions = await fetchLiveSessions();
10057
10088
  const accountDir = scopeAccountId ? resolve12(ACCOUNTS_DIR, scopeAccountId) : null;
@@ -10096,7 +10127,7 @@ app4.get("/", requireAdminSession, async (c) => {
10096
10127
  let mtimeMs;
10097
10128
  try {
10098
10129
  body = readFileSync17(path3, "utf8");
10099
- mtimeMs = statSync5(path3).mtimeMs;
10130
+ mtimeMs = statSync6(path3).mtimeMs;
10100
10131
  } catch {
10101
10132
  continue;
10102
10133
  }
@@ -10104,7 +10135,7 @@ app4.get("/", requireAdminSession, async (c) => {
10104
10135
  const pid = live ? liveSessions.get(sessionId) ?? null : null;
10105
10136
  const resolved = resolveTitle(body, sessionId, userTitles);
10106
10137
  titleSourceCounts[resolved.source] += 1;
10107
- const metaPath = join16(projectDir, `${sessionId}.meta.json`);
10138
+ const metaPath = join17(projectDir, `${sessionId}.meta.json`);
10108
10139
  const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } = readSidecarMeta(metaPath);
10109
10140
  if (multiAccount) {
10110
10141
  if (rowAccountId === null) untaggedCount += 1;
@@ -10417,9 +10448,9 @@ function isModelGated(turns) {
10417
10448
  return turns.some((t) => t.kind === "agent-error" && t.code === "model_unavailable");
10418
10449
  }
10419
10450
  function renderOrSuppressChannelInbound(u, ts, out, queuedPendingSuppress) {
10420
- const armed = queuedPendingSuppress.get(u.text) ?? 0;
10421
- if (armed > 0) {
10422
- queuedPendingSuppress.set(u.text, armed - 1);
10451
+ const armed2 = queuedPendingSuppress.get(u.text) ?? 0;
10452
+ if (armed2 > 0) {
10453
+ queuedPendingSuppress.set(u.text, armed2 - 1);
10423
10454
  } else {
10424
10455
  out.push(operatorInboundTurn(u, ts));
10425
10456
  }
@@ -10517,8 +10548,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
10517
10548
  }
10518
10549
 
10519
10550
  // app/lib/whatsapp-reader/enrich-attachments.ts
10520
- import { readFileSync as readFileSync18, readdirSync as readdirSync12 } from "fs";
10521
- import { join as join17 } from "path";
10551
+ import { readFileSync as readFileSync18, readdirSync as readdirSync13 } from "fs";
10552
+ import { join as join18 } from "path";
10522
10553
  var ADMIN_UPLOAD_PATH = /\/uploads\/(?!public\/)([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})\//gi;
10523
10554
  function adminAttachmentIds(text) {
10524
10555
  const ids = [];
@@ -10531,7 +10562,7 @@ function adminAttachmentIds(text) {
10531
10562
  function adminAttachmentsFromText(text, uploadsBase) {
10532
10563
  const out = [];
10533
10564
  for (const id of adminAttachmentIds(text)) {
10534
- const meta = readAttachmentMeta(join17(uploadsBase, id));
10565
+ const meta = readAttachmentMeta(join18(uploadsBase, id));
10535
10566
  if (meta) out.push(meta);
10536
10567
  }
10537
10568
  return out;
@@ -10539,7 +10570,7 @@ function adminAttachmentsFromText(text, uploadsBase) {
10539
10570
  function readSidecar(dir, attachmentId) {
10540
10571
  let parsed;
10541
10572
  try {
10542
- parsed = JSON.parse(readFileSync18(join17(dir, `${attachmentId}.meta.json`), "utf8"));
10573
+ parsed = JSON.parse(readFileSync18(join18(dir, `${attachmentId}.meta.json`), "utf8"));
10543
10574
  } catch {
10544
10575
  return null;
10545
10576
  }
@@ -10562,13 +10593,13 @@ function readAttachmentMeta(dir) {
10562
10593
  function listSessionAttachmentsInDir(dir) {
10563
10594
  let entries;
10564
10595
  try {
10565
- entries = readdirSync12(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10596
+ entries = readdirSync13(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10566
10597
  } catch {
10567
10598
  return [];
10568
10599
  }
10569
10600
  const sidecars = [];
10570
10601
  for (const name of entries) {
10571
- const sidecar = readSidecar(join17(dir, name), name);
10602
+ const sidecar = readSidecar(join18(dir, name), name);
10572
10603
  if (sidecar) sidecars.push(sidecar);
10573
10604
  }
10574
10605
  sidecars.sort((a, b) => a.storedAt.localeCompare(b.storedAt));
@@ -10628,8 +10659,8 @@ function pickActivity(entries, grown, nowMs, concurrencyWindowMs) {
10628
10659
 
10629
10660
  // server/routes/stream-lifecycle.ts
10630
10661
  var GAUGE_INTERVAL_MS = 6e4;
10631
- function isArmed(timer2) {
10632
- return timer2._destroyed !== true;
10662
+ function isArmed(timer) {
10663
+ return timer._destroyed !== true;
10633
10664
  }
10634
10665
  var Registration = class {
10635
10666
  constructor(connId, channel, startedAt) {
@@ -10639,9 +10670,9 @@ var Registration = class {
10639
10670
  }
10640
10671
  timers = [];
10641
10672
  closed = false;
10642
- arm(timer2) {
10643
- this.timers.push(timer2);
10644
- return timer2;
10673
+ arm(timer) {
10674
+ this.timers.push(timer);
10675
+ return timer;
10645
10676
  }
10646
10677
  teardown(reason) {
10647
10678
  if (this.closed) return false;
@@ -10675,11 +10706,11 @@ function emitGauge() {
10675
10706
  counts[reg.channel]++;
10676
10707
  oldestMs = Math.max(oldestMs, now - reg.startedAt);
10677
10708
  }
10678
- const armed = counts.reader + counts.store;
10709
+ const armed2 = counts.reader + counts.store;
10679
10710
  console.log(
10680
- `[wa-stream] op=gauge armed=${armed} reader=${counts.reader} store=${counts.store} oldestSec=${Math.floor(oldestMs / 1e3)} stale=${stale}`
10711
+ `[wa-stream] op=gauge armed=${armed2} reader=${counts.reader} store=${counts.store} oldestSec=${Math.floor(oldestMs / 1e3)} stale=${stale}`
10681
10712
  );
10682
- if (armed === 0) stopGauge();
10713
+ if (armed2 === 0) stopGauge();
10683
10714
  }
10684
10715
  function startGauge() {
10685
10716
  if (gaugeTimer) return;
@@ -10728,14 +10759,14 @@ app5.get("/conversations", requireAdminSession, async (c) => {
10728
10759
  }
10729
10760
  const cfg = claudeConfigDir();
10730
10761
  if (!cfg) return c.json({ conversations: [] });
10731
- const projectsRoot = join18(cfg, "projects");
10762
+ const projectsRoot = join19(cfg, "projects");
10732
10763
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
10733
10764
  const rows = [];
10734
10765
  let sessionRowsExcludedUntagged = 0;
10735
10766
  for (const { path: path3 } of enumerateJsonls(projectsRoot)) {
10736
10767
  const sessionId = basename4(path3).replace(/\.jsonl$/, "");
10737
10768
  const projectDir = dirname5(path3);
10738
- const meta = readSidecarMeta(join18(projectDir, `${sessionId}.meta.json`));
10769
+ const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
10739
10770
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
10740
10771
  if (multiAccount) {
10741
10772
  if (meta.accountId === null) sessionRowsExcludedUntagged += 1;
@@ -10827,7 +10858,7 @@ app5.get("/conversations", requireAdminSession, async (c) => {
10827
10858
  return c.json({ conversations: [...sessionConversations, ...allStoreRows] });
10828
10859
  });
10829
10860
  function readFrom(path3, from) {
10830
- const end = statSync6(path3).size;
10861
+ const end = statSync7(path3).size;
10831
10862
  if (end <= from) return { buf: Buffer.alloc(0), end: from };
10832
10863
  const fd = openSync(path3, "r");
10833
10864
  try {
@@ -10912,7 +10943,7 @@ function openTaskKey(turns) {
10912
10943
  }
10913
10944
  function readSubagentMeta(dir, hex) {
10914
10945
  try {
10915
- const m = JSON.parse(readFileSync19(join18(dir, `agent-${hex}.meta.json`), "utf8"));
10946
+ const m = JSON.parse(readFileSync19(join19(dir, `agent-${hex}.meta.json`), "utf8"));
10916
10947
  if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
10917
10948
  return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
10918
10949
  }
@@ -10935,7 +10966,7 @@ function runActivityTick(c) {
10935
10966
  c.parentGrewThisTick = false;
10936
10967
  let names = [];
10937
10968
  try {
10938
- names = readdirSync13(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
10969
+ names = readdirSync14(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
10939
10970
  } catch {
10940
10971
  }
10941
10972
  const entries = [];
@@ -10944,7 +10975,7 @@ function runActivityTick(c) {
10944
10975
  let size = 0;
10945
10976
  let mtimeMs = 0;
10946
10977
  try {
10947
- const st = statSync6(join18(c.subagentsDir, name));
10978
+ const st = statSync7(join19(c.subagentsDir, name));
10948
10979
  size = st.size;
10949
10980
  mtimeMs = st.mtimeMs;
10950
10981
  } catch {
@@ -10989,11 +11020,11 @@ app5.get("/stream", requireAdminSession, (c) => {
10989
11020
  const sessionId = c.req.query("sessionId") ?? "";
10990
11021
  const projectDir = c.req.query("projectDir") ?? "";
10991
11022
  const cfg = claudeConfigDir();
10992
- const projectsRoot = cfg ? resolve13(join18(cfg, "projects")) : null;
11023
+ const projectsRoot = cfg ? resolve13(join19(cfg, "projects")) : null;
10993
11024
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
10994
11025
  return c.json({ error: "bad session reference" }, 400);
10995
11026
  }
10996
- const jsonlPath = resolve13(join18(projectDir, `${sessionId}.jsonl`));
11027
+ const jsonlPath = resolve13(join19(projectDir, `${sessionId}.jsonl`));
10997
11028
  if (!jsonlPath.startsWith(projectsRoot + sep3)) {
10998
11029
  return c.json({ error: "bad session reference" }, 400);
10999
11030
  }
@@ -11012,7 +11043,7 @@ data: ${JSON.stringify(turn)}
11012
11043
  start(controller) {
11013
11044
  const fileEnd0 = (() => {
11014
11045
  try {
11015
- return statSync6(jsonlPath).size;
11046
+ return statSync7(jsonlPath).size;
11016
11047
  } catch {
11017
11048
  return 0;
11018
11049
  }
@@ -11020,9 +11051,9 @@ data: ${JSON.stringify(turn)}
11020
11051
  let offset = resumeOffset(lastEventId, fileEnd0);
11021
11052
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
11022
11053
  const sessionKey = c.req.query("session_key") ?? "";
11023
- const subagentsDir = resolve13(join18(projectDir, sessionId, "subagents"));
11054
+ const subagentsDir = resolve13(join19(projectDir, sessionId, "subagents"));
11024
11055
  console.log(
11025
- `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync12(subagentsDir)}`
11056
+ `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync13(subagentsDir)}`
11026
11057
  );
11027
11058
  const actx = makeActivityCtx({
11028
11059
  subagentsDir,
@@ -11136,10 +11167,10 @@ app5.get("/directives", requireAdminSession, (c) => {
11136
11167
  const sessionId = c.req.query("sessionId") ?? "";
11137
11168
  if (!SESSION_ID_RE2.test(sessionId)) return c.json({ error: "bad session reference" }, 400);
11138
11169
  const dir = directiveStoreDir(sessionId);
11139
- if (!dir || !existsSync12(dir)) return c.json({ entries: [] });
11170
+ if (!dir || !existsSync13(dir)) return c.json({ entries: [] });
11140
11171
  let names;
11141
11172
  try {
11142
- names = readdirSync13(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
11173
+ names = readdirSync14(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
11143
11174
  } catch {
11144
11175
  return c.json({ entries: [] });
11145
11176
  }
@@ -11149,7 +11180,7 @@ app5.get("/directives", requireAdminSession, (c) => {
11149
11180
  const pid = Number(pidPart);
11150
11181
  let len = 0;
11151
11182
  try {
11152
- len = statSync6(join18(dir, name)).size;
11183
+ len = statSync7(join19(dir, name)).size;
11153
11184
  } catch {
11154
11185
  }
11155
11186
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -11164,7 +11195,7 @@ app5.get("/directive", requireAdminSession, (c) => {
11164
11195
  }
11165
11196
  const dir = directiveStoreDir(sessionId);
11166
11197
  if (!dir) return c.json({ error: "no account" }, 404);
11167
- const path3 = resolve13(join18(dir, name));
11198
+ const path3 = resolve13(join19(dir, name));
11168
11199
  if (!path3.startsWith(dir + sep3)) return c.json({ error: "bad reference" }, 400);
11169
11200
  let body;
11170
11201
  try {
@@ -11222,7 +11253,7 @@ app5.get("/store-stream", requireAdminSession, (c) => {
11222
11253
  console.log(`[wa-reader] op=store-quote msgId=${r.msgKeyId} quoted=${!!q}`);
11223
11254
  }
11224
11255
  if (r.attachmentId) {
11225
- const meta = readAttachmentMeta(join18(uploadsBase, r.attachmentId));
11256
+ const meta = readAttachmentMeta(join19(uploadsBase, r.attachmentId));
11226
11257
  if (meta) return { ...turn, attachments: [meta] };
11227
11258
  }
11228
11259
  return turn;
@@ -11255,7 +11286,7 @@ data: ${JSON.stringify(payload)}
11255
11286
  };
11256
11287
  const fileEnd0 = (() => {
11257
11288
  try {
11258
- return statSync6(file).size;
11289
+ return statSync7(file).size;
11259
11290
  } catch {
11260
11291
  return 0;
11261
11292
  }
@@ -11473,7 +11504,7 @@ app5.post("/reply", requireAdminSession, async (c) => {
11473
11504
  const absolute = resolved.absolute;
11474
11505
  let size = -1;
11475
11506
  try {
11476
- const st = statSync6(absolute);
11507
+ const st = statSync7(absolute);
11477
11508
  size = st.isFile() ? st.size : -1;
11478
11509
  } catch {
11479
11510
  size = -1;
@@ -11597,8 +11628,8 @@ app5.post("/reply", requireAdminSession, async (c) => {
11597
11628
  var whatsapp_reader_default = app5;
11598
11629
 
11599
11630
  // server/routes/public-reader.ts
11600
- import { statSync as statSync7, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync20, readdirSync as readdirSync14 } from "fs";
11601
- import { basename as basename5, dirname as dirname6, join as join19, resolve as resolve14, sep as sep4 } from "path";
11631
+ import { statSync as statSync8, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync20, readdirSync as readdirSync15 } from "fs";
11632
+ import { basename as basename5, dirname as dirname6, join as join20, resolve as resolve14, sep as sep4 } from "path";
11602
11633
 
11603
11634
  // app/lib/whatsapp-reader/delivered-kinds.ts
11604
11635
  var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
@@ -11672,10 +11703,10 @@ function enumeratePublicRows() {
11672
11703
  const cfg = claudeConfigDir();
11673
11704
  if (!cfg) return [];
11674
11705
  const rows = [];
11675
- for (const { path: path3 } of enumerateJsonls(join19(cfg, "projects"))) {
11706
+ for (const { path: path3 } of enumerateJsonls(join20(cfg, "projects"))) {
11676
11707
  const sessionId = basename5(path3).replace(/\.jsonl$/, "");
11677
11708
  const projectDir = dirname6(path3);
11678
- const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
11709
+ const meta = readSidecarMeta(join20(projectDir, `${sessionId}.meta.json`));
11679
11710
  rows.push({
11680
11711
  sessionId,
11681
11712
  projectDir,
@@ -11731,7 +11762,7 @@ function enrichPublicAttachments(turns, sessionAttachments, cursor) {
11731
11762
  }
11732
11763
  }
11733
11764
  function readFrom2(path3, from) {
11734
- const end = statSync7(path3).size;
11765
+ const end = statSync8(path3).size;
11735
11766
  if (end <= from) return { buf: Buffer.alloc(0), end: from };
11736
11767
  const fd = openSync2(path3, "r");
11737
11768
  try {
@@ -11751,15 +11782,15 @@ app6.get("/stream", (c) => {
11751
11782
  const sessionId = c.req.query("sessionId") ?? "";
11752
11783
  const projectDir = c.req.query("projectDir") ?? "";
11753
11784
  const cfg = claudeConfigDir();
11754
- const projectsRoot = cfg ? resolve14(join19(cfg, "projects")) : null;
11785
+ const projectsRoot = cfg ? resolve14(join20(cfg, "projects")) : null;
11755
11786
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
11756
11787
  return c.json({ error: "bad session reference" }, 400);
11757
11788
  }
11758
- const jsonlPath = resolve14(join19(projectDir, `${sessionId}.jsonl`));
11789
+ const jsonlPath = resolve14(join20(projectDir, `${sessionId}.jsonl`));
11759
11790
  if (!jsonlPath.startsWith(projectsRoot + sep4)) {
11760
11791
  return c.json({ error: "bad session reference" }, 400);
11761
11792
  }
11762
- const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
11793
+ const meta = readSidecarMeta(join20(projectDir, `${sessionId}.meta.json`));
11763
11794
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
11764
11795
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
11765
11796
  if (!(isPublicWebchat && owns)) {
@@ -11872,7 +11903,7 @@ app6.get("/attachment/:attachmentId", (c) => {
11872
11903
  let dataFile;
11873
11904
  let buffer;
11874
11905
  try {
11875
- dataFile = readdirSync14(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
11906
+ dataFile = readdirSync15(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
11876
11907
  if (!dataFile) throw new Error("no data file");
11877
11908
  buffer = readFileSync20(resolve14(dir, dataFile));
11878
11909
  } catch {
@@ -11896,16 +11927,16 @@ var public_reader_default = app6;
11896
11927
 
11897
11928
  // server/routes/webchat.ts
11898
11929
  import { basename as basename6, dirname as dirname7 } from "path";
11899
- import { join as join22 } from "path";
11900
- import { existsSync as existsSync14, readdirSync as readdirSync16, readFileSync as readFileSync23, renameSync as renameSync4, statSync as statSync8, writeFileSync as writeFileSync8 } from "fs";
11930
+ import { join as join23 } from "path";
11931
+ import { existsSync as existsSync15, readdirSync as readdirSync17, readFileSync as readFileSync23, renameSync as renameSync4, statSync as statSync9, writeFileSync as writeFileSync8 } from "fs";
11901
11932
 
11902
11933
  // server/canonical-webchat-override.ts
11903
11934
  import { readFileSync as readFileSync21, writeFileSync as writeFileSync6, renameSync as renameSync2 } from "fs";
11904
- import { join as join20 } from "path";
11935
+ import { join as join21 } from "path";
11905
11936
  var FILE = "canonical-webchat-session.json";
11906
11937
  var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
11907
11938
  function canonicalOverridePath(accountDir) {
11908
- return join20(accountDir, FILE);
11939
+ return join21(accountDir, FILE);
11909
11940
  }
11910
11941
  function readRaw(accountDir) {
11911
11942
  try {
@@ -11984,8 +12015,8 @@ function isNewSessionEffortLevel(value) {
11984
12015
  }
11985
12016
 
11986
12017
  // ../services/claude-session-manager/src/sidecar-store.ts
11987
- import { existsSync as existsSync13, mkdirSync as mkdirSync4, readdirSync as readdirSync15, readFileSync as readFileSync22, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
11988
- import { join as join21 } from "path";
12018
+ import { existsSync as existsSync14, mkdirSync as mkdirSync4, readdirSync as readdirSync16, readFileSync as readFileSync22, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
12019
+ import { join as join22 } from "path";
11989
12020
  function escapeRegExp(s) {
11990
12021
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11991
12022
  }
@@ -11993,7 +12024,7 @@ function createSidecarStore(config) {
11993
12024
  const { suffix, validate: validate2 } = config;
11994
12025
  const suffixRe = new RegExp(`${escapeRegExp(suffix)}$`);
11995
12026
  function pathFor(sessionsDir, id) {
11996
- return join21(sessionsDir, `${id}${suffix}`);
12027
+ return join22(sessionsDir, `${id}${suffix}`);
11997
12028
  }
11998
12029
  function write(sessionsDir, id, record) {
11999
12030
  mkdirSync4(sessionsDir, { recursive: true });
@@ -12005,7 +12036,7 @@ function createSidecarStore(config) {
12005
12036
  return { ok: true };
12006
12037
  } catch (error) {
12007
12038
  try {
12008
- if (existsSync13(tmp)) unlinkSync2(tmp);
12039
+ if (existsSync14(tmp)) unlinkSync2(tmp);
12009
12040
  } catch {
12010
12041
  }
12011
12042
  return { ok: false, error };
@@ -12030,14 +12061,14 @@ function createSidecarStore(config) {
12030
12061
  function readAll(sessionsDir, onSkip) {
12031
12062
  let names;
12032
12063
  try {
12033
- names = readdirSync15(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
12064
+ names = readdirSync16(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
12034
12065
  } catch {
12035
12066
  return [];
12036
12067
  }
12037
12068
  const out = [];
12038
12069
  for (const name of names) {
12039
12070
  if (!suffixRe.test(name)) continue;
12040
- const path3 = join21(sessionsDir, name);
12071
+ const path3 = join22(sessionsDir, name);
12041
12072
  let raw;
12042
12073
  try {
12043
12074
  raw = readFileSync22(path3, "utf8");
@@ -12061,7 +12092,7 @@ function createSidecarStore(config) {
12061
12092
  function clear(sessionsDir, id) {
12062
12093
  const path3 = pathFor(sessionsDir, id);
12063
12094
  try {
12064
- if (existsSync13(path3)) {
12095
+ if (existsSync14(path3)) {
12065
12096
  unlinkSync2(path3);
12066
12097
  return { ok: true, removed: true };
12067
12098
  }
@@ -12114,22 +12145,22 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
12114
12145
  function locateSession(sessionId) {
12115
12146
  const dir = findSessionProjectDir(sessionId);
12116
12147
  if (!dir) return { projectDir: null, channel: null, accountId: null };
12117
- const meta = readSidecarMeta(join22(dir, `${sessionId}.meta.json`));
12148
+ const meta = readSidecarMeta(join23(dir, `${sessionId}.meta.json`));
12118
12149
  return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
12119
12150
  }
12120
12151
  function locateSidecar(sessionId) {
12121
12152
  const cfg = claudeConfigDir();
12122
12153
  if (!cfg) return null;
12123
- const projectsRoot = join22(cfg, "projects");
12154
+ const projectsRoot = join23(cfg, "projects");
12124
12155
  let slugs;
12125
12156
  try {
12126
- slugs = readdirSync16(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12157
+ slugs = readdirSync17(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12127
12158
  } catch {
12128
12159
  return null;
12129
12160
  }
12130
12161
  for (const slug of slugs) {
12131
- const metaPath = join22(projectsRoot, slug, `${sessionId}.meta.json`);
12132
- if (existsSync14(metaPath)) {
12162
+ const metaPath = join23(projectsRoot, slug, `${sessionId}.meta.json`);
12163
+ if (existsSync15(metaPath)) {
12133
12164
  const meta = readSidecarMeta(metaPath);
12134
12165
  return { channel: meta.channel, adminUserId: meta.adminUserId, accountId: meta.accountId };
12135
12166
  }
@@ -12141,7 +12172,7 @@ function readTargetOwner(sessionId) {
12141
12172
  if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
12142
12173
  const { projectDir } = locateSession(sessionId);
12143
12174
  if (projectDir !== null) {
12144
- return { found: true, owner: readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`)).adminUserId };
12175
+ return { found: true, owner: readSidecarMeta(join23(projectDir, `${sessionId}.meta.json`)).adminUserId };
12145
12176
  }
12146
12177
  return { found: false, owner: null };
12147
12178
  }
@@ -12155,7 +12186,7 @@ function sessionSidecarExists(sessionId) {
12155
12186
  function jsonlSizeBytes(projectDir, sessionId) {
12156
12187
  if (projectDir === null) return null;
12157
12188
  try {
12158
- return statSync8(join22(projectDir, `${sessionId}.jsonl`)).size;
12189
+ return statSync9(join23(projectDir, `${sessionId}.jsonl`)).size;
12159
12190
  } catch {
12160
12191
  return null;
12161
12192
  }
@@ -12291,15 +12322,15 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
12291
12322
  const cfg = claudeConfigDir();
12292
12323
  if (!cfg) return null;
12293
12324
  let best = null;
12294
- for (const { path: path3, isSubagent, archived } of enumerateJsonls(join22(cfg, "projects"))) {
12325
+ for (const { path: path3, isSubagent, archived } of enumerateJsonls(join23(cfg, "projects"))) {
12295
12326
  if (isSubagent || archived) continue;
12296
12327
  const id = basename6(path3).slice(0, -".jsonl".length);
12297
- const meta = readSidecarMeta(join22(dirname7(path3), `${id}.meta.json`));
12328
+ const meta = readSidecarMeta(join23(dirname7(path3), `${id}.meta.json`));
12298
12329
  if (meta.role !== "admin" || meta.channel !== "webchat") continue;
12299
12330
  if (multiAccount && meta.accountId !== scopeAccountId) continue;
12300
12331
  let mtimeMs;
12301
12332
  try {
12302
- mtimeMs = statSync8(path3).mtimeMs;
12333
+ mtimeMs = statSync9(path3).mtimeMs;
12303
12334
  } catch {
12304
12335
  continue;
12305
12336
  }
@@ -12616,7 +12647,7 @@ ${note}` : note;
12616
12647
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
12617
12648
  return c.json({ error: "account unresolved" }, 503);
12618
12649
  }
12619
- const accountJsonPath = join22(account.accountDir, "account.json");
12650
+ const accountJsonPath = join23(account.accountDir, "account.json");
12620
12651
  try {
12621
12652
  const parsed = JSON.parse(readFileSync23(accountJsonPath, "utf8"));
12622
12653
  if (op === "model") parsed.adminModel = value;
@@ -12664,7 +12695,7 @@ ${note}` : note;
12664
12695
  const cfg2 = claudeConfigDir();
12665
12696
  if (cfg2) {
12666
12697
  const source2 = resolveBridgeSource(
12667
- join22(cfg2, "sessions"),
12698
+ join23(cfg2, "sessions"),
12668
12699
  target,
12669
12700
  (id) => locateSession(id).projectDir !== null
12670
12701
  );
@@ -12696,7 +12727,7 @@ ${note}` : note;
12696
12727
  const cfg = claudeConfigDir();
12697
12728
  let projectDir = null;
12698
12729
  if (cfg) {
12699
- for (const { path: path3 } of enumerateJsonls(join22(cfg, "projects"))) {
12730
+ for (const { path: path3 } of enumerateJsonls(join23(cfg, "projects"))) {
12700
12731
  if (basename6(path3) === `${sessionId}.jsonl`) {
12701
12732
  projectDir = dirname7(path3);
12702
12733
  break;
@@ -12704,7 +12735,7 @@ ${note}` : note;
12704
12735
  }
12705
12736
  }
12706
12737
  if (source === "latest" && requesterUserId !== null) {
12707
- const owner = readSidecarMeta(join22(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
12738
+ const owner = readSidecarMeta(join23(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
12708
12739
  if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
12709
12740
  console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
12710
12741
  }
@@ -12736,8 +12767,8 @@ ${note}` : note;
12736
12767
  import { resolve as resolve15 } from "path";
12737
12768
 
12738
12769
  // app/lib/claude-agent/specialist-roster.ts
12739
- import { existsSync as existsSync15, readFileSync as readFileSync24, readdirSync as readdirSync17 } from "fs";
12740
- import { join as join23 } from "path";
12770
+ import { existsSync as existsSync16, readFileSync as readFileSync24, readdirSync as readdirSync18 } from "fs";
12771
+ import { join as join24 } from "path";
12741
12772
  function field(fm, name) {
12742
12773
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
12743
12774
  if (!m) return null;
@@ -12748,15 +12779,15 @@ function field(fm, name) {
12748
12779
  return value || null;
12749
12780
  }
12750
12781
  function readSpecialistRoster(specialistsDir) {
12751
- if (!existsSync15(specialistsDir)) return { specialists: [], skipped: [] };
12752
- const entries = readdirSync17(specialistsDir);
12782
+ if (!existsSync16(specialistsDir)) return { specialists: [], skipped: [] };
12783
+ const entries = readdirSync18(specialistsDir);
12753
12784
  const specialists = [];
12754
12785
  const skipped = [];
12755
12786
  for (const file of entries.sort()) {
12756
12787
  if (!file.endsWith(".md")) continue;
12757
12788
  let raw;
12758
12789
  try {
12759
- raw = readFileSync24(join23(specialistsDir, file), "utf-8");
12790
+ raw = readFileSync24(join24(specialistsDir, file), "utf-8");
12760
12791
  } catch (err) {
12761
12792
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
12762
12793
  continue;
@@ -12873,8 +12904,8 @@ var webchat_greeting_default = app7;
12873
12904
 
12874
12905
  // server/routes/telegram.ts
12875
12906
  import { homedir as homedir2 } from "os";
12876
- import { resolve as resolve16, join as join24 } from "path";
12877
- import { existsSync as existsSync16, readFileSync as readFileSync25 } from "fs";
12907
+ import { resolve as resolve16, join as join25 } from "path";
12908
+ import { existsSync as existsSync17, readFileSync as readFileSync25 } from "fs";
12878
12909
 
12879
12910
  // app/lib/telegram/gateway/instance.ts
12880
12911
  var instance = null;
@@ -12933,8 +12964,8 @@ function routeTelegramUpdate(input) {
12933
12964
  var TAG27 = "[telegram-inbound]";
12934
12965
  function configDirName() {
12935
12966
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? resolve16(process.cwd(), "..");
12936
- const brandPath = join24(platformRoot5, "config", "brand.json");
12937
- if (existsSync16(brandPath)) {
12967
+ const brandPath = join25(platformRoot5, "config", "brand.json");
12968
+ if (existsSync17(brandPath)) {
12938
12969
  try {
12939
12970
  return JSON.parse(readFileSync25(brandPath, "utf-8")).configDir ?? ".maxy";
12940
12971
  } catch {
@@ -12955,7 +12986,7 @@ app8.post("/", async (c) => {
12955
12986
  return c.json({ ok: false }, 400);
12956
12987
  }
12957
12988
  const sp = secretPath(botType);
12958
- if (!existsSync16(sp)) {
12989
+ if (!existsSync17(sp)) {
12959
12990
  console.error(`${TAG27} op=reject reason=no-secret-file botType=${botType}`);
12960
12991
  return c.json({ ok: false }, 401);
12961
12992
  }
@@ -13022,21 +13053,21 @@ app8.post("/", async (c) => {
13022
13053
  var telegram_default = app8;
13023
13054
 
13024
13055
  // server/routes/quickbooks.ts
13025
- import { join as join25 } from "path";
13026
- import { existsSync as existsSync17, readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5, rmSync, renameSync as renameSync5 } from "fs";
13056
+ import { join as join26 } from "path";
13057
+ import { existsSync as existsSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5, rmSync, renameSync as renameSync5 } from "fs";
13027
13058
  var TAG28 = "[quickbooks]";
13028
13059
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
13029
13060
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
13030
13061
  function pendingPath(accountDir, state) {
13031
- return join25(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
13062
+ return join26(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
13032
13063
  }
13033
13064
  function storePath(accountDir) {
13034
- return join25(accountDir, "secrets", "quickbooks.json");
13065
+ return join26(accountDir, "secrets", "quickbooks.json");
13035
13066
  }
13036
13067
  async function completeConsent(args) {
13037
13068
  const { accountDir, code, realmId } = args;
13038
13069
  const state = args.state;
13039
- if (!state || !STATE_RE.test(state) || !existsSync17(pendingPath(accountDir, state))) {
13070
+ if (!state || !STATE_RE.test(state) || !existsSync18(pendingPath(accountDir, state))) {
13040
13071
  console.error(`${TAG28} op=callback state=${state ?? ""} stateValid=false realmId=${realmId ?? ""}`);
13041
13072
  return { ok: false, status: 400, message: "Invalid or unknown authorization state.", stateValid: false };
13042
13073
  }
@@ -13063,7 +13094,7 @@ async function completeConsent(args) {
13063
13094
  if (!code || !realmId) {
13064
13095
  return { ok: false, status: 400, message: "Missing code or realmId in the callback.", stateValid: true };
13065
13096
  }
13066
- if (!existsSync17(storePath(accountDir))) {
13097
+ if (!existsSync18(storePath(accountDir))) {
13067
13098
  return { ok: false, status: 500, message: "No QuickBooks credentials are stored for this account.", stateValid: true };
13068
13099
  }
13069
13100
  const store2 = JSON.parse(readFileSync26(storePath(accountDir), "utf-8"));
@@ -13098,7 +13129,7 @@ async function completeConsent(args) {
13098
13129
  refreshTokenExpiry: now + (body.x_refresh_token_expires_in ?? 864e4) * 1e3,
13099
13130
  lastRefresh: now
13100
13131
  };
13101
- mkdirSync5(join25(accountDir, "secrets"), { recursive: true });
13132
+ mkdirSync5(join26(accountDir, "secrets"), { recursive: true });
13102
13133
  writeFileSync9(storePath(accountDir), JSON.stringify(store2, null, 2), { mode: 384 });
13103
13134
  const persisted = JSON.parse(readFileSync26(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
13104
13135
  console.error(`${TAG28} op=token-exchange realmId=${realmId} persisted=${persisted}`);
@@ -13131,7 +13162,7 @@ var quickbooks_default = app9;
13131
13162
 
13132
13163
  // server/routes/onboarding.ts
13133
13164
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
13134
- import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync11, writeSync, existsSync as existsSync19, readFileSync as readFileSync28, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
13165
+ import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync11, writeSync, existsSync as existsSync20, readFileSync as readFileSync28, unlinkSync as unlinkSync3, renameSync as renameSync7 } from "fs";
13135
13166
  import { createHash as createHash4, randomUUID as randomUUID8 } from "crypto";
13136
13167
 
13137
13168
  // app/lib/claude-spawn-env.ts
@@ -13140,7 +13171,7 @@ function claudeBin() {
13140
13171
  }
13141
13172
 
13142
13173
  // server/routes/onboarding.ts
13143
- import { dirname as dirname9, join as join27 } from "path";
13174
+ import { dirname as dirname9, join as join28 } from "path";
13144
13175
 
13145
13176
  // app/lib/claude-keychain.ts
13146
13177
  import { execFileSync as execFileSync2 } from "child_process";
@@ -13269,8 +13300,8 @@ function readHostCredsBlob(service) {
13269
13300
  }
13270
13301
 
13271
13302
  // ../lib/admins-write/src/index.ts
13272
- import { existsSync as existsSync18, readFileSync as readFileSync27, writeFileSync as writeFileSync10, renameSync as renameSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync18, statSync as statSync9, appendFileSync as appendFileSync3 } from "fs";
13273
- import { dirname as dirname8, join as join26 } from "path";
13303
+ import { existsSync as existsSync19, readFileSync as readFileSync27, writeFileSync as writeFileSync10, renameSync as renameSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync19, statSync as statSync10, appendFileSync as appendFileSync3 } from "fs";
13304
+ import { dirname as dirname8, join as join27 } from "path";
13274
13305
  function id8(value) {
13275
13306
  return value.slice(0, 8);
13276
13307
  }
@@ -13311,7 +13342,7 @@ function writeAdminEntry(input) {
13311
13342
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
13312
13343
  try {
13313
13344
  let users = [];
13314
- if (existsSync18(input.usersFile)) {
13345
+ if (existsSync19(input.usersFile)) {
13315
13346
  const raw = readFileSync27(input.usersFile, "utf-8").trim();
13316
13347
  if (raw) {
13317
13348
  const parsed = JSON.parse(raw);
@@ -13343,8 +13374,8 @@ function writeAdminEntry(input) {
13343
13374
  return result;
13344
13375
  }
13345
13376
  try {
13346
- const accountJsonPath = join26(input.accountDir, "account.json");
13347
- if (!existsSync18(accountJsonPath)) {
13377
+ const accountJsonPath = join27(input.accountDir, "account.json");
13378
+ if (!existsSync19(accountJsonPath)) {
13348
13379
  throw new Error(`account.json not found at ${accountJsonPath}`);
13349
13380
  }
13350
13381
  const config = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
@@ -13367,7 +13398,7 @@ function writeAdminEntry(input) {
13367
13398
  function computeAdminStoreDivergence(input) {
13368
13399
  const result = { divergences: 0, accountWithoutUsers: [], usersWithoutAccount: [], errors: [] };
13369
13400
  const usersUserIds = /* @__PURE__ */ new Set();
13370
- if (existsSync18(input.usersFile)) {
13401
+ if (existsSync19(input.usersFile)) {
13371
13402
  try {
13372
13403
  const raw = readFileSync27(input.usersFile, "utf-8").trim();
13373
13404
  if (raw) {
@@ -13381,24 +13412,24 @@ function computeAdminStoreDivergence(input) {
13381
13412
  }
13382
13413
  }
13383
13414
  const accountUserIds = /* @__PURE__ */ new Set();
13384
- if (existsSync18(input.accountsDir)) {
13415
+ if (existsSync19(input.accountsDir)) {
13385
13416
  let entries;
13386
13417
  try {
13387
- entries = readdirSync18(input.accountsDir);
13418
+ entries = readdirSync19(input.accountsDir);
13388
13419
  } catch (err) {
13389
13420
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
13390
13421
  return result;
13391
13422
  }
13392
13423
  for (const entry of entries) {
13393
13424
  if (entry.startsWith(".")) continue;
13394
- const accountDir = join26(input.accountsDir, entry);
13425
+ const accountDir = join27(input.accountsDir, entry);
13395
13426
  try {
13396
- if (!statSync9(accountDir).isDirectory()) continue;
13427
+ if (!statSync10(accountDir).isDirectory()) continue;
13397
13428
  } catch {
13398
13429
  continue;
13399
13430
  }
13400
- const accountJsonPath = join26(accountDir, "account.json");
13401
- if (!existsSync18(accountJsonPath)) continue;
13431
+ const accountJsonPath = join27(accountDir, "account.json");
13432
+ if (!existsSync19(accountJsonPath)) continue;
13402
13433
  let admins = [];
13403
13434
  try {
13404
13435
  const config = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
@@ -13449,7 +13480,7 @@ function hashPin2(pin) {
13449
13480
  return createHash4("sha256").update(pin).digest("hex");
13450
13481
  }
13451
13482
  function readUsersFile2() {
13452
- if (!existsSync19(USERS_FILE)) return null;
13483
+ if (!existsSync20(USERS_FILE)) return null;
13453
13484
  const raw = readFileSync28(USERS_FILE, "utf-8").trim();
13454
13485
  if (!raw) return [];
13455
13486
  return JSON.parse(raw);
@@ -13509,7 +13540,7 @@ app10.post("/claude-auth", async (c) => {
13509
13540
  } catch (err) {
13510
13541
  logoutError = err instanceof Error ? err.message : String(err);
13511
13542
  }
13512
- const credentialsPresent = existsSync19(CLAUDE_CREDENTIALS_FILE);
13543
+ const credentialsPresent = existsSync20(CLAUDE_CREDENTIALS_FILE);
13513
13544
  const ranMs = Date.now() - start;
13514
13545
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
13515
13546
  return c.json({ logged_out: !credentialsPresent });
@@ -13575,7 +13606,7 @@ app10.post("/claude-auth", async (c) => {
13575
13606
  });
13576
13607
  persistKeychainService(
13577
13608
  writebackResult,
13578
- (service) => writeFileSync11(join27(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13609
+ (service) => writeFileSync11(join28(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13579
13610
  (line) => console.log(line)
13580
13611
  );
13581
13612
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -13658,7 +13689,7 @@ app10.post("/set-pin", async (c) => {
13658
13689
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
13659
13690
  if (process.platform === "linux") {
13660
13691
  let installOwner = null;
13661
- if (existsSync19(INSTALL_OWNER_FILE)) {
13692
+ if (existsSync20(INSTALL_OWNER_FILE)) {
13662
13693
  try {
13663
13694
  const raw = readFileSync28(INSTALL_OWNER_FILE, "utf-8").trim();
13664
13695
  if (raw.length > 0) installOwner = raw;
@@ -13806,7 +13837,7 @@ app10.put("/set-pin", requireAdminSession, async (c) => {
13806
13837
  console.log(`[set-pin] changed PIN in place: userId=${sessionUserId.slice(0, 8)}\u2026`);
13807
13838
  if (process.platform === "linux") {
13808
13839
  let installOwner = null;
13809
- if (existsSync19(INSTALL_OWNER_FILE)) {
13840
+ if (existsSync20(INSTALL_OWNER_FILE)) {
13810
13841
  try {
13811
13842
  const raw = readFileSync28(INSTALL_OWNER_FILE, "utf-8").trim();
13812
13843
  if (raw.length > 0) installOwner = raw;
@@ -13840,9 +13871,9 @@ ${body.newPin}
13840
13871
  var onboarding_default = app10;
13841
13872
 
13842
13873
  // server/routes/client-error.ts
13843
- import { appendFileSync as appendFileSync4, existsSync as existsSync20, renameSync as renameSync8, statSync as statSync10 } from "fs";
13844
- import { join as join28 } from "path";
13845
- var CLIENT_ERRORS_LOG = join28(LOG_DIR, "client-errors.log");
13874
+ import { appendFileSync as appendFileSync4, existsSync as existsSync21, renameSync as renameSync8, statSync as statSync11 } from "fs";
13875
+ import { join as join29 } from "path";
13876
+ var CLIENT_ERRORS_LOG = join29(LOG_DIR, "client-errors.log");
13846
13877
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
13847
13878
  var MAX_BODY_SIZE = 8 * 1024;
13848
13879
  var MAX_STACK_LEN = 2e3;
@@ -13890,8 +13921,8 @@ function stackHead(stack) {
13890
13921
  }
13891
13922
  function rotateIfNeeded() {
13892
13923
  try {
13893
- if (!existsSync20(CLIENT_ERRORS_LOG)) return;
13894
- const stats = statSync10(CLIENT_ERRORS_LOG);
13924
+ if (!existsSync21(CLIENT_ERRORS_LOG)) return;
13925
+ const stats = statSync11(CLIENT_ERRORS_LOG);
13895
13926
  if (stats.size < MAX_LOG_SIZE) return;
13896
13927
  renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13897
13928
  } catch (err) {
@@ -14217,18 +14248,18 @@ app13.get("/", requireAdminSession, async (c) => {
14217
14248
  var accounts_default = app13;
14218
14249
 
14219
14250
  // server/routes/admin/logs.ts
14220
- import { existsSync as existsSync22, readdirSync as readdirSync19, readFileSync as readFileSync29, statSync as statSync11 } from "fs";
14251
+ import { existsSync as existsSync23, readdirSync as readdirSync20, readFileSync as readFileSync29, statSync as statSync12 } from "fs";
14221
14252
  import { resolve as resolve17, basename as basename7 } from "path";
14222
14253
 
14223
14254
  // app/lib/logs-read-resolve.ts
14224
- import { existsSync as existsSync21 } from "fs";
14225
- import { join as join29 } from "path";
14255
+ import { existsSync as existsSync22 } from "fs";
14256
+ import { join as join30 } from "path";
14226
14257
  function resolveSessionLogPaths(filename, logDirs) {
14227
14258
  const tried = [filename];
14228
14259
  const hits = [];
14229
14260
  for (const dir of logDirs) {
14230
- const fullPath = join29(dir, filename);
14231
- if (existsSync21(fullPath)) {
14261
+ const fullPath = join30(dir, filename);
14262
+ if (existsSync22(fullPath)) {
14232
14263
  hits.push({ path: fullPath, dir });
14233
14264
  }
14234
14265
  }
@@ -14257,7 +14288,7 @@ app14.get("/", async (c) => {
14257
14288
  searched.push(filePath);
14258
14289
  try {
14259
14290
  const buffer = readFileSync29(filePath);
14260
- const onDiskBytes = statSync11(filePath).size;
14291
+ const onDiskBytes = statSync12(filePath).size;
14261
14292
  const headers = {
14262
14293
  "Content-Type": "text/plain; charset=utf-8",
14263
14294
  "Content-Length": String(buffer.byteLength)
@@ -14322,7 +14353,7 @@ app14.get("/", async (c) => {
14322
14353
  try {
14323
14354
  const filename = basename7(hit.path);
14324
14355
  const buffer = readFileSync29(hit.path);
14325
- const onDiskBytes = statSync11(hit.path).size;
14356
+ const onDiskBytes = statSync12(hit.path).size;
14326
14357
  const headers = {
14327
14358
  "Content-Type": "text/plain; charset=utf-8",
14328
14359
  "Content-Length": String(buffer.byteLength)
@@ -14356,16 +14387,16 @@ app14.get("/", async (c) => {
14356
14387
  const seen = /* @__PURE__ */ new Set();
14357
14388
  const logs = {};
14358
14389
  for (const dir of logDirs) {
14359
- if (!existsSync22(dir)) continue;
14390
+ if (!existsSync23(dir)) continue;
14360
14391
  let files;
14361
14392
  try {
14362
- files = readdirSync19(dir).filter((f) => f.endsWith(".log"));
14393
+ files = readdirSync20(dir).filter((f) => f.endsWith(".log"));
14363
14394
  } catch (err) {
14364
14395
  const reason = err instanceof Error ? err.message : String(err);
14365
14396
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
14366
14397
  continue;
14367
14398
  }
14368
- files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync11(resolve17(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
14399
+ files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync12(resolve17(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
14369
14400
  seen.add(name);
14370
14401
  try {
14371
14402
  const content = readFileSync29(resolve17(dir, name));
@@ -14408,7 +14439,7 @@ var claude_info_default = app15;
14408
14439
 
14409
14440
  // server/routes/admin/attachment.ts
14410
14441
  import { readFile as readFile2, readdir } from "fs/promises";
14411
- import { existsSync as existsSync23 } from "fs";
14442
+ import { existsSync as existsSync24 } from "fs";
14412
14443
  import { resolve as resolve18 } from "path";
14413
14444
  var app16 = new Hono();
14414
14445
  var ATTACHMENT_ID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -14431,12 +14462,12 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14431
14462
  }
14432
14463
  let accountId = pinnedAccountId;
14433
14464
  let dir = uploadsDirFor2(accountId, attachmentId);
14434
- let found = existsSync23(dir);
14465
+ let found = existsSync24(dir);
14435
14466
  if (!found) {
14436
14467
  for (const candidate of listValidAccounts()) {
14437
14468
  if (candidate.accountId === pinnedAccountId) continue;
14438
14469
  const candidateDir = uploadsDirFor2(candidate.accountId, attachmentId);
14439
- if (existsSync23(candidateDir)) {
14470
+ if (existsSync24(candidateDir)) {
14440
14471
  accountId = candidate.accountId;
14441
14472
  dir = candidateDir;
14442
14473
  found = true;
@@ -14451,7 +14482,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14451
14482
  return new Response("Not found", { status: 404 });
14452
14483
  }
14453
14484
  const metaPath = resolve18(dir, `${attachmentId}.meta.json`);
14454
- if (!existsSync23(metaPath)) {
14485
+ if (!existsSync24(metaPath)) {
14455
14486
  return new Response("Not found", { status: 404 });
14456
14487
  }
14457
14488
  let meta;
@@ -14485,21 +14516,21 @@ var attachment_default = app16;
14485
14516
 
14486
14517
  // server/routes/admin/agents.ts
14487
14518
  import { resolve as resolve19 } from "path";
14488
- import { readdirSync as readdirSync20, readFileSync as readFileSync30, existsSync as existsSync24, rmSync as rmSync2 } from "fs";
14519
+ import { readdirSync as readdirSync21, readFileSync as readFileSync30, existsSync as existsSync25, rmSync as rmSync2 } from "fs";
14489
14520
  var app17 = new Hono();
14490
14521
  app17.get("/", (c) => {
14491
14522
  const account = resolveAccount();
14492
14523
  if (!account) return c.json({ agents: [] });
14493
14524
  const agentsDir = resolve19(account.accountDir, "agents");
14494
- if (!existsSync24(agentsDir)) return c.json({ agents: [] });
14525
+ if (!existsSync25(agentsDir)) return c.json({ agents: [] });
14495
14526
  const agents = [];
14496
14527
  try {
14497
- const entries = readdirSync20(agentsDir, { withFileTypes: true });
14528
+ const entries = readdirSync21(agentsDir, { withFileTypes: true });
14498
14529
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
14499
14530
  if (!entry.isDirectory()) continue;
14500
14531
  if (entry.name === "admin") continue;
14501
14532
  const configPath2 = resolve19(agentsDir, entry.name, "config.json");
14502
- if (!existsSync24(configPath2)) continue;
14533
+ if (!existsSync25(configPath2)) continue;
14503
14534
  try {
14504
14535
  const config = JSON.parse(readFileSync30(configPath2, "utf-8"));
14505
14536
  agents.push({
@@ -14528,7 +14559,7 @@ app17.delete("/:slug", async (c) => {
14528
14559
  return c.json({ error: "Invalid agent slug" }, 400);
14529
14560
  }
14530
14561
  const agentDir = resolve19(account.accountDir, "agents", slug);
14531
- if (!existsSync24(agentDir)) {
14562
+ if (!existsSync25(agentDir)) {
14532
14563
  return c.json({ error: "Agent not found" }, 404);
14533
14564
  }
14534
14565
  try {
@@ -14558,7 +14589,7 @@ app17.post("/:slug/project", async (c) => {
14558
14589
  return c.json({ error: "Invalid agent slug" }, 400);
14559
14590
  }
14560
14591
  const agentDir = resolve19(account.accountDir, "agents", slug);
14561
- if (!existsSync24(agentDir)) {
14592
+ if (!existsSync25(agentDir)) {
14562
14593
  return c.json({ error: "Agent not found on disk" }, 404);
14563
14594
  }
14564
14595
  try {
@@ -14574,7 +14605,7 @@ var agents_default = app17;
14574
14605
  // server/routes/admin/sessions.ts
14575
14606
  import crypto2 from "crypto";
14576
14607
  import { resolve as resolvePath } from "path";
14577
- import { existsSync as existsSync25, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14608
+ import { existsSync as existsSync26, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14578
14609
 
14579
14610
  // ../lib/admin-conversation-purge/src/index.ts
14580
14611
  async function purgeAdminConversationJsonls(args) {
@@ -14734,7 +14765,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
14734
14765
  let reason = null;
14735
14766
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
14736
14767
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
14737
- else if (!existsSync25(a.storagePath)) reason = "missing-file";
14768
+ else if (!existsSync26(a.storagePath)) reason = "missing-file";
14738
14769
  if (reason) {
14739
14770
  invalid++;
14740
14771
  try {
@@ -15260,8 +15291,8 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
15260
15291
  var sessions_default = app18;
15261
15292
 
15262
15293
  // app/lib/claude-agent/spawn-context.ts
15263
- import { existsSync as existsSync26, readFileSync as readFileSync31, readdirSync as readdirSync21, statSync as statSync12 } from "fs";
15264
- import { dirname as dirname10, resolve as resolve20, join as join30 } from "path";
15294
+ import { existsSync as existsSync27, readFileSync as readFileSync31, readdirSync as readdirSync22, statSync as statSync13 } from "fs";
15295
+ import { dirname as dirname10, resolve as resolve20, join as join31 } from "path";
15265
15296
  async function resolveOwnerProfileBlock(accountId, userId) {
15266
15297
  if (!userId) return { ok: false, reason: "missing-user-id" };
15267
15298
  try {
@@ -15302,12 +15333,12 @@ function frontmatterField(manifest, field2) {
15302
15333
  function extractPluginToolDescriptions(pluginDir) {
15303
15334
  const out = /* @__PURE__ */ new Map();
15304
15335
  const candidates = [
15305
- join30(pluginDir, "mcp/dist/index.js"),
15306
- join30(pluginDir, "mcp/src/index.ts")
15336
+ join31(pluginDir, "mcp/dist/index.js"),
15337
+ join31(pluginDir, "mcp/src/index.ts")
15307
15338
  ];
15308
15339
  let raw = null;
15309
15340
  for (const path3 of candidates) {
15310
- if (!existsSync26(path3)) continue;
15341
+ if (!existsSync27(path3)) continue;
15311
15342
  try {
15312
15343
  raw = readFileSync31(path3, "utf-8");
15313
15344
  break;
@@ -15359,25 +15390,25 @@ function parseSkillPathsFromFrontmatter(fm) {
15359
15390
  function listPluginDirs() {
15360
15391
  const out = /* @__PURE__ */ new Map();
15361
15392
  const platformPlugins = resolve20(PLATFORM_ROOT, "plugins");
15362
- if (existsSync26(platformPlugins)) {
15363
- for (const name of readdirSync21(platformPlugins)) {
15364
- const dir = join30(platformPlugins, name);
15393
+ if (existsSync27(platformPlugins)) {
15394
+ for (const name of readdirSync22(platformPlugins)) {
15395
+ const dir = join31(platformPlugins, name);
15365
15396
  try {
15366
- if (statSync12(dir).isDirectory()) out.set(name, dir);
15397
+ if (statSync13(dir).isDirectory()) out.set(name, dir);
15367
15398
  } catch {
15368
15399
  }
15369
15400
  }
15370
15401
  }
15371
15402
  const premiumRoot = resolve20(dirname10(PLATFORM_ROOT), "premium-plugins");
15372
- if (existsSync26(premiumRoot)) {
15373
- for (const bundle of readdirSync21(premiumRoot)) {
15374
- const bundlePlugins = join30(premiumRoot, bundle, "plugins");
15375
- if (!existsSync26(bundlePlugins)) continue;
15403
+ if (existsSync27(premiumRoot)) {
15404
+ for (const bundle of readdirSync22(premiumRoot)) {
15405
+ const bundlePlugins = join31(premiumRoot, bundle, "plugins");
15406
+ if (!existsSync27(bundlePlugins)) continue;
15376
15407
  try {
15377
- for (const name of readdirSync21(bundlePlugins)) {
15378
- const dir = join30(bundlePlugins, name);
15408
+ for (const name of readdirSync22(bundlePlugins)) {
15409
+ const dir = join31(bundlePlugins, name);
15379
15410
  try {
15380
- if (statSync12(dir).isDirectory()) out.set(name, dir);
15411
+ if (statSync13(dir).isDirectory()) out.set(name, dir);
15381
15412
  } catch {
15382
15413
  }
15383
15414
  }
@@ -15389,7 +15420,7 @@ function listPluginDirs() {
15389
15420
  }
15390
15421
  function readEnabledPlugins(accountId) {
15391
15422
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15392
- if (!existsSync26(accountFile)) return /* @__PURE__ */ new Set();
15423
+ if (!existsSync27(accountFile)) return /* @__PURE__ */ new Set();
15393
15424
  try {
15394
15425
  const parsed = JSON.parse(readFileSync31(accountFile, "utf-8"));
15395
15426
  return new Set(
@@ -15400,7 +15431,7 @@ function readEnabledPlugins(accountId) {
15400
15431
  }
15401
15432
  }
15402
15433
  function readFrontmatter(path3) {
15403
- if (!existsSync26(path3)) return null;
15434
+ if (!existsSync27(path3)) return null;
15404
15435
  let raw;
15405
15436
  try {
15406
15437
  raw = readFileSync31(path3, "utf-8");
@@ -15418,7 +15449,7 @@ function computeActivePlugins(accountId) {
15418
15449
  for (const name of Array.from(enabled).sort()) {
15419
15450
  const dir = pluginDirs.get(name);
15420
15451
  if (!dir) continue;
15421
- const fm = readFrontmatter(join30(dir, "PLUGIN.md"));
15452
+ const fm = readFrontmatter(join31(dir, "PLUGIN.md"));
15422
15453
  if (!fm) continue;
15423
15454
  const description = frontmatterField(`---
15424
15455
  ${fm}
@@ -15435,7 +15466,7 @@ ${fm}
15435
15466
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
15436
15467
  );
15437
15468
  if (toolNames.length > 0 && descMap.size === 0) {
15438
- const hasSource = existsSync26(join30(dir, "mcp/dist/index.js")) || existsSync26(join30(dir, "mcp/src/index.ts"));
15469
+ const hasSource = existsSync27(join31(dir, "mcp/dist/index.js")) || existsSync27(join31(dir, "mcp/src/index.ts"));
15439
15470
  if (hasSource) {
15440
15471
  console.warn(
15441
15472
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -15445,7 +15476,7 @@ ${fm}
15445
15476
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
15446
15477
  const skills = [];
15447
15478
  for (const relPath of skillPaths) {
15448
- const skillPath = join30(dir, relPath);
15479
+ const skillPath = join31(dir, relPath);
15449
15480
  const skillFm = readFrontmatter(skillPath);
15450
15481
  if (!skillFm) continue;
15451
15482
  const skillName = frontmatterField(`---
@@ -15462,10 +15493,10 @@ ${skillFm}
15462
15493
  }
15463
15494
  function computeSpecialistDomains(accountId) {
15464
15495
  const specialistsDir = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
15465
- if (!existsSync26(specialistsDir)) return [];
15496
+ if (!existsSync27(specialistsDir)) return [];
15466
15497
  let entries;
15467
15498
  try {
15468
- entries = readdirSync21(specialistsDir);
15499
+ entries = readdirSync22(specialistsDir);
15469
15500
  } catch {
15470
15501
  return [];
15471
15502
  }
@@ -15489,7 +15520,7 @@ function computeSpecialistDomains(accountId) {
15489
15520
  const out = [];
15490
15521
  for (const file of entries.sort()) {
15491
15522
  if (!file.endsWith(".md")) continue;
15492
- const fm = readFrontmatter(join30(specialistsDir, file));
15523
+ const fm = readFrontmatter(join31(specialistsDir, file));
15493
15524
  if (!fm) continue;
15494
15525
  const wrapped = `---
15495
15526
  ${fm}
@@ -15508,7 +15539,7 @@ ${fm}
15508
15539
  }
15509
15540
  function computeDormantPlugins(accountId) {
15510
15541
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15511
- if (!existsSync26(accountFile)) return [];
15542
+ if (!existsSync27(accountFile)) return [];
15512
15543
  let enabled;
15513
15544
  try {
15514
15545
  const raw = readFileSync31(accountFile, "utf-8");
@@ -15523,10 +15554,10 @@ function computeDormantPlugins(accountId) {
15523
15554
  return [];
15524
15555
  }
15525
15556
  const pluginsDir = resolve20(PLATFORM_ROOT, "plugins");
15526
- if (!existsSync26(pluginsDir)) return [];
15557
+ if (!existsSync27(pluginsDir)) return [];
15527
15558
  let entries;
15528
15559
  try {
15529
- entries = readdirSync21(pluginsDir);
15560
+ entries = readdirSync22(pluginsDir);
15530
15561
  } catch {
15531
15562
  return [];
15532
15563
  }
@@ -15534,7 +15565,7 @@ function computeDormantPlugins(accountId) {
15534
15565
  for (const name of entries) {
15535
15566
  if (enabled.has(name)) continue;
15536
15567
  const manifestPath = resolve20(pluginsDir, name, "PLUGIN.md");
15537
- if (!existsSync26(manifestPath)) continue;
15568
+ if (!existsSync27(manifestPath)) continue;
15538
15569
  let manifest;
15539
15570
  try {
15540
15571
  manifest = readFileSync31(manifestPath, "utf-8");
@@ -15551,11 +15582,11 @@ function computeDormantPlugins(accountId) {
15551
15582
  }
15552
15583
 
15553
15584
  // server/routes/admin/claude-sessions.ts
15554
- import { existsSync as existsSync27, readFileSync as readFileSync32 } from "fs";
15585
+ import { existsSync as existsSync28, readFileSync as readFileSync32 } from "fs";
15555
15586
  import { resolve as resolve21 } from "path";
15556
15587
  function readTunnelState(brandConfigDir) {
15557
15588
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
15558
- if (!existsSync27(statePath)) return null;
15589
+ if (!existsSync28(statePath)) return null;
15559
15590
  try {
15560
15591
  const parsed = JSON.parse(readFileSync32(statePath, "utf-8"));
15561
15592
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
@@ -15813,11 +15844,11 @@ app21.post("/", async (c) => {
15813
15844
  var events_default = app21;
15814
15845
 
15815
15846
  // server/routes/admin/files.ts
15816
- import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync28 } from "fs";
15847
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync29 } from "fs";
15817
15848
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, unlink as unlink2, rename, rmdir } from "fs/promises";
15818
15849
  import { realpathSync as realpathSync6 } from "fs";
15819
15850
  import { randomUUID as randomUUID10 } from "crypto";
15820
- import { basename as basename9, dirname as dirname11, join as join32, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15851
+ import { basename as basename9, dirname as dirname11, join as join33, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15821
15852
  import { Readable as Readable2 } from "stream";
15822
15853
 
15823
15854
  // ../lib/graph-trash/src/index.ts
@@ -16054,7 +16085,7 @@ async function restoreNode(params) {
16054
16085
  }
16055
16086
 
16056
16087
  // app/lib/file-delete-cascade.ts
16057
- var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16088
+ var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16058
16089
  function parseAttachmentPath(relPath) {
16059
16090
  const segments = relPath.split("/").filter(Boolean);
16060
16091
  if (segments.length !== 5) return null;
@@ -16062,7 +16093,7 @@ function parseAttachmentPath(relPath) {
16062
16093
  const accountId = segments[1];
16063
16094
  const attachmentId = segments[3];
16064
16095
  const filename = segments[4];
16065
- if (!UUID_RE2.test(accountId) || !UUID_RE2.test(attachmentId)) return null;
16096
+ if (!UUID_RE3.test(accountId) || !UUID_RE3.test(attachmentId)) return null;
16066
16097
  const dot = filename.lastIndexOf(".");
16067
16098
  if (dot === -1) return null;
16068
16099
  const stem = filename.slice(0, dot);
@@ -16135,7 +16166,7 @@ async function cascadeDeleteDocument(params) {
16135
16166
 
16136
16167
  // app/lib/file-index.ts
16137
16168
  import * as fsp from "fs/promises";
16138
- import { resolve as resolve22, relative as relative3, join as join31, basename as basename8, extname as extname2, sep as sep5 } from "path";
16169
+ import { resolve as resolve22, relative as relative3, join as join32, basename as basename8, extname as extname2, sep as sep5 } from "path";
16139
16170
  import { tmpdir as tmpdir2 } from "os";
16140
16171
  import { execFile as execFile2 } from "child_process";
16141
16172
  import { promisify as promisify2 } from "util";
@@ -16217,7 +16248,7 @@ async function extractPdf(absolute) {
16217
16248
  return stdout.trim();
16218
16249
  }
16219
16250
  async function ocrPdf(absolute) {
16220
- const outPdf = join31(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
16251
+ const outPdf = join32(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
16221
16252
  try {
16222
16253
  await execFileAsync2(
16223
16254
  "ocrmypdf",
@@ -16279,7 +16310,7 @@ async function readDisplayName(absolute) {
16279
16310
  const stem = dot === -1 ? base : base.slice(0, dot);
16280
16311
  if (base === `${stem}.meta.json`) return null;
16281
16312
  try {
16282
- const raw = await fsp.readFile(join31(dir, `${stem}.meta.json`), "utf-8");
16313
+ const raw = await fsp.readFile(join32(dir, `${stem}.meta.json`), "utf-8");
16283
16314
  const meta = JSON.parse(raw);
16284
16315
  const dn = meta.displayName ?? meta.filename;
16285
16316
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -16300,7 +16331,7 @@ async function walkSubtree(root, dataRoot, out) {
16300
16331
  for (const entry of entries) {
16301
16332
  if (entry.isSymbolicLink()) continue;
16302
16333
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
16303
- const abs = join31(root, entry.name);
16334
+ const abs = join32(root, entry.name);
16304
16335
  if (entry.isDirectory()) {
16305
16336
  const sub = await walkSubtree(abs, dataRoot, out);
16306
16337
  if (!sub.clean) clean = false;
@@ -16653,10 +16684,10 @@ function buildZip(entries) {
16653
16684
 
16654
16685
  // server/routes/admin/files.ts
16655
16686
  var UPLOAD_TMP_DIR = ".uploads-tmp";
16656
- var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16687
+ var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16657
16688
  async function readMeta(absDir, baseName) {
16658
16689
  try {
16659
- const raw = await readFile4(join32(absDir, `${baseName}.meta.json`), "utf8");
16690
+ const raw = await readFile4(join33(absDir, `${baseName}.meta.json`), "utf8");
16660
16691
  const parsed = JSON.parse(raw);
16661
16692
  if (typeof parsed?.filename === "string") {
16662
16693
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -16675,7 +16706,7 @@ async function readAccountNames() {
16675
16706
  return map;
16676
16707
  }
16677
16708
  for (const name of names) {
16678
- if (!UUID_RE3.test(name)) continue;
16709
+ if (!UUID_RE4.test(name)) continue;
16679
16710
  const configPath2 = resolve23(accountsDir, name, "account.json");
16680
16711
  try {
16681
16712
  const raw = await readFile4(configPath2, "utf8");
@@ -16710,8 +16741,8 @@ async function servableFilesIn(dirAbs, uuid) {
16710
16741
  return out;
16711
16742
  }
16712
16743
  async function enrich(absolute, entry, accountNames) {
16713
- if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
16714
- const dirAbs = join32(absolute, entry.name);
16744
+ if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
16745
+ const dirAbs = join33(absolute, entry.name);
16715
16746
  const meta = await readMeta(dirAbs, entry.name);
16716
16747
  if (meta?.filename) {
16717
16748
  const servable = await servableFilesIn(dirAbs, entry.name);
@@ -16720,7 +16751,7 @@ async function enrich(absolute, entry, accountNames) {
16720
16751
  let size = null;
16721
16752
  let modifiedAt = entry.modifiedAt;
16722
16753
  try {
16723
- const st = await stat4(join32(dirAbs, innerName));
16754
+ const st = await stat4(join33(dirAbs, innerName));
16724
16755
  size = st.size;
16725
16756
  modifiedAt = st.mtime.toISOString();
16726
16757
  } catch {
@@ -16745,7 +16776,7 @@ async function enrich(absolute, entry, accountNames) {
16745
16776
  if (entry.kind === "file") {
16746
16777
  const dot = entry.name.lastIndexOf(".");
16747
16778
  const base = dot === -1 ? entry.name : entry.name.slice(0, dot);
16748
- if (UUID_RE3.test(base)) {
16779
+ if (UUID_RE4.test(base)) {
16749
16780
  const meta = await readMeta(absolute, base);
16750
16781
  if (meta?.filename) {
16751
16782
  entry.displayName = meta.filename;
@@ -16758,7 +16789,7 @@ async function enrich(absolute, entry, accountNames) {
16758
16789
  function buildDisplayPath(relPath, accountNames) {
16759
16790
  if (relPath === "." || relPath === "") return [];
16760
16791
  return relPath.split("/").filter(Boolean).map((seg) => {
16761
- const dn = UUID_RE3.test(seg) ? accountNames.get(seg) : void 0;
16792
+ const dn = UUID_RE4.test(seg) ? accountNames.get(seg) : void 0;
16762
16793
  return dn ? { name: seg, displayName: dn } : { name: seg };
16763
16794
  });
16764
16795
  }
@@ -16808,11 +16839,11 @@ function isProtectedFromRename(relPath) {
16808
16839
  if (segments.length === 3 && segments[0] === "accounts" && segments[2] === "uploads") {
16809
16840
  return true;
16810
16841
  }
16811
- if (segments.length === 4 && segments[0] === "accounts" && segments[2] === "uploads" && UUID_RE3.test(segments[3])) {
16842
+ if (segments.length === 4 && segments[0] === "accounts" && segments[2] === "uploads" && UUID_RE4.test(segments[3])) {
16812
16843
  return true;
16813
16844
  }
16814
16845
  if (parseAttachmentPath(relPath) !== null) return true;
16815
- if (UUID_RE3.test(base.replace(/\.meta\.json$/, "")) && base.endsWith(".meta.json")) {
16846
+ if (UUID_RE4.test(base.replace(/\.meta\.json$/, "")) && base.endsWith(".meta.json")) {
16816
16847
  return true;
16817
16848
  }
16818
16849
  return false;
@@ -16886,16 +16917,16 @@ app22.get("/", requireAdminSession, async (c) => {
16886
16917
  const isAccountParent = segs.length === 1 && segs[0] === "accounts";
16887
16918
  const entries = [];
16888
16919
  for (const name of names) {
16889
- if (UUID_RE3.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
16920
+ if (UUID_RE4.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
16890
16921
  continue;
16891
16922
  }
16892
- if (isAccountParent && UUID_RE3.test(name) && name !== accountId) {
16923
+ if (isAccountParent && UUID_RE4.test(name) && name !== accountId) {
16893
16924
  continue;
16894
16925
  }
16895
16926
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
16896
16927
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
16897
16928
  try {
16898
- const entryPath = join32(absolute, name);
16929
+ const entryPath = join33(absolute, name);
16899
16930
  const s = await stat4(entryPath);
16900
16931
  entries.push({
16901
16932
  name,
@@ -16958,7 +16989,7 @@ app22.get("/download", requireAdminSession, async (c) => {
16958
16989
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
16959
16990
  return c.json({ error: "Not found" }, 404);
16960
16991
  }
16961
- const meta = readSidecarMeta(join32(projectDir, `${sessionId}.meta.json`));
16992
+ const meta = readSidecarMeta(join33(projectDir, `${sessionId}.meta.json`));
16962
16993
  if (!meta.accountId || meta.accountId !== accountId) {
16963
16994
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
16964
16995
  return c.json({ error: "Not found" }, 404);
@@ -17053,7 +17084,7 @@ async function* walkRegularFiles(dirAbsolute) {
17053
17084
  const dirents = await readdir3(dirAbsolute, { withFileTypes: true });
17054
17085
  for (const d of dirents) {
17055
17086
  if (d.isSymbolicLink()) continue;
17056
- const child = join32(dirAbsolute, d.name);
17087
+ const child = join33(dirAbsolute, d.name);
17057
17088
  if (d.isDirectory()) {
17058
17089
  yield* walkRegularFiles(child);
17059
17090
  continue;
@@ -17163,7 +17194,7 @@ async function resolveUploadTarget(c, accountId, uid) {
17163
17194
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
17164
17195
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
17165
17196
  const relDir = relpath ? dirname11(relpath) : ".";
17166
- const destRel = relDir === "." ? base.relative : join32(base.relative, relDir);
17197
+ const destRel = relDir === "." ? base.relative : join33(base.relative, relDir);
17167
17198
  if (crossesForeignAccountPartition(destRel, accountId)) {
17168
17199
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
17169
17200
  return { ok: false, status: 404, error: "Not found" };
@@ -17237,7 +17268,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
17237
17268
  });
17238
17269
  await unlink2(tmpPath).catch(() => {
17239
17270
  });
17240
- const tempRemoved = !existsSync28(tmpPath);
17271
+ const tempRemoved = !existsSync29(tmpPath);
17241
17272
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
17242
17273
  };
17243
17274
  const reader = body.getReader();
@@ -17311,7 +17342,7 @@ async function discardChunkUpload(uploadId, state) {
17311
17342
  });
17312
17343
  await unlink2(state.tmpPath).catch(() => {
17313
17344
  });
17314
- const tempRemoved = !existsSync28(state.tmpPath);
17345
+ const tempRemoved = !existsSync29(state.tmpPath);
17315
17346
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
17316
17347
  }
17317
17348
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -17540,8 +17571,8 @@ app22.delete("/", requireAdminSession, async (c) => {
17540
17571
  const dot = base.lastIndexOf(".");
17541
17572
  const stem = dot === -1 ? base : base.slice(0, dot);
17542
17573
  const containerDir = dirname11(absolute);
17543
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join32(containerDir, `${stem}.meta.json`) : null;
17544
- const isAttachmentContainer = UUID_RE3.test(stem) && basename9(containerDir) === stem;
17574
+ const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join33(containerDir, `${stem}.meta.json`) : null;
17575
+ const isAttachmentContainer = UUID_RE4.test(stem) && basename9(containerDir) === stem;
17545
17576
  await unlink2(absolute);
17546
17577
  if (sidecarPath) {
17547
17578
  try {
@@ -17550,7 +17581,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17550
17581
  }
17551
17582
  }
17552
17583
  if (isAttachmentContainer) {
17553
- await unlink2(join32(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17584
+ await unlink2(join33(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17554
17585
  });
17555
17586
  await rmdir(containerDir).catch(() => {
17556
17587
  });
@@ -18654,8 +18685,8 @@ function isHiddenByDefault(label) {
18654
18685
  }
18655
18686
 
18656
18687
  // server/lib/top-level-labels.ts
18657
- import { readdirSync as readdirSync22, readFileSync as readFileSync33 } from "fs";
18658
- import { join as join33, resolve as resolve24 } from "path";
18688
+ import { readdirSync as readdirSync23, readFileSync as readFileSync33 } from "fs";
18689
+ import { join as join34, resolve as resolve24 } from "path";
18659
18690
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
18660
18691
  /* @__PURE__ */ new Set([
18661
18692
  // Base-schema infra (schema-base.md has no top-level section).
@@ -18748,7 +18779,7 @@ function parseTopLevelLabels(content) {
18748
18779
  }
18749
18780
  function resolveReferencesDir() {
18750
18781
  if (process.env.MAXY_PLATFORM_ROOT) {
18751
- return join33(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18782
+ return join34(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18752
18783
  }
18753
18784
  return resolve24(import.meta.dirname, "../../../plugins/memory/references");
18754
18785
  }
@@ -18756,9 +18787,9 @@ function parseTableTopLevelLabels(referencesDir) {
18756
18787
  const labels = /* @__PURE__ */ new Set();
18757
18788
  const contributingFiles = [];
18758
18789
  try {
18759
- const fileNames = readdirSync22(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18790
+ const fileNames = readdirSync23(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18760
18791
  for (const fileName of fileNames) {
18761
- const content = readFileSync33(join33(referencesDir, fileName), "utf-8");
18792
+ const content = readFileSync33(join34(referencesDir, fileName), "utf-8");
18762
18793
  const parsed = parseTopLevelLabels(content);
18763
18794
  if (parsed.length > 0) contributingFiles.push(fileName);
18764
18795
  for (const label of parsed) labels.add(label);
@@ -19912,7 +19943,7 @@ var graph_default_view_default = app28;
19912
19943
  // server/routes/admin/sidebar-artefacts.ts
19913
19944
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
19914
19945
  import { resolve as resolve25, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename10 } from "path";
19915
- import { existsSync as existsSync29 } from "fs";
19946
+ import { existsSync as existsSync30 } from "fs";
19916
19947
  var LIMIT = 50;
19917
19948
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
19918
19949
  function toDataRootRelPath(absPath) {
@@ -20019,7 +20050,7 @@ async function fetchAgentTemplateRows(accountDir) {
20019
20050
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
20020
20051
  const names = /* @__PURE__ */ new Set();
20021
20052
  for (const dir of [overrideDir, bundledDir]) {
20022
- if (!existsSync29(dir)) continue;
20053
+ if (!existsSync30(dir)) continue;
20023
20054
  try {
20024
20055
  const entries = await readdir4(dir);
20025
20056
  for (const entry of entries) {
@@ -20034,7 +20065,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
20034
20065
  }
20035
20066
  async function readAgentTemplateRow(inp) {
20036
20067
  let chosenPath = null;
20037
- if (existsSync29(inp.overridePath)) {
20068
+ if (existsSync30(inp.overridePath)) {
20038
20069
  try {
20039
20070
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
20040
20071
  chosenPath = inp.overridePath;
@@ -20045,7 +20076,7 @@ async function readAgentTemplateRow(inp) {
20045
20076
  );
20046
20077
  return null;
20047
20078
  }
20048
- } else if (existsSync29(inp.bundledPath)) {
20079
+ } else if (existsSync30(inp.bundledPath)) {
20049
20080
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
20050
20081
  console.error(
20051
20082
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -20647,12 +20678,12 @@ app37.get("/", async (c) => {
20647
20678
  var system_stats_default = app37;
20648
20679
 
20649
20680
  // server/routes/admin/health.ts
20650
- import { existsSync as existsSync30, readFileSync as readFileSync34 } from "fs";
20651
- import { resolve as resolve26, join as join34 } from "path";
20681
+ import { existsSync as existsSync31, readFileSync as readFileSync34 } from "fs";
20682
+ import { resolve as resolve26, join as join35 } from "path";
20652
20683
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
20653
20684
  var brandHostname = "maxy";
20654
- var brandJsonPath = join34(PLATFORM_ROOT6, "config", "brand.json");
20655
- if (existsSync30(brandJsonPath)) {
20685
+ var brandJsonPath = join35(PLATFORM_ROOT6, "config", "brand.json");
20686
+ if (existsSync31(brandJsonPath)) {
20656
20687
  try {
20657
20688
  const brand = JSON.parse(readFileSync34(brandJsonPath, "utf-8"));
20658
20689
  if (brand.hostname) brandHostname = brand.hostname;
@@ -20663,7 +20694,7 @@ var VERSION_FILE = resolve26(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
20663
20694
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
20664
20695
  var PROBE_TIMEOUT_MS = 1e3;
20665
20696
  function readVersion() {
20666
- if (!existsSync30(VERSION_FILE)) return "unknown";
20697
+ if (!existsSync31(VERSION_FILE)) return "unknown";
20667
20698
  return readFileSync34(VERSION_FILE, "utf-8").trim() || "unknown";
20668
20699
  }
20669
20700
  async function probeConversationDb() {
@@ -20673,18 +20704,18 @@ async function probeConversationDb() {
20673
20704
  } catch (err) {
20674
20705
  return { state: "error", reason: err instanceof Error ? err.message : String(err) };
20675
20706
  }
20676
- let timer2;
20707
+ let timer;
20677
20708
  try {
20678
20709
  const probe = session.run("RETURN 1");
20679
20710
  const timeout = new Promise((_, reject) => {
20680
- timer2 = setTimeout(() => reject(new Error("timeout")), PROBE_TIMEOUT_MS);
20711
+ timer = setTimeout(() => reject(new Error("timeout")), PROBE_TIMEOUT_MS);
20681
20712
  });
20682
20713
  await Promise.race([probe, timeout]);
20683
20714
  return { state: "ok" };
20684
20715
  } catch (err) {
20685
20716
  return { state: "error", reason: err instanceof Error ? err.message : String(err) };
20686
20717
  } finally {
20687
- if (timer2) clearTimeout(timer2);
20718
+ if (timer) clearTimeout(timer);
20688
20719
  session.close().catch(() => {
20689
20720
  });
20690
20721
  }
@@ -21440,8 +21471,8 @@ app45.post("/launch", requireAdminSession, async (c) => {
21440
21471
  var browser_default = app45;
21441
21472
 
21442
21473
  // server/routes/admin/calendar.ts
21443
- import { existsSync as existsSync31 } from "fs";
21444
- import { join as join36 } from "path";
21474
+ import { existsSync as existsSync32 } from "fs";
21475
+ import { join as join37 } from "path";
21445
21476
 
21446
21477
  // server/lib/calendar-ics.ts
21447
21478
  var CRLF = "\r\n";
@@ -21541,7 +21572,7 @@ function countVEvents(ics) {
21541
21572
 
21542
21573
  // server/lib/calendar-availability.ts
21543
21574
  import { readFileSync as readFileSync35 } from "fs";
21544
- import { join as join35 } from "path";
21575
+ import { join as join36 } from "path";
21545
21576
  var AVAILABILITY_FILENAME = "calendar-availability.json";
21546
21577
  var REQUIRED_KEYS = [
21547
21578
  "timezone",
@@ -21550,7 +21581,7 @@ var REQUIRED_KEYS = [
21550
21581
  "weekly"
21551
21582
  ];
21552
21583
  function readAvailabilityConfig(accountDir) {
21553
- const path3 = join35(accountDir, AVAILABILITY_FILENAME);
21584
+ const path3 = join36(accountDir, AVAILABILITY_FILENAME);
21554
21585
  let raw;
21555
21586
  try {
21556
21587
  raw = readFileSync35(path3, "utf-8");
@@ -21912,7 +21943,7 @@ app46.get("/booking-link", requireAdminSession, (c) => {
21912
21943
  console.error('[calendar] op=booking-link-fail err="no account configured"');
21913
21944
  return c.json({ bookingDomain: null });
21914
21945
  }
21915
- if (!existsSync31(join36(account.accountDir, AVAILABILITY_FILENAME))) {
21946
+ if (!existsSync32(join37(account.accountDir, AVAILABILITY_FILENAME))) {
21916
21947
  console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
21917
21948
  return c.json({ bookingDomain: null });
21918
21949
  }
@@ -22269,7 +22300,7 @@ app51.post("/", requireAdminSession, async (c) => {
22269
22300
  var task_time_adjust_default = app51;
22270
22301
 
22271
22302
  // server/routes/admin/activity.ts
22272
- import { readdirSync as readdirSync23 } from "fs";
22303
+ import { readdirSync as readdirSync24 } from "fs";
22273
22304
  var app52 = new Hono();
22274
22305
  var TAG42 = "[activity]";
22275
22306
  function resolveHouseAccountId(accounts) {
@@ -22285,7 +22316,7 @@ function requestToken() {
22285
22316
  var short = (id) => id ? id.slice(0, 8) : "unset";
22286
22317
  function countAccountDirsOnDisk() {
22287
22318
  try {
22288
- return readdirSync23(ACCOUNTS_DIR, { withFileTypes: true }).filter(
22319
+ return readdirSync24(ACCOUNTS_DIR, { withFileTypes: true }).filter(
22289
22320
  (e) => e.isDirectory() && !e.name.startsWith(".")
22290
22321
  ).length;
22291
22322
  } catch {
@@ -22340,8 +22371,10 @@ app52.get("/", requireAdminSession, async (c) => {
22340
22371
  const untaggedCount = rows.filter((r) => r.accountId === null).length;
22341
22372
  const meteringFailed = rows.filter((r) => r.meteringError !== null).length;
22342
22373
  const censusAgeMs = census ? Date.now() - census.sampleAtMs : null;
22374
+ const ageNull = rows.filter((r) => r.ageMs === null).length;
22375
+ const sidecarNull = rows.filter((r) => r.sidecarMissing).length;
22343
22376
  console.log(
22344
- `${TAG42} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"}`
22377
+ `${TAG42} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"} rows=${rows.length} ageNull=${ageNull} sidecarNull=${sidecarNull}`
22345
22378
  );
22346
22379
  console.log(
22347
22380
  `${TAG42} op=response req=${req} rows=${rows.length} accounts=${valid.length} untagged=${untaggedCount} meteringFailed=${meteringFailed} ms=${Date.now() - start}`
@@ -22353,10 +22386,20 @@ app52.get("/", requireAdminSession, async (c) => {
22353
22386
  if (name) names[a.accountId] = name;
22354
22387
  })
22355
22388
  );
22389
+ const loopRows = listLoops();
22390
+ const armed2 = armedCount();
22391
+ const byState = loopRows.reduce((acc, r) => {
22392
+ acc[r.state] = (acc[r.state] ?? 0) + 1;
22393
+ return acc;
22394
+ }, {});
22395
+ console.log(
22396
+ `${TAG42} op=loops req=${req} armed=${armed2} rendered=${loopRows.length} ` + Object.entries(byState).map(([s, n]) => `${s}=${n}`).join(" ")
22397
+ );
22356
22398
  return c.json({
22357
22399
  rows,
22358
22400
  census,
22359
22401
  censusAgeMs,
22402
+ loops: { armed: armed2, rows: loopRows },
22360
22403
  accounts: {
22361
22404
  onDisk,
22362
22405
  valid: valid.length,
@@ -22649,7 +22692,7 @@ app56.route("/request-magic-link", request_magic_link_default);
22649
22692
  var access_default = app56;
22650
22693
 
22651
22694
  // server/routes/sites.ts
22652
- import { existsSync as existsSync32, readFileSync as readFileSync36, realpathSync as realpathSync7, statSync as statSync13 } from "fs";
22695
+ import { existsSync as existsSync33, readFileSync as readFileSync36, realpathSync as realpathSync7, statSync as statSync14 } from "fs";
22653
22696
  import { resolve as resolve28 } from "path";
22654
22697
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
22655
22698
  var MIME = {
@@ -22715,7 +22758,7 @@ app57.get("/:rel{.*}", (c) => {
22715
22758
  }
22716
22759
  let stat8;
22717
22760
  try {
22718
- stat8 = existsSync32(filePath) ? statSync13(filePath) : null;
22761
+ stat8 = existsSync33(filePath) ? statSync14(filePath) : null;
22719
22762
  } catch {
22720
22763
  stat8 = null;
22721
22764
  }
@@ -22734,7 +22777,7 @@ app57.get("/:rel{.*}", (c) => {
22734
22777
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
22735
22778
  return c.text("Forbidden", 403);
22736
22779
  }
22737
- if (!existsSync32(filePath)) {
22780
+ if (!existsSync33(filePath)) {
22738
22781
  console.error(`[sites] not-found path=${reqPath} status=404`);
22739
22782
  return c.text("Not found", 404);
22740
22783
  }
@@ -22865,8 +22908,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
22865
22908
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
22866
22909
 
22867
22910
  // app/lib/brand-config.ts
22868
- import { existsSync as existsSync33, readFileSync as readFileSync38 } from "fs";
22869
- import { join as join37 } from "path";
22911
+ import { existsSync as existsSync34, readFileSync as readFileSync38 } from "fs";
22912
+ import { join as join38 } from "path";
22870
22913
  var cached2 = null;
22871
22914
  var cachedAttempted = false;
22872
22915
  function readBrandConfig() {
@@ -22874,8 +22917,8 @@ function readBrandConfig() {
22874
22917
  cachedAttempted = true;
22875
22918
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
22876
22919
  if (!platformRoot5) return null;
22877
- const brandPath = join37(platformRoot5, "config", "brand.json");
22878
- if (!existsSync33(brandPath)) return null;
22920
+ const brandPath = join38(platformRoot5, "config", "brand.json");
22921
+ if (!existsSync34(brandPath)) return null;
22879
22922
  try {
22880
22923
  cached2 = JSON.parse(readFileSync38(brandPath, "utf-8"));
22881
22924
  return cached2;
@@ -23366,8 +23409,8 @@ var visitor_event_default = app60;
23366
23409
 
23367
23410
  // server/routes/session.ts
23368
23411
  import { resolve as resolve29 } from "path";
23369
- import { existsSync as existsSync34, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9 } from "fs";
23370
- var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23412
+ import { existsSync as existsSync35, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9 } from "fs";
23413
+ var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23371
23414
  function writeBrandingCache(accountId, agentSlug, branding) {
23372
23415
  try {
23373
23416
  const cacheDir = resolve29(MAXY_DIR, "branding-cache", accountId);
@@ -23382,7 +23425,7 @@ function parseVisitorCookie2(cookieHeader) {
23382
23425
  const match = cookieHeader.match(/(?:^|;\s*)maxy_visitor=([^;]*)/);
23383
23426
  if (!match) return null;
23384
23427
  const value = decodeURIComponent(match[1]).trim();
23385
- return UUID_RE4.test(value) ? value : null;
23428
+ return UUID_RE5.test(value) ? value : null;
23386
23429
  }
23387
23430
  function parseAccessSessionId2(cookieHeader) {
23388
23431
  if (!cookieHeader) return null;
@@ -23450,7 +23493,7 @@ app61.post("/", async (c) => {
23450
23493
  let agentConfig = null;
23451
23494
  if (account) {
23452
23495
  const agentDir = resolve29(account.accountDir, "agents", agentSlug);
23453
- if (!existsSync34(agentDir) || !existsSync34(resolve29(agentDir, "config.json"))) {
23496
+ if (!existsSync35(agentDir) || !existsSync35(resolve29(agentDir, "config.json"))) {
23454
23497
  return c.json({ error: "Agent not found" }, 404);
23455
23498
  }
23456
23499
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -23480,7 +23523,7 @@ app61.post("/", async (c) => {
23480
23523
  );
23481
23524
  }
23482
23525
  }
23483
- if (body.session_key && typeof body.session_key === "string" && UUID_RE4.test(body.session_key)) {
23526
+ if (body.session_key && typeof body.session_key === "string" && UUID_RE5.test(body.session_key)) {
23484
23527
  if (visitorId) {
23485
23528
  const recent = await findRecentConversation(visitorId, accountId, agentSlug).catch(() => null);
23486
23529
  if (recent) {
@@ -23771,19 +23814,17 @@ function startTimeEntryCensus(openSession, opts = {}) {
23771
23814
  }
23772
23815
  }
23773
23816
  };
23774
- void tick();
23775
- const id = setInterval(() => {
23776
- void tick();
23777
- }, intervalMs);
23778
- if (typeof id.unref === "function") {
23779
- id.unref();
23780
- }
23781
- return () => clearInterval(id);
23817
+ return registerLoop({
23818
+ name: "timeentry-census",
23819
+ intervalMs,
23820
+ firstRunDelayMs: 0,
23821
+ run: tick
23822
+ });
23782
23823
  }
23783
23824
 
23784
23825
  // app/lib/ledger-census.ts
23785
- import { readdirSync as readdirSync24, readFileSync as readFileSync39, statSync as statSync14 } from "fs";
23786
- import { join as join38 } from "path";
23826
+ import { readdirSync as readdirSync25, readFileSync as readFileSync39, statSync as statSync15 } from "fs";
23827
+ import { join as join39 } from "path";
23787
23828
 
23788
23829
  // ../lib/ledger-core/dist/reconcile.js
23789
23830
  var LEDGER_INDEX_NAMES = [
@@ -23831,15 +23872,15 @@ var DAY_MS = 864e5;
23831
23872
  function countWriteRejects24h(logDir, now) {
23832
23873
  let entries;
23833
23874
  try {
23834
- entries = readdirSync24(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
23875
+ entries = readdirSync25(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
23835
23876
  } catch {
23836
23877
  return 0;
23837
23878
  }
23838
23879
  let total = 0;
23839
23880
  for (const name of entries) {
23840
- const path3 = join38(logDir, name);
23881
+ const path3 = join39(logDir, name);
23841
23882
  try {
23842
- if (now - statSync14(path3).mtimeMs > DAY_MS) continue;
23883
+ if (now - statSync15(path3).mtimeMs > DAY_MS) continue;
23843
23884
  for (const line of readFileSync39(path3, "utf8").split("\n")) {
23844
23885
  if (line.includes("[graph-write] reject")) total += 1;
23845
23886
  }
@@ -23932,15 +23973,12 @@ function startLedgerCensus(openSession, opts = {}) {
23932
23973
  }
23933
23974
  }
23934
23975
  };
23935
- void tick();
23936
- const id = setInterval(() => {
23937
- void tick();
23938
- }, intervalMs);
23939
- if (typeof id.unref === "function") {
23940
- ;
23941
- id.unref();
23942
- }
23943
- return () => clearInterval(id);
23976
+ return registerLoop({
23977
+ name: "ledger-census",
23978
+ intervalMs,
23979
+ firstRunDelayMs: 0,
23980
+ run: tick
23981
+ });
23944
23982
  }
23945
23983
 
23946
23984
  // app/lib/conversation-audit.ts
@@ -23992,7 +24030,7 @@ function renderLabelTop(rows) {
23992
24030
  return `${labels}:${c}`;
23993
24031
  }).join(",");
23994
24032
  }
23995
- var timer = null;
24033
+ var armed = false;
23996
24034
  async function runGraphHealthTick() {
23997
24035
  const session = getSession();
23998
24036
  try {
@@ -24087,16 +24125,16 @@ async function verifyUserProfileConstraint() {
24087
24125
  }
24088
24126
  }
24089
24127
  function startGraphHealthTimer() {
24090
- if (timer) return;
24128
+ if (armed) return;
24091
24129
  verifyUserProfileConstraint().catch(() => {
24092
24130
  });
24093
- runGraphHealthTick().catch(() => {
24131
+ registerLoop({
24132
+ name: "graph-health",
24133
+ intervalMs: HOUR_MS,
24134
+ firstRunDelayMs: 0,
24135
+ run: () => runGraphHealthTick()
24094
24136
  });
24095
- timer = setInterval(() => {
24096
- runGraphHealthTick().catch(() => {
24097
- });
24098
- }, HOUR_MS);
24099
- if (typeof timer.unref === "function") timer.unref();
24137
+ armed = true;
24100
24138
  }
24101
24139
 
24102
24140
  // app/lib/file-watcher.ts
@@ -24327,8 +24365,8 @@ async function migrateUploads(opts = {}) {
24327
24365
 
24328
24366
  // app/lib/migrate-admin-webchat-sidecars.ts
24329
24367
  import { readdir as readdir6, readFile as readFile6, rename as rename3, writeFile as writeFile4, unlink as unlink3 } from "fs/promises";
24330
- import { existsSync as existsSync35 } from "fs";
24331
- import { join as join39 } from "path";
24368
+ import { existsSync as existsSync36 } from "fs";
24369
+ import { join as join40 } from "path";
24332
24370
  var ADMIN_ROLE2 = "admin";
24333
24371
  var WEBCHAT_CHANNEL2 = "webchat";
24334
24372
  var SESSION_META_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.meta\.json$/i;
@@ -24357,7 +24395,7 @@ async function writeRaw(path3, obj) {
24357
24395
  await rename3(tmp, path3);
24358
24396
  } catch (err) {
24359
24397
  try {
24360
- if (existsSync35(tmp)) await unlink3(tmp);
24398
+ if (existsSync36(tmp)) await unlink3(tmp);
24361
24399
  } catch {
24362
24400
  }
24363
24401
  throw err;
@@ -24373,7 +24411,7 @@ async function collectLiveSidecars(projectsRoot) {
24373
24411
  }
24374
24412
  for (const slug of slugs) {
24375
24413
  if (!slug.isDirectory()) continue;
24376
- const slugDir = join39(projectsRoot, slug.name);
24414
+ const slugDir = join40(projectsRoot, slug.name);
24377
24415
  let entries;
24378
24416
  try {
24379
24417
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -24382,9 +24420,9 @@ async function collectLiveSidecars(projectsRoot) {
24382
24420
  }
24383
24421
  for (const entry of entries) {
24384
24422
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
24385
- out.push(join39(slugDir, entry.name));
24423
+ out.push(join40(slugDir, entry.name));
24386
24424
  } else if (entry.isDirectory() && entry.name === "subagents") {
24387
- const subDir = join39(slugDir, entry.name);
24425
+ const subDir = join40(slugDir, entry.name);
24388
24426
  let subs;
24389
24427
  try {
24390
24428
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -24392,7 +24430,7 @@ async function collectLiveSidecars(projectsRoot) {
24392
24430
  continue;
24393
24431
  }
24394
24432
  for (const s of subs) {
24395
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join39(subDir, s.name));
24433
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join40(subDir, s.name));
24396
24434
  }
24397
24435
  }
24398
24436
  }
@@ -24404,7 +24442,7 @@ function shortId(path3) {
24404
24442
  return base.slice(0, 8);
24405
24443
  }
24406
24444
  async function migrateAdminWebchatSidecars(opts = {}) {
24407
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join39(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
24445
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join40(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
24408
24446
  const usersFile = opts.usersFile ?? USERS_FILE;
24409
24447
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
24410
24448
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -25416,13 +25454,13 @@ var WebchatGateway = class _WebchatGateway {
25416
25454
  * response, preserving the pre-756 POST→single-blob browser contract. */
25417
25455
  awaitReply(key, timeoutMs) {
25418
25456
  return new Promise((resolve37) => {
25419
- const timer2 = setTimeout(() => {
25457
+ const timer = setTimeout(() => {
25420
25458
  this.replyAwaiters.delete(key);
25421
25459
  resolve37({ timeout: true });
25422
25460
  }, timeoutMs);
25423
- if (timer2.unref) timer2.unref();
25461
+ if (timer.unref) timer.unref();
25424
25462
  this.replyAwaiters.set(key, (r) => {
25425
- clearTimeout(timer2);
25463
+ clearTimeout(timer);
25426
25464
  this.replyAwaiters.delete(key);
25427
25465
  resolve37(r);
25428
25466
  });
@@ -25437,16 +25475,16 @@ var WebchatGateway = class _WebchatGateway {
25437
25475
  const k = _WebchatGateway.promptKey(p.key, p.requestId);
25438
25476
  return new Promise((resolve37) => {
25439
25477
  this.pendingPrompts.get(k)?.resolve({ timeout: true });
25440
- const timer2 = setTimeout(() => {
25478
+ const timer = setTimeout(() => {
25441
25479
  this.pendingPrompts.delete(k);
25442
25480
  resolve37({ timeout: true });
25443
25481
  }, timeoutMs);
25444
- if (timer2.unref) timer2.unref();
25482
+ if (timer.unref) timer.unref();
25445
25483
  this.pendingPrompts.set(k, {
25446
25484
  ...p,
25447
25485
  at: Date.now(),
25448
25486
  resolve: (r) => {
25449
- clearTimeout(timer2);
25487
+ clearTimeout(timer);
25450
25488
  this.pendingPrompts.delete(k);
25451
25489
  resolve37(r);
25452
25490
  }
@@ -26767,12 +26805,12 @@ function startTelegramNativeFileFollower(input) {
26767
26805
  }
26768
26806
 
26769
26807
  // server/telegram-descriptor.ts
26770
- import { resolve as resolve34, join as join40 } from "path";
26808
+ import { resolve as resolve34, join as join41 } from "path";
26771
26809
  function telegramGatewayUrl() {
26772
26810
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26773
26811
  }
26774
26812
  function telegramServerPath() {
26775
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join40(__dirname, ".."), "services/telegram-channel/dist/server.js");
26813
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."), "services/telegram-channel/dist/server.js");
26776
26814
  }
26777
26815
 
26778
26816
  // app/lib/channel-pty-bridge/public-session-end-review.ts
@@ -27059,7 +27097,7 @@ function broadcastAdminShutdown(reason) {
27059
27097
 
27060
27098
  // ../lib/entitlement/src/index.ts
27061
27099
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
27062
- import { existsSync as existsSync36, readFileSync as readFileSync40, statSync as statSync15 } from "fs";
27100
+ import { existsSync as existsSync37, readFileSync as readFileSync40, statSync as statSync16 } from "fs";
27063
27101
  import { resolve as resolve35 } from "path";
27064
27102
 
27065
27103
  // ../lib/entitlement/src/canonicalize.ts
@@ -27108,10 +27146,10 @@ function resolveEntitlement(brand, account) {
27108
27146
  return logResolved(implicitTrust(account), null);
27109
27147
  }
27110
27148
  const entitlementPath = resolve35(brand.configDir, "entitlement.json");
27111
- if (!existsSync36(entitlementPath)) {
27149
+ if (!existsSync37(entitlementPath)) {
27112
27150
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
27113
27151
  }
27114
- const stat8 = statSync15(entitlementPath);
27152
+ const stat8 = statSync16(entitlementPath);
27115
27153
  const key = memoKey(stat8.mtimeMs, account);
27116
27154
  if (memo && memo.key === key) {
27117
27155
  return memo.result;
@@ -27299,12 +27337,12 @@ function clientFrom(c) {
27299
27337
  }
27300
27338
  installMediaDownloadGuard();
27301
27339
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
27302
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join41(PLATFORM_ROOT8, "config", "brand.json") : "";
27340
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join42(PLATFORM_ROOT8, "config", "brand.json") : "";
27303
27341
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
27304
- if (BRAND_JSON_PATH && !existsSync37(BRAND_JSON_PATH)) {
27342
+ if (BRAND_JSON_PATH && !existsSync38(BRAND_JSON_PATH)) {
27305
27343
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
27306
27344
  }
27307
- if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
27345
+ if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
27308
27346
  try {
27309
27347
  const parsed = JSON.parse(readFileSync41(BRAND_JSON_PATH, "utf-8"));
27310
27348
  BRAND = { ...BRAND, ...parsed };
@@ -27338,10 +27376,10 @@ var brandLoginOpts = {
27338
27376
  appleTouchIconPath: brandAppIcon512Path,
27339
27377
  themeColor: BRAND.defaultColors?.primary
27340
27378
  };
27341
- var ALIAS_DOMAINS_PATH = join41(homedir4(), BRAND.configDir, "alias-domains.json");
27379
+ var ALIAS_DOMAINS_PATH = join42(homedir4(), BRAND.configDir, "alias-domains.json");
27342
27380
  function loadAliasDomains() {
27343
27381
  try {
27344
- if (!existsSync37(ALIAS_DOMAINS_PATH)) return null;
27382
+ if (!existsSync38(ALIAS_DOMAINS_PATH)) return null;
27345
27383
  const parsed = JSON.parse(readFileSync41(ALIAS_DOMAINS_PATH, "utf-8"));
27346
27384
  if (!Array.isArray(parsed)) {
27347
27385
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -27406,7 +27444,7 @@ async function recordPassiveDispatch(input) {
27406
27444
  var waGateway = new WaGateway({
27407
27445
  fetchStandingRules: fetchAccountStandingRules,
27408
27446
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
27409
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
27447
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
27410
27448
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
27411
27449
  // path-validation scope) is the sender's effective SESSION account, resolved
27412
27450
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -27421,7 +27459,7 @@ var waGateway = new WaGateway({
27421
27459
  caption,
27422
27460
  accountId,
27423
27461
  maxyAccountId,
27424
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."))
27462
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, ".."))
27425
27463
  });
27426
27464
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
27427
27465
  },
@@ -27525,7 +27563,7 @@ function runDuplicateSenderAudit() {
27525
27563
  try {
27526
27564
  const configDir2 = process.env.CLAUDE_CONFIG_DIR;
27527
27565
  if (!configDir2) return;
27528
- const projectsRoot = join41(configDir2, "projects");
27566
+ const projectsRoot = join42(configDir2, "projects");
27529
27567
  const records = [];
27530
27568
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
27531
27569
  if (isSubagent || archived) continue;
@@ -27539,8 +27577,12 @@ function runDuplicateSenderAudit() {
27539
27577
  console.error(`[whatsapp-native] op=duplicate-sender-audit-error error=${err instanceof Error ? err.message : String(err)}`);
27540
27578
  }
27541
27579
  }
27542
- setTimeout(runDuplicateSenderAudit, 0).unref();
27543
- setInterval(runDuplicateSenderAudit, 15 * 6e4).unref();
27580
+ registerLoop({
27581
+ name: "whatsapp-duplicate-sender-audit",
27582
+ intervalMs: 15 * 6e4,
27583
+ firstRunDelayMs: 0,
27584
+ run: runDuplicateSenderAudit
27585
+ });
27544
27586
  var webchatGateway = new WebchatGateway({
27545
27587
  fetchStandingRules: fetchAccountStandingRules,
27546
27588
  gatewayUrl: webchatGatewayUrl(),
@@ -28077,7 +28119,7 @@ app63.get("/agent-assets/:slug/:filename", (c) => {
28077
28119
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
28078
28120
  return c.text("Forbidden", 403);
28079
28121
  }
28080
- if (!existsSync37(filePath)) {
28122
+ if (!existsSync38(filePath)) {
28081
28123
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
28082
28124
  return c.text("Not found", 404);
28083
28125
  }
@@ -28107,7 +28149,7 @@ app63.get("/generated/:filename", (c) => {
28107
28149
  console.error(`[generated] serve file=${filename} status=403`);
28108
28150
  return c.text("Forbidden", 403);
28109
28151
  }
28110
- if (!existsSync37(filePath)) {
28152
+ if (!existsSync38(filePath)) {
28111
28153
  console.error(`[generated] serve file=${filename} status=404`);
28112
28154
  return c.text("Not found", 404);
28113
28155
  }
@@ -28127,7 +28169,7 @@ app63.route("/v", visitor_consent_default);
28127
28169
  var htmlCache = /* @__PURE__ */ new Map();
28128
28170
  var brandLogoPath = "/brand/maxy-monochrome.png";
28129
28171
  var brandIconPath = "/brand/maxy-monochrome.png";
28130
- if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
28172
+ if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
28131
28173
  try {
28132
28174
  const fullBrand = JSON.parse(readFileSync41(BRAND_JSON_PATH, "utf-8"));
28133
28175
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -28156,7 +28198,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
28156
28198
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
28157
28199
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
28158
28200
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
28159
- (p) => existsSync37(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
28201
+ (p) => existsSync38(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
28160
28202
  );
28161
28203
  var SW_SOURCE = (() => {
28162
28204
  try {
@@ -28168,8 +28210,8 @@ var SW_SOURCE = (() => {
28168
28210
  function readInstalledVersion() {
28169
28211
  try {
28170
28212
  if (!PLATFORM_ROOT8) return "unknown";
28171
- const versionFile = join41(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
28172
- if (!existsSync37(versionFile)) return "unknown";
28213
+ const versionFile = join42(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
28214
+ if (!existsSync38(versionFile)) return "unknown";
28173
28215
  const content = readFileSync41(versionFile, "utf-8").trim();
28174
28216
  return content || "unknown";
28175
28217
  } catch {
@@ -28228,12 +28270,12 @@ ${clientErrorReporterScript}
28228
28270
  return html;
28229
28271
  }
28230
28272
  function loadBrandingCache(agentSlug) {
28231
- const configDir2 = join41(homedir4(), BRAND.configDir);
28273
+ const configDir2 = join42(homedir4(), BRAND.configDir);
28232
28274
  try {
28233
28275
  const accountId = getDefaultAccountId();
28234
28276
  if (!accountId) return null;
28235
- const cachePath = join41(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
28236
- if (!existsSync37(cachePath)) return null;
28277
+ const cachePath = join42(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
28278
+ if (!existsSync38(cachePath)) return null;
28237
28279
  return JSON.parse(readFileSync41(cachePath, "utf-8"));
28238
28280
  } catch {
28239
28281
  return null;
@@ -28466,11 +28508,11 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
28466
28508
  var httpServer = serve({ fetch: app63.fetch, port, hostname });
28467
28509
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28468
28510
  {
28469
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28511
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28470
28512
  const reconcileScript = resolve36(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
28471
28513
  const RECONCILE_INTERVAL_MS = 12e4;
28472
28514
  const runReconcile = () => {
28473
- if (!existsSync37(reconcileScript)) return;
28515
+ if (!existsSync38(reconcileScript)) return;
28474
28516
  try {
28475
28517
  const child = spawn3(process.execPath, [reconcileScript], {
28476
28518
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -28482,17 +28524,20 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28482
28524
  console.error(`[calendar-reconcile] spawn-failed err="${err.message}"`);
28483
28525
  }
28484
28526
  };
28485
- const firstRun = setTimeout(runReconcile, 15e3);
28486
- firstRun.unref();
28487
- const loop = setInterval(runReconcile, RECONCILE_INTERVAL_MS);
28488
- loop.unref();
28527
+ registerLoop({
28528
+ name: "calendar-reconcile",
28529
+ intervalMs: RECONCILE_INTERVAL_MS,
28530
+ firstRunDelayMs: 15e3,
28531
+ detached: true,
28532
+ run: runReconcile
28533
+ });
28489
28534
  }
28490
28535
  {
28491
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28536
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28492
28537
  const outlookScript = resolve36(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
28493
28538
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
28494
28539
  const runOutlookComplete = () => {
28495
- if (!existsSync37(outlookScript)) return;
28540
+ if (!existsSync38(outlookScript)) return;
28496
28541
  try {
28497
28542
  const child = spawn3(process.execPath, [outlookScript], {
28498
28543
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -28504,26 +28549,29 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28504
28549
  console.error(`[outlook-complete] spawn-failed err="${err.message}"`);
28505
28550
  }
28506
28551
  };
28507
- const outlookFirst = setTimeout(runOutlookComplete, 18e3);
28508
- outlookFirst.unref();
28509
- const outlookLoop = setInterval(runOutlookComplete, OUTLOOK_COMPLETE_INTERVAL_MS);
28510
- outlookLoop.unref();
28552
+ registerLoop({
28553
+ name: "outlook-devicecode-complete",
28554
+ intervalMs: OUTLOOK_COMPLETE_INTERVAL_MS,
28555
+ firstRunDelayMs: 18e3,
28556
+ detached: true,
28557
+ run: runOutlookComplete
28558
+ });
28511
28559
  }
28512
28560
  {
28513
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28561
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28514
28562
  const strandedAccountsDir = resolve36(auditRoot, "..", "data/accounts");
28515
28563
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
28516
28564
  const STRANDED_AGE_MS = 16 * 6e4;
28517
28565
  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;
28518
28566
  const runStrandedAudit = () => {
28519
28567
  try {
28520
- if (!existsSync37(strandedAccountsDir)) return;
28568
+ if (!existsSync38(strandedAccountsDir)) return;
28521
28569
  const now = Date.now();
28522
- for (const name of readdirSync25(strandedAccountsDir)) {
28570
+ for (const name of readdirSync26(strandedAccountsDir)) {
28523
28571
  if (!STRANDED_UUID_RE.test(name)) continue;
28524
28572
  const pendingPath2 = resolve36(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
28525
- if (!existsSync37(pendingPath2)) continue;
28526
- const ageMs = now - statSync16(pendingPath2).mtimeMs;
28573
+ if (!existsSync38(pendingPath2)) continue;
28574
+ const ageMs = now - statSync17(pendingPath2).mtimeMs;
28527
28575
  if (ageMs > STRANDED_AGE_MS) {
28528
28576
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs / 1e3)}`);
28529
28577
  }
@@ -28532,35 +28580,82 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28532
28580
  console.error(`[outlook-mcp] devicecode-stranded-audit error="${err.message}"`);
28533
28581
  }
28534
28582
  };
28535
- const strandedFirst = setTimeout(runStrandedAudit, 25e3);
28536
- strandedFirst.unref();
28537
- const strandedLoop = setInterval(runStrandedAudit, STRANDED_AUDIT_INTERVAL_MS);
28538
- strandedLoop.unref();
28583
+ registerLoop({
28584
+ name: "outlook-stranded-audit",
28585
+ intervalMs: STRANDED_AUDIT_INTERVAL_MS,
28586
+ firstRunDelayMs: 25e3,
28587
+ run: runStrandedAudit
28588
+ });
28539
28589
  }
28540
28590
  {
28541
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28542
- const STORAGE_AUDIT_INTERVAL_MS = 3e5;
28543
- const runStorageAuditSafe = () => {
28544
- runStorageAudit(auditPlatformRoot).catch(
28545
- (err) => console.error(`[storage-audit] error="${err.message}"`)
28546
- );
28591
+ const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28592
+ const googleAccountsDir = resolve36(googleRoot, "..", "data/accounts");
28593
+ const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
28594
+ const runGooglePendingAuditSafe = () => {
28595
+ try {
28596
+ runGooglePendingAudit(googleAccountsDir, Date.now(), (line) => console.error(line));
28597
+ } catch (err) {
28598
+ console.error(`[google-oauth] op=pending-audit-error error="${err.message}"`);
28599
+ }
28547
28600
  };
28548
- const auditFirst = setTimeout(runStorageAuditSafe, 2e4);
28549
- auditFirst.unref();
28550
- const auditLoop = setInterval(runStorageAuditSafe, STORAGE_AUDIT_INTERVAL_MS);
28551
- auditLoop.unref();
28552
- const runPagesAuditSafe = () => {
28553
- runPagesAudit(auditPlatformRoot).catch(
28554
- (err) => console.error(`[pages-audit] error="${err.message}"`)
28555
- );
28601
+ registerLoop({
28602
+ name: "google-pending-audit",
28603
+ intervalMs: GOOGLE_PENDING_AUDIT_INTERVAL_MS,
28604
+ firstRunDelayMs: 27e3,
28605
+ run: runGooglePendingAuditSafe
28606
+ });
28607
+ const googleAuditScript = resolve36(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
28608
+ const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
28609
+ const runGoogleAccountAudit = () => {
28610
+ if (!existsSync38(googleAuditScript)) return;
28611
+ try {
28612
+ const child = spawn3(process.execPath, [googleAuditScript], {
28613
+ env: { ...process.env, PLATFORM_ROOT: googleRoot },
28614
+ stdio: "inherit"
28615
+ });
28616
+ child.unref();
28617
+ child.on(
28618
+ "error",
28619
+ (err) => console.error(`[google-account-audit] op=spawn-failed error="${err.message}"`)
28620
+ );
28621
+ } catch (err) {
28622
+ console.error(`[google-account-audit] op=spawn-failed error="${err.message}"`);
28623
+ }
28556
28624
  };
28557
- const pagesAuditFirst = setTimeout(runPagesAuditSafe, 35e3);
28558
- pagesAuditFirst.unref();
28559
- const pagesAuditLoop = setInterval(runPagesAuditSafe, STORAGE_AUDIT_INTERVAL_MS);
28560
- pagesAuditLoop.unref();
28625
+ registerLoop({
28626
+ name: "google-account-audit",
28627
+ intervalMs: GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS,
28628
+ firstRunDelayMs: 45e3,
28629
+ detached: true,
28630
+ run: runGoogleAccountAudit
28631
+ });
28561
28632
  }
28562
28633
  {
28563
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28634
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28635
+ const STORAGE_AUDIT_INTERVAL_MS = 3e5;
28636
+ const runStorageAuditSafe = () => runStorageAudit(auditPlatformRoot).catch((err) => {
28637
+ console.error(`[storage-audit] error="${err.message}"`);
28638
+ throw err;
28639
+ });
28640
+ registerLoop({
28641
+ name: "storage-audit",
28642
+ intervalMs: STORAGE_AUDIT_INTERVAL_MS,
28643
+ firstRunDelayMs: 2e4,
28644
+ run: runStorageAuditSafe
28645
+ });
28646
+ const runPagesAuditSafe = () => runPagesAudit(auditPlatformRoot).catch((err) => {
28647
+ console.error(`[pages-audit] error="${err.message}"`);
28648
+ throw err;
28649
+ });
28650
+ registerLoop({
28651
+ name: "pages-audit",
28652
+ intervalMs: STORAGE_AUDIT_INTERVAL_MS,
28653
+ firstRunDelayMs: 35e3,
28654
+ run: runPagesAuditSafe
28655
+ });
28656
+ }
28657
+ {
28658
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28564
28659
  const publishScript = resolve36(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
28565
28660
  const PUBLISH_INTERVAL_MS = 3e5;
28566
28661
  const currentAccount = () => {
@@ -28572,7 +28667,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28572
28667
  }
28573
28668
  };
28574
28669
  const spawnPublish = (account) => {
28575
- if (!existsSync37(publishScript)) return;
28670
+ if (!existsSync38(publishScript)) return;
28576
28671
  try {
28577
28672
  const child = spawn3(process.execPath, [publishScript], {
28578
28673
  env: {
@@ -28593,7 +28688,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28593
28688
  const availPath = resolve36(account.accountDir, "calendar-availability.json");
28594
28689
  let hasBookingSite = false;
28595
28690
  try {
28596
- if (existsSync37(availPath)) {
28691
+ if (existsSync38(availPath)) {
28597
28692
  const cfg = JSON.parse(readFileSync41(availPath, "utf-8"));
28598
28693
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
28599
28694
  }
@@ -28602,7 +28697,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28602
28697
  if (!hasBookingSite) return;
28603
28698
  const statePath = resolve36(account.accountDir, "state", "booking-availability", "last-publish.json");
28604
28699
  let lastSuccessAt = null;
28605
- if (existsSync37(statePath)) {
28700
+ if (existsSync38(statePath)) {
28606
28701
  try {
28607
28702
  const rec = JSON.parse(readFileSync41(statePath, "utf-8"));
28608
28703
  lastSuccessAt = rec.lastSuccessAt ?? null;
@@ -28621,20 +28716,23 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28621
28716
  spawnPublish(account);
28622
28717
  auditSnapshotAge(account);
28623
28718
  };
28624
- const firstPublish = setTimeout(publishTick, 2e4);
28625
- firstPublish.unref();
28626
- const publishLoop = setInterval(publishTick, PUBLISH_INTERVAL_MS);
28627
- publishLoop.unref();
28719
+ registerLoop({
28720
+ name: "calendar-availability-publish",
28721
+ intervalMs: PUBLISH_INTERVAL_MS,
28722
+ firstRunDelayMs: 2e4,
28723
+ detached: true,
28724
+ run: publishTick
28725
+ });
28628
28726
  }
28629
28727
  startTimeEntryCensus(() => getSession());
28630
28728
  startLedgerCensus(() => getSession());
28631
28729
  {
28632
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28730
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28633
28731
  const auditScript = resolve36(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
28634
28732
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
28635
28733
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
28636
28734
  const runConnectorAudit = () => {
28637
- if (!existsSync37(auditScript)) return;
28735
+ if (!existsSync38(auditScript)) return;
28638
28736
  try {
28639
28737
  const child = spawn3(process.execPath, [auditScript], {
28640
28738
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -28646,10 +28744,13 @@ startLedgerCensus(() => getSession());
28646
28744
  console.error(`[connector-audit] spawn-failed err="${err.message}"`);
28647
28745
  }
28648
28746
  };
28649
- const firstAudit = setTimeout(runConnectorAudit, 3e4);
28650
- firstAudit.unref();
28651
- const auditLoop = setInterval(runConnectorAudit, CONNECTOR_AUDIT_INTERVAL_MS);
28652
- auditLoop.unref();
28747
+ registerLoop({
28748
+ name: "connector-audit",
28749
+ intervalMs: CONNECTOR_AUDIT_INTERVAL_MS,
28750
+ firstRunDelayMs: 3e4,
28751
+ detached: true,
28752
+ run: runConnectorAudit
28753
+ });
28653
28754
  }
28654
28755
  {
28655
28756
  const census = pwaCensus({
@@ -28672,15 +28773,19 @@ startAuthHealthHeartbeat();
28672
28773
  loopHist.enable();
28673
28774
  const LOG_THRESHOLD_MS = 1e3;
28674
28775
  const WINDOW_MS2 = 3e4;
28675
- const lagTimer = setInterval(() => {
28676
- const maxMs = loopHist.max / 1e6;
28677
- const p99Ms = loopHist.percentile(99) / 1e6;
28678
- loopHist.reset();
28679
- if (maxMs >= LOG_THRESHOLD_MS) {
28680
- console.error(`[event-loop] lag p99=${Math.round(p99Ms)} max=${Math.round(maxMs)} window=${WINDOW_MS2 / 1e3}s`);
28776
+ registerLoop({
28777
+ name: "event-loop-lag",
28778
+ intervalMs: WINDOW_MS2,
28779
+ run: () => {
28780
+ const maxMs = loopHist.max / 1e6;
28781
+ const p99Ms = loopHist.percentile(99) / 1e6;
28782
+ loopHist.reset();
28783
+ if (maxMs >= LOG_THRESHOLD_MS) {
28784
+ console.error(`[event-loop] lag p99=${Math.round(p99Ms)} max=${Math.round(maxMs)} window=${WINDOW_MS2 / 1e3}s`);
28785
+ }
28786
+ return `p99 ${Math.round(p99Ms)}ms, max ${Math.round(maxMs)}ms`;
28681
28787
  }
28682
- }, WINDOW_MS2);
28683
- lagTimer.unref();
28788
+ });
28684
28789
  }
28685
28790
  var SUBAPP_MANIFEST = [
28686
28791
  { prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
@@ -28745,7 +28850,7 @@ try {
28745
28850
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28746
28851
  async function runAdminUserReconcileTick() {
28747
28852
  try {
28748
- if (!existsSync37(USERS_FILE)) {
28853
+ if (!existsSync38(USERS_FILE)) {
28749
28854
  console.error("[adminuser-self-heal] skip reason=no-users-file");
28750
28855
  return;
28751
28856
  }
@@ -28772,11 +28877,14 @@ async function runAdminUserReconcileTick() {
28772
28877
  console.error(`[adminuser-self-heal] rejected: ${err instanceof Error ? err.message : String(err)}`);
28773
28878
  }
28774
28879
  }
28775
- void runAdminUserReconcileTick();
28776
- var adminUserReconcileTimer = setInterval(() => {
28777
- void runAdminUserReconcileTick();
28778
- }, ADMINUSER_RECONCILE_INTERVAL_MS);
28779
- if (typeof adminUserReconcileTimer.unref === "function") adminUserReconcileTimer.unref();
28880
+ registerLoop({
28881
+ name: "adminuser-reconcile",
28882
+ intervalMs: ADMINUSER_RECONCILE_INTERVAL_MS,
28883
+ firstRunDelayMs: 0,
28884
+ // Returned, not void-called: the registry awaits it, so the recorded
28885
+ // duration and outcome describe the tick rather than the call that started it.
28886
+ run: () => runAdminUserReconcileTick()
28887
+ });
28780
28888
  var INGEST_AUDIT_INTERVAL_MS = 15 * 60 * 1e3;
28781
28889
  var runIngestAuditTick = () => {
28782
28890
  try {
@@ -28785,12 +28893,15 @@ var runIngestAuditTick = () => {
28785
28893
  console.error(`[wa-ingest-audit] rejected: ${err instanceof Error ? err.message : String(err)}`);
28786
28894
  }
28787
28895
  };
28788
- runIngestAuditTick();
28789
- var ingestAuditTimer = setInterval(runIngestAuditTick, INGEST_AUDIT_INTERVAL_MS);
28790
- if (typeof ingestAuditTimer.unref === "function") ingestAuditTimer.unref();
28896
+ registerLoop({
28897
+ name: "wa-ingest-audit",
28898
+ intervalMs: INGEST_AUDIT_INTERVAL_MS,
28899
+ firstRunDelayMs: 0,
28900
+ run: runIngestAuditTick
28901
+ });
28791
28902
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28792
28903
  function countUsersRows() {
28793
- if (!existsSync37(USERS_FILE)) return 0;
28904
+ if (!existsSync38(USERS_FILE)) return 0;
28794
28905
  const raw = readFileSync41(USERS_FILE, "utf-8").trim();
28795
28906
  if (!raw) return 0;
28796
28907
  const users = JSON.parse(raw);
@@ -28814,9 +28925,12 @@ function runUsersReconcileTick() {
28814
28925
  console.error(`[users-reconcile] op=error detail=${err instanceof Error ? err.message : String(err)}`);
28815
28926
  }
28816
28927
  }
28817
- runUsersReconcileTick();
28818
- var usersReconcileTimer = setInterval(runUsersReconcileTick, USERS_RECONCILE_INTERVAL_MS);
28819
- if (typeof usersReconcileTimer.unref === "function") usersReconcileTimer.unref();
28928
+ registerLoop({
28929
+ name: "users-reconcile",
28930
+ intervalMs: USERS_RECONCILE_INTERVAL_MS,
28931
+ firstRunDelayMs: 0,
28932
+ run: runUsersReconcileTick
28933
+ });
28820
28934
  startGraphHealthTimer();
28821
28935
  void migrateUploads().catch((err) => console.error(`[uploads-migrate] failed err="${err instanceof Error ? err.message : String(err)}"`)).finally(() => {
28822
28936
  void startFileWatcher().catch((err) => {
@@ -28825,9 +28939,19 @@ void migrateUploads().catch((err) => console.error(`[uploads-migrate] failed err
28825
28939
  });
28826
28940
  void sweepStaleUploadTemps().catch((err) => console.error(`[data-upload] op=sweep-failed err="${err instanceof Error ? err.message : String(err)}"`));
28827
28941
  var CHUNK_IDLE_TTL_MS = 30 * 60 * 1e3;
28828
- setInterval(() => {
28829
- void evictStaleChunkUploads(CHUNK_IDLE_TTL_MS).catch((err) => console.error(`[data-upload] op=evict-failed err="${err instanceof Error ? err.message : String(err)}"`));
28830
- }, 10 * 60 * 1e3).unref();
28942
+ registerLoop({
28943
+ name: "upload-chunk-evict",
28944
+ intervalMs: 10 * 60 * 1e3,
28945
+ // The domain-tagged line is kept and the rejection rethrown: existing
28946
+ // `[data-upload]` greps keep working AND the registry records the failure,
28947
+ // rather than swallowing it and reporting the run as healthy.
28948
+ run: () => evictStaleChunkUploads(CHUNK_IDLE_TTL_MS).then((evicted) => `evicted ${evicted}`).catch((err) => {
28949
+ console.error(
28950
+ `[data-upload] op=evict-failed err="${err instanceof Error ? err.message : String(err)}"`
28951
+ );
28952
+ throw err;
28953
+ })
28954
+ });
28831
28955
  void migrateAdminWebchatSidecars().catch((err) => console.error(`[sidecar-backfill] failed err="${err instanceof Error ? err.message : String(err)}"`));
28832
28956
  try {
28833
28957
  const accounts = enumerateValidAccountIds(getAccountsDirFromEnv());
@@ -28911,7 +29035,7 @@ if (bootAccountConfig?.whatsapp) {
28911
29035
  }
28912
29036
  init({
28913
29037
  configDir: configDirForWhatsApp,
28914
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..")),
29038
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..")),
28915
29039
  accountConfig: bootAccountConfig,
28916
29040
  onMessage: async (msg) => {
28917
29041
  if (msg.isOwnerMirror) {