@rubytech/create-maxy-code 0.1.473 → 0.1.475

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 (119) hide show
  1. package/dist/__tests__/google-client-id-env.test.js +3 -2
  2. package/package.json +1 -1
  3. package/payload/platform/neo4j/schema.cypher +4 -1
  4. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +29 -16
  5. package/payload/platform/plugins/docs/references/admin-ui.md +1 -1
  6. package/payload/platform/plugins/docs/references/google-guide.md +25 -12
  7. package/payload/platform/plugins/docs/references/voice-mirror-guide.md +2 -2
  8. package/payload/platform/plugins/google/.claude-plugin/plugin.json +1 -1
  9. package/payload/platform/plugins/google/PLUGIN.md +73 -14
  10. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.d.ts +2 -0
  11. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.d.ts.map +1 -0
  12. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.js +229 -0
  13. package/payload/platform/plugins/google/mcp/dist/__tests__/account-audit.test.js.map +1 -0
  14. package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js +9 -9
  15. package/payload/platform/plugins/google/mcp/dist/__tests__/account-register.test.js.map +1 -1
  16. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.d.ts +2 -0
  17. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.d.ts.map +1 -0
  18. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.js +17 -0
  19. package/payload/platform/plugins/google/mcp/dist/__tests__/consent-url-redirect.test.js.map +1 -0
  20. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.d.ts +2 -0
  21. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.d.ts.map +1 -0
  22. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.js +146 -0
  23. package/payload/platform/plugins/google/mcp/dist/__tests__/loopback-listener.test.js.map +1 -0
  24. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.d.ts +2 -0
  25. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.d.ts.map +1 -0
  26. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.js +19 -0
  27. package/payload/platform/plugins/google/mcp/dist/__tests__/pending-redirect.test.js.map +1 -0
  28. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.d.ts +2 -0
  29. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.d.ts.map +1 -0
  30. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.js +41 -0
  31. package/payload/platform/plugins/google/mcp/dist/__tests__/register-redirect-chain.test.js.map +1 -0
  32. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.d.ts +44 -0
  33. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.d.ts.map +1 -0
  34. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.js +112 -0
  35. package/payload/platform/plugins/google/mcp/dist/auth/account-audit.js.map +1 -0
  36. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.d.ts +17 -0
  37. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.d.ts.map +1 -0
  38. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.js +143 -0
  39. package/payload/platform/plugins/google/mcp/dist/auth/loopback-listener.js.map +1 -0
  40. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts +9 -0
  41. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.d.ts.map +1 -1
  42. package/payload/platform/plugins/google/mcp/dist/auth/pending-store.js.map +1 -1
  43. package/payload/platform/plugins/google/mcp/dist/index.js +73 -5
  44. package/payload/platform/plugins/google/mcp/dist/index.js.map +1 -1
  45. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.d.ts +2 -0
  46. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.d.ts.map +1 -0
  47. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.js +37 -0
  48. package/payload/platform/plugins/google/mcp/dist/scripts/account-audit.js.map +1 -0
  49. package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts +20 -4
  50. package/payload/platform/plugins/google/mcp/dist/tools/account-register.d.ts.map +1 -1
  51. package/payload/platform/plugins/google/mcp/dist/tools/account-register.js +19 -9
  52. package/payload/platform/plugins/google/mcp/dist/tools/account-register.js.map +1 -1
  53. package/payload/platform/plugins/google/references/auth.md +331 -367
  54. package/payload/platform/plugins/voice-mirror/PLUGIN.md +1 -1
  55. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js +3 -3
  56. package/payload/platform/plugins/voice-mirror/mcp/dist/index.js.map +1 -1
  57. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.d.ts +14 -1
  58. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.d.ts.map +1 -1
  59. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.js +15 -0
  60. package/payload/platform/plugins/voice-mirror/mcp/dist/lib/voice-corpus.js.map +1 -1
  61. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.d.ts.map +1 -1
  62. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js +3 -1
  63. package/payload/platform/plugins/voice-mirror/mcp/dist/tools/voice-distil-profile.js.map +1 -1
  64. package/payload/platform/plugins/voice-mirror/mcp/scripts/smoke.mjs +51 -4
  65. package/payload/platform/plugins/voice-mirror/skills/voice-mirror/SKILL.md +4 -0
  66. package/payload/platform/scripts/backfill-task-ids.sh +206 -0
  67. package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts +21 -3
  68. package/payload/platform/services/claude-session-manager/dist/activity-rows.d.ts.map +1 -1
  69. package/payload/platform/services/claude-session-manager/dist/activity-rows.js +6 -2
  70. package/payload/platform/services/claude-session-manager/dist/activity-rows.js.map +1 -1
  71. package/payload/platform/services/claude-session-manager/dist/fs-watcher.d.ts.map +1 -1
  72. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js +43 -5
  73. package/payload/platform/services/claude-session-manager/dist/fs-watcher.js.map +1 -1
  74. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts +9 -0
  75. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.d.ts.map +1 -1
  76. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js +78 -0
  77. package/payload/platform/services/claude-session-manager/dist/jsonl-enumerator.js.map +1 -1
  78. package/payload/server/public/activity.html +6 -6
  79. package/payload/server/public/assets/{AdminLoginScreens-B7TQZV8u.js → AdminLoginScreens-B44KbEuC.js} +1 -1
  80. package/payload/server/public/assets/{AdminShell-DAuri4Yh.js → AdminShell-BjxV2qkb.js} +2 -2
  81. package/payload/server/public/assets/{Checkbox-B1XhnhPk.js → Checkbox-DSeZNGNA.js} +1 -1
  82. package/payload/server/public/assets/activity-Mz1BhgB1.js +1 -0
  83. package/payload/server/public/assets/{admin-BdcccSb5.js → admin-B4LpTCur.js} +1 -1
  84. package/payload/server/public/assets/{browser-B6woQ2qX.js → browser-CEFvaWwI.js} +1 -1
  85. package/payload/server/public/assets/{calendar-CalCeg5T.js → calendar-B3zo6V34.js} +1 -1
  86. package/payload/server/public/assets/chat-5tJdo9i_.js +1 -0
  87. package/payload/server/public/assets/chevron-left-BJllrPBj.js +1 -0
  88. package/payload/server/public/assets/data-Du79EgR-.js +1 -0
  89. package/payload/server/public/assets/{graph-HeZaatSQ.js → graph-RaOrnSf2.js} +1 -1
  90. package/payload/server/public/assets/{graph-labels-4W7JuOgG.js → graph-labels-GlTEIYJj.js} +1 -1
  91. package/payload/server/public/assets/{maximize-2-DKx-aTPb.js → maximize-2-CHDa8p5h.js} +1 -1
  92. package/payload/server/public/assets/{operator-DD9L2VJM.js → operator-DtqHY4jV.js} +1 -1
  93. package/payload/server/public/assets/{page-tJxw0zNO.js → page-CkhFj8GQ.js} +1 -1
  94. package/payload/server/public/assets/{page-Ceado9Kr.js → page-DxnWgPtd.js} +1 -1
  95. package/payload/server/public/assets/{public-BYFWxyeC.js → public-D5TUfQ3I.js} +1 -1
  96. package/payload/server/public/assets/{rotate-ccw-DrzdV9h7.js → rotate-ccw-BJjVAQQY.js} +1 -1
  97. package/payload/server/public/assets/tasks-CM9pYYG1.js +1 -0
  98. package/payload/server/public/assets/{time-entry-format-Bn79w6tq.js → time-entry-format-C5RYEYjM.js} +1 -1
  99. package/payload/server/public/assets/{triangle-alert-CjDVh6r-.js → triangle-alert-DLfIsuo_.js} +1 -1
  100. package/payload/server/public/assets/{useCopyFeedback-DXHkkJw-.js → useCopyFeedback-7yKeiAzV.js} +1 -1
  101. package/payload/server/public/assets/{useSelectionMode-D2H8jAhE.js → useSelectionMode-CWlh6AEq.js} +1 -1
  102. package/payload/server/public/assets/{useSubAccountSwitcher-Br7Z6Cpu.css → useSubAccountSwitcher-B2n9QPVI.css} +1 -1
  103. package/payload/server/public/assets/{useVoiceRecorder-zUvPe55I.js → useVoiceRecorder-j3ZArZ2H.js} +1 -1
  104. package/payload/server/public/browser.html +5 -5
  105. package/payload/server/public/calendar.html +6 -6
  106. package/payload/server/public/chat.html +12 -12
  107. package/payload/server/public/data.html +11 -11
  108. package/payload/server/public/graph.html +11 -11
  109. package/payload/server/public/index.html +14 -14
  110. package/payload/server/public/operator.html +14 -14
  111. package/payload/server/public/public.html +12 -12
  112. package/payload/server/public/tasks.html +5 -5
  113. package/payload/server/server.js +433 -313
  114. package/payload/server/public/assets/activity-kRwzxEKU.js +0 -1
  115. package/payload/server/public/assets/chat-9s2-L06v.js +0 -1
  116. package/payload/server/public/assets/chevron-left-C3ho8SnB.js +0 -1
  117. package/payload/server/public/assets/data-Cfr-7ERI.js +0 -1
  118. package/payload/server/public/assets/tasks-DSwoxGzh.js +0 -1
  119. /package/payload/server/public/assets/{useSubAccountSwitcher-CUJpgkKI.js → useSubAccountSwitcher-CBlKgwms.js} +0 -0
@@ -1534,10 +1534,10 @@ var serveStatic = (options = { root: "" }) => {
1534
1534
  };
1535
1535
 
1536
1536
  // server/index.ts
1537
- import { readFileSync as readFileSync41, existsSync as existsSync37, watchFile, readdirSync as readdirSync25, statSync as statSync16 } from "fs";
1537
+ import { readFileSync as readFileSync41, existsSync as existsSync38, watchFile, readdirSync as readdirSync26, statSync as statSync17 } from "fs";
1538
1538
  import { spawn as spawn3 } from "child_process";
1539
1539
  import { createHash as createHash7 } from "crypto";
1540
- import { resolve as resolve36, join as join41, basename as basename12 } from "path";
1540
+ import { resolve as resolve36, join as join42, basename as basename12 } from "path";
1541
1541
  import { homedir as homedir4 } from "os";
1542
1542
  import { monitorEventLoopDelay } from "perf_hooks";
1543
1543
 
@@ -8448,6 +8448,23 @@ function conversationCounterpartyPhone(remoteJid, earliestSenderTelephone) {
8448
8448
  function counterpartyBoundToSubAccount(managerPhones, counterpartyPhone) {
8449
8449
  return counterpartyPhone != null && managerPhones.some((mp) => phonesMatch(mp, counterpartyPhone));
8450
8450
  }
8451
+ function storePushNamesBySender(summaries) {
8452
+ const best = /* @__PURE__ */ new Map();
8453
+ const out = /* @__PURE__ */ new Map();
8454
+ for (const [remoteJid, { first, last, firstNamedSender }] of summaries) {
8455
+ if (!firstNamedSender) continue;
8456
+ const phone = conversationCounterpartyPhone(remoteJid, first.senderTelephone);
8457
+ if (!phone) continue;
8458
+ const key = normalizeE164(phone);
8459
+ if (key.length === 0) continue;
8460
+ const at = last.dateSent ?? "";
8461
+ const seen = best.get(key);
8462
+ if (seen !== void 0 && (seen.at > at || seen.at === at && seen.jid <= remoteJid)) continue;
8463
+ best.set(key, { at, jid: remoteJid });
8464
+ out.set(key, firstNamedSender);
8465
+ }
8466
+ return out;
8467
+ }
8451
8468
  function buildStoreConversationRows(accountId, summaries) {
8452
8469
  const rows = [];
8453
8470
  for (const [remoteJid, { first, last, firstNamedSender }] of summaries) {
@@ -9670,46 +9687,74 @@ async function runPagesAudit(root) {
9670
9687
  }
9671
9688
  }
9672
9689
 
9690
+ // server/google-pending-audit.ts
9691
+ import { existsSync as existsSync10, readdirSync as readdirSync9, statSync as statSync4 } from "fs";
9692
+ import { join as join14 } from "path";
9693
+ var GOOGLE_PENDING_LIFETIME_SEC = 600;
9694
+ var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9695
+ function runGooglePendingAudit(accountsDir, nowMs, emit, readMtimeMs = (path3) => statSync4(path3).mtimeMs) {
9696
+ let scanned = 0;
9697
+ let stranded = 0;
9698
+ if (existsSync10(accountsDir)) {
9699
+ for (const accountId of readdirSync9(accountsDir)) {
9700
+ if (!UUID_RE2.test(accountId)) continue;
9701
+ const pendingPath2 = join14(accountsDir, accountId, "secrets", "google", "pending-oauth.enc");
9702
+ try {
9703
+ if (!existsSync10(pendingPath2)) continue;
9704
+ const ageSec = Math.max(0, Math.floor((nowMs - readMtimeMs(pendingPath2)) / 1e3));
9705
+ scanned += 1;
9706
+ if (ageSec >= GOOGLE_PENDING_LIFETIME_SEC) {
9707
+ stranded += 1;
9708
+ emit(`[google-oauth] op=pending-stranded account=${accountId} ageSec=${ageSec}`);
9709
+ }
9710
+ } catch {
9711
+ }
9712
+ }
9713
+ }
9714
+ emit(`[google-oauth] op=pending-audit scanned=${scanned} stranded=${stranded}`);
9715
+ return { scanned, stranded };
9716
+ }
9717
+
9673
9718
  // server/routes/whatsapp-reader.ts
9674
- import { readFileSync as readFileSync19, watch, statSync as statSync6, openSync, readSync, closeSync, existsSync as existsSync12, readdirSync as readdirSync13, realpathSync as realpathSync5 } from "fs";
9675
- import { basename as basename4, dirname as dirname5, isAbsolute, join as join18, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
9719
+ import { readFileSync as readFileSync19, watch, statSync as statSync7, openSync, readSync, closeSync, existsSync as existsSync13, readdirSync as readdirSync14, realpathSync as realpathSync5 } from "fs";
9720
+ import { basename as basename4, dirname as dirname5, isAbsolute, join as join19, relative as relative2, resolve as resolve13, sep as sep3 } from "path";
9676
9721
 
9677
9722
  // server/routes/admin/sidebar-sessions.ts
9678
- import { readdirSync as readdirSync11, readFileSync as readFileSync17, statSync as statSync5 } from "fs";
9679
- import { dirname as dirname4, join as join16, resolve as resolve12 } from "path";
9723
+ import { readdirSync as readdirSync12, readFileSync as readFileSync17, statSync as statSync6 } from "fs";
9724
+ import { dirname as dirname4, join as join17, resolve as resolve12 } from "path";
9680
9725
 
9681
9726
  // ../services/claude-session-manager/src/jsonl-path.ts
9682
- import { existsSync as existsSync10, readdirSync as readdirSync9 } from "fs";
9727
+ import { existsSync as existsSync11, readdirSync as readdirSync10 } from "fs";
9683
9728
  import { homedir } from "os";
9684
- import { join as join14 } from "path";
9729
+ import { join as join15 } from "path";
9685
9730
  function findExistingJsonlForSessionId(claudeConfigDir2, sessionId) {
9686
- const projectsRoot = join14(claudeConfigDir2, "projects");
9687
- if (!existsSync10(projectsRoot)) return null;
9731
+ const projectsRoot = join15(claudeConfigDir2, "projects");
9732
+ if (!existsSync11(projectsRoot)) return null;
9688
9733
  let slugs;
9689
9734
  try {
9690
- slugs = readdirSync9(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9735
+ slugs = readdirSync10(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9691
9736
  } catch {
9692
9737
  return null;
9693
9738
  }
9694
9739
  const basename13 = `${sessionId}.jsonl`;
9695
9740
  for (const slug of slugs) {
9696
- const live = join14(projectsRoot, slug, basename13);
9697
- if (existsSync10(live)) return live;
9698
- const archived = join14(projectsRoot, slug, "archive", basename13);
9699
- if (existsSync10(archived)) return archived;
9741
+ const live = join15(projectsRoot, slug, basename13);
9742
+ if (existsSync11(live)) return live;
9743
+ const archived = join15(projectsRoot, slug, "archive", basename13);
9744
+ if (existsSync11(archived)) return archived;
9700
9745
  }
9701
9746
  return null;
9702
9747
  }
9703
9748
 
9704
9749
  // app/lib/admin-identity/pin-validator.ts
9705
9750
  import { createHash as createHash3 } from "crypto";
9706
- import { existsSync as existsSync11, readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync4 } from "fs";
9707
- import { join as join15 } from "path";
9751
+ import { existsSync as existsSync12, readFileSync as readFileSync16, readdirSync as readdirSync11, statSync as statSync5 } from "fs";
9752
+ import { join as join16 } from "path";
9708
9753
  function hashPin(pin) {
9709
9754
  return createHash3("sha256").update(pin).digest("hex");
9710
9755
  }
9711
9756
  function readUsersFile(usersFilePath) {
9712
- if (!existsSync11(usersFilePath)) return null;
9757
+ if (!existsSync12(usersFilePath)) return null;
9713
9758
  const raw = readFileSync16(usersFilePath, "utf-8").trim();
9714
9759
  if (!raw) return [];
9715
9760
  return JSON.parse(raw);
@@ -9829,16 +9874,16 @@ function enumerateJsonls(projectsRoot) {
9829
9874
  const out = [];
9830
9875
  let slugs;
9831
9876
  try {
9832
- slugs = readdirSync11(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9877
+ slugs = readdirSync12(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
9833
9878
  } catch (err) {
9834
9879
  if (err.code === "ENOENT") return out;
9835
9880
  throw err;
9836
9881
  }
9837
9882
  for (const slug of slugs) {
9838
- const slugDir = join16(projectsRoot, slug);
9883
+ const slugDir = join17(projectsRoot, slug);
9839
9884
  let entries;
9840
9885
  try {
9841
- entries = readdirSync11(slugDir, { withFileTypes: true });
9886
+ entries = readdirSync12(slugDir, { withFileTypes: true });
9842
9887
  } catch (err) {
9843
9888
  const code = err.code ?? "unknown";
9844
9889
  console.error(`[admin-sessions-list] slug-skipped slug=${slug} code=${code}`);
@@ -9846,12 +9891,12 @@ function enumerateJsonls(projectsRoot) {
9846
9891
  }
9847
9892
  for (const entry of entries) {
9848
9893
  if (entry.isFile() && SESSION_ID_RE.test(entry.name)) {
9849
- out.push({ path: join16(slugDir, entry.name), isSubagent: false, archived: false });
9894
+ out.push({ path: join17(slugDir, entry.name), isSubagent: false, archived: false });
9850
9895
  } else if (entry.isDirectory() && entry.name === "subagents") {
9851
- const subDir = join16(slugDir, entry.name);
9896
+ const subDir = join17(slugDir, entry.name);
9852
9897
  let subEntries;
9853
9898
  try {
9854
- subEntries = readdirSync11(subDir, { withFileTypes: true });
9899
+ subEntries = readdirSync12(subDir, { withFileTypes: true });
9855
9900
  } catch (err) {
9856
9901
  const code = err.code ?? "unknown";
9857
9902
  console.error(`[admin-sessions-list] subagents-skipped slug=${slug} code=${code}`);
@@ -9859,14 +9904,14 @@ function enumerateJsonls(projectsRoot) {
9859
9904
  }
9860
9905
  for (const sub of subEntries) {
9861
9906
  if (sub.isFile() && SESSION_ID_RE.test(sub.name)) {
9862
- out.push({ path: join16(subDir, sub.name), isSubagent: true, archived: false });
9907
+ out.push({ path: join17(subDir, sub.name), isSubagent: true, archived: false });
9863
9908
  }
9864
9909
  }
9865
9910
  } else if (entry.isDirectory() && entry.name === "archive") {
9866
- const archiveDir = join16(slugDir, entry.name);
9911
+ const archiveDir = join17(slugDir, entry.name);
9867
9912
  let archiveEntries;
9868
9913
  try {
9869
- archiveEntries = readdirSync11(archiveDir, { withFileTypes: true });
9914
+ archiveEntries = readdirSync12(archiveDir, { withFileTypes: true });
9870
9915
  } catch (err) {
9871
9916
  const code = err.code ?? "unknown";
9872
9917
  console.error(`[admin-sessions-list] archive-skipped slug=${slug} code=${code}`);
@@ -9874,7 +9919,7 @@ function enumerateJsonls(projectsRoot) {
9874
9919
  }
9875
9920
  for (const arc of archiveEntries) {
9876
9921
  if (arc.isFile() && SESSION_ID_RE.test(arc.name)) {
9877
- out.push({ path: join16(archiveDir, arc.name), isSubagent: false, archived: true });
9922
+ out.push({ path: join17(archiveDir, arc.name), isSubagent: false, archived: true });
9878
9923
  }
9879
9924
  }
9880
9925
  }
@@ -9907,7 +9952,7 @@ async function fetchLiveSessions() {
9907
9952
  function loadUserTitles(accountDir) {
9908
9953
  const out = /* @__PURE__ */ new Map();
9909
9954
  if (!accountDir) return out;
9910
- const path3 = join16(accountDir, "session-titles.json");
9955
+ const path3 = join17(accountDir, "session-titles.json");
9911
9956
  let raw;
9912
9957
  try {
9913
9958
  raw = readFileSync17(path3, "utf8");
@@ -10034,7 +10079,7 @@ app4.get("/", requireAdminSession, async (c) => {
10034
10079
  console.error("[admin-sessions-list] CLAUDE_CONFIG_DIR not set; returning empty list");
10035
10080
  return c.json({ sessions: [], accountId: scopeAccountId });
10036
10081
  }
10037
- const projectsRoot = join16(configDir2, "projects");
10082
+ const projectsRoot = join17(configDir2, "projects");
10038
10083
  const jsonls = enumerateJsonls(projectsRoot);
10039
10084
  const liveSessions = await fetchLiveSessions();
10040
10085
  const accountDir = scopeAccountId ? resolve12(ACCOUNTS_DIR, scopeAccountId) : null;
@@ -10079,7 +10124,7 @@ app4.get("/", requireAdminSession, async (c) => {
10079
10124
  let mtimeMs;
10080
10125
  try {
10081
10126
  body = readFileSync17(path3, "utf8");
10082
- mtimeMs = statSync5(path3).mtimeMs;
10127
+ mtimeMs = statSync6(path3).mtimeMs;
10083
10128
  } catch {
10084
10129
  continue;
10085
10130
  }
@@ -10087,7 +10132,7 @@ app4.get("/", requireAdminSession, async (c) => {
10087
10132
  const pid = live ? liveSessions.get(sessionId) ?? null : null;
10088
10133
  const resolved = resolveTitle(body, sessionId, userTitles);
10089
10134
  titleSourceCounts[resolved.source] += 1;
10090
- const metaPath = join16(projectDir, `${sessionId}.meta.json`);
10135
+ const metaPath = join17(projectDir, `${sessionId}.meta.json`);
10091
10136
  const { bridgeIds, role, channel: sidecarChannel, senderId, personId, adminUserId, accountId: rowAccountId } = readSidecarMeta(metaPath);
10092
10137
  if (multiAccount) {
10093
10138
  if (rowAccountId === null) untaggedCount += 1;
@@ -10121,7 +10166,8 @@ app4.get("/", requireAdminSession, async (c) => {
10121
10166
  personName: null,
10122
10167
  model: lastAssistantModel(body),
10123
10168
  accountId: rowAccountId,
10124
- senderId
10169
+ senderId,
10170
+ whatsappName: null
10125
10171
  });
10126
10172
  if ((sidecarChannel === "whatsapp" || sidecarChannel === "telegram") && resolved.source === "prefix") {
10127
10173
  if (senderId) channelSenderBySession.set(sessionId, senderId);
@@ -10162,20 +10208,36 @@ app4.get("/", requireAdminSession, async (c) => {
10162
10208
  );
10163
10209
  }
10164
10210
  let channelNamesResolved = 0;
10211
+ let operatorResolvedCount = 0;
10212
+ let storeResolvedCount = 0;
10165
10213
  const channelNameCandidates = channelSenderBySession.size + channelMissNoSender.length;
10166
10214
  if (account && channelSenderBySession.size > 0) {
10167
10215
  const resolvedNames = await resolveOperatorNamesBySender(channelUsers, channelAdmins, channelSenderBySession.values());
10216
+ let pushNames = /* @__PURE__ */ new Map();
10217
+ try {
10218
+ pushNames = storePushNamesBySender(readConversationSummaries(account.accountId));
10219
+ } catch (err) {
10220
+ console.error(`[admin-sessions-list] op=store-unreadable reason=${err instanceof Error ? err.message : String(err)}`);
10221
+ }
10168
10222
  for (const row of rows) {
10169
10223
  const rowSenderId = channelSenderBySession.get(row.sessionId);
10170
10224
  if (!rowSenderId) continue;
10171
10225
  const r = resolvedNames.get(rowSenderId) ?? { name: null, reason: "no-binding" };
10172
10226
  if (r.name) {
10173
10227
  row.personName = r.name;
10228
+ operatorResolvedCount += 1;
10174
10229
  channelNamesResolved += 1;
10175
- } else {
10176
- const reason = r.reason === "neo4j-unreachable" ? "neo4j-down" : "classify-miss";
10177
- console.error(`[admin-sessions-list] op=channel-name-unresolved sessionId=${row.sessionId.slice(0, 8)} channel=${row.channel} senderId=${rowSenderId} reason=${reason}`);
10230
+ continue;
10178
10231
  }
10232
+ const pushName = row.channel === "whatsapp" && r.reason === "no-binding" ? pushNames.get(normalizeE164(rowSenderId)) ?? null : null;
10233
+ if (pushName) {
10234
+ row.whatsappName = pushName;
10235
+ storeResolvedCount += 1;
10236
+ channelNamesResolved += 1;
10237
+ continue;
10238
+ }
10239
+ const reason = r.reason === "neo4j-unreachable" ? "neo4j-down" : "classify-miss";
10240
+ console.error(`[admin-sessions-list] op=channel-name-unresolved sessionId=${row.sessionId.slice(0, 8)} channel=${row.channel} senderId=${rowSenderId} reason=${reason}`);
10179
10241
  }
10180
10242
  }
10181
10243
  for (const m of channelMissNoSender) {
@@ -10183,7 +10245,7 @@ app4.get("/", requireAdminSession, async (c) => {
10183
10245
  }
10184
10246
  rows.sort((a, b) => a.startedAt < b.startedAt ? 1 : -1);
10185
10247
  console.log(
10186
- `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} channelInList=whatsapp:${channelInList.whatsapp},telegram:${channelInList.telegram},webchat:${channelInList.webchat} channelNameCandidates=${channelNameCandidates} channelNamesResolved=${channelNamesResolved} unknownChannel=${unknownChannelCount} excludedPublicWebchat=${excludedPublicWebchatCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"}`
10248
+ `[admin-sessions-list] rows=${rows.length} live=${liveCount} subagents=${subagentCount} archived=${archivedCount} channelInList=whatsapp:${channelInList.whatsapp},telegram:${channelInList.telegram},webchat:${channelInList.webchat} channelNameCandidates=${channelNameCandidates} channelNamesResolved=${channelNamesResolved} (operator=${operatorResolvedCount} store=${storeResolvedCount}) unknownChannel=${unknownChannelCount} excludedPublicWebchat=${excludedPublicWebchatCount} titles user=${titleSourceCounts.user} ai=${titleSourceCounts.ai} first=${titleSourceCounts["first-message"]} prefix=${titleSourceCounts.prefix} personNames=${personNameCount} adminNames=${adminNameCount} accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"}`
10187
10249
  );
10188
10250
  console.log(
10189
10251
  `[admin-sessions-list] accountId=${scopeAccountId ? scopeAccountId.slice(0, 8) : "unset"} scope=${multiAccount ? "scoped" : "all"} rows=${rows.length}`
@@ -10483,8 +10545,8 @@ function parseTranscript(lines, queuedPendingSuppress = /* @__PURE__ */ new Map(
10483
10545
  }
10484
10546
 
10485
10547
  // app/lib/whatsapp-reader/enrich-attachments.ts
10486
- import { readFileSync as readFileSync18, readdirSync as readdirSync12 } from "fs";
10487
- import { join as join17 } from "path";
10548
+ import { readFileSync as readFileSync18, readdirSync as readdirSync13 } from "fs";
10549
+ import { join as join18 } from "path";
10488
10550
  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;
10489
10551
  function adminAttachmentIds(text) {
10490
10552
  const ids = [];
@@ -10497,7 +10559,7 @@ function adminAttachmentIds(text) {
10497
10559
  function adminAttachmentsFromText(text, uploadsBase) {
10498
10560
  const out = [];
10499
10561
  for (const id of adminAttachmentIds(text)) {
10500
- const meta = readAttachmentMeta(join17(uploadsBase, id));
10562
+ const meta = readAttachmentMeta(join18(uploadsBase, id));
10501
10563
  if (meta) out.push(meta);
10502
10564
  }
10503
10565
  return out;
@@ -10505,7 +10567,7 @@ function adminAttachmentsFromText(text, uploadsBase) {
10505
10567
  function readSidecar(dir, attachmentId) {
10506
10568
  let parsed;
10507
10569
  try {
10508
- parsed = JSON.parse(readFileSync18(join17(dir, `${attachmentId}.meta.json`), "utf8"));
10570
+ parsed = JSON.parse(readFileSync18(join18(dir, `${attachmentId}.meta.json`), "utf8"));
10509
10571
  } catch {
10510
10572
  return null;
10511
10573
  }
@@ -10528,13 +10590,13 @@ function readAttachmentMeta(dir) {
10528
10590
  function listSessionAttachmentsInDir(dir) {
10529
10591
  let entries;
10530
10592
  try {
10531
- entries = readdirSync12(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10593
+ entries = readdirSync13(dir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
10532
10594
  } catch {
10533
10595
  return [];
10534
10596
  }
10535
10597
  const sidecars = [];
10536
10598
  for (const name of entries) {
10537
- const sidecar = readSidecar(join17(dir, name), name);
10599
+ const sidecar = readSidecar(join18(dir, name), name);
10538
10600
  if (sidecar) sidecars.push(sidecar);
10539
10601
  }
10540
10602
  sidecars.sort((a, b) => a.storedAt.localeCompare(b.storedAt));
@@ -10694,14 +10756,14 @@ app5.get("/conversations", requireAdminSession, async (c) => {
10694
10756
  }
10695
10757
  const cfg = claudeConfigDir();
10696
10758
  if (!cfg) return c.json({ conversations: [] });
10697
- const projectsRoot = join18(cfg, "projects");
10759
+ const projectsRoot = join19(cfg, "projects");
10698
10760
  const userTitles = loadUserTitles(ACCOUNTS_DIR ?? null);
10699
10761
  const rows = [];
10700
10762
  let sessionRowsExcludedUntagged = 0;
10701
10763
  for (const { path: path3 } of enumerateJsonls(projectsRoot)) {
10702
10764
  const sessionId = basename4(path3).replace(/\.jsonl$/, "");
10703
10765
  const projectDir = dirname5(path3);
10704
- const meta = readSidecarMeta(join18(projectDir, `${sessionId}.meta.json`));
10766
+ const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
10705
10767
  if (!isReaderChannelSession(meta.role, meta.channel)) continue;
10706
10768
  if (multiAccount) {
10707
10769
  if (meta.accountId === null) sessionRowsExcludedUntagged += 1;
@@ -10793,7 +10855,7 @@ app5.get("/conversations", requireAdminSession, async (c) => {
10793
10855
  return c.json({ conversations: [...sessionConversations, ...allStoreRows] });
10794
10856
  });
10795
10857
  function readFrom(path3, from) {
10796
- const end = statSync6(path3).size;
10858
+ const end = statSync7(path3).size;
10797
10859
  if (end <= from) return { buf: Buffer.alloc(0), end: from };
10798
10860
  const fd = openSync(path3, "r");
10799
10861
  try {
@@ -10878,7 +10940,7 @@ function openTaskKey(turns) {
10878
10940
  }
10879
10941
  function readSubagentMeta(dir, hex) {
10880
10942
  try {
10881
- const m = JSON.parse(readFileSync19(join18(dir, `agent-${hex}.meta.json`), "utf8"));
10943
+ const m = JSON.parse(readFileSync19(join19(dir, `agent-${hex}.meta.json`), "utf8"));
10882
10944
  if (typeof m.agentType === "string" && typeof m.description === "string" && typeof m.toolUseId === "string") {
10883
10945
  return { agentType: m.agentType, description: m.description, toolUseId: m.toolUseId };
10884
10946
  }
@@ -10901,7 +10963,7 @@ function runActivityTick(c) {
10901
10963
  c.parentGrewThisTick = false;
10902
10964
  let names = [];
10903
10965
  try {
10904
- names = readdirSync13(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
10966
+ names = readdirSync14(c.subagentsDir).filter((n) => AGENT_JSONL_RE.test(n));
10905
10967
  } catch {
10906
10968
  }
10907
10969
  const entries = [];
@@ -10910,7 +10972,7 @@ function runActivityTick(c) {
10910
10972
  let size = 0;
10911
10973
  let mtimeMs = 0;
10912
10974
  try {
10913
- const st = statSync6(join18(c.subagentsDir, name));
10975
+ const st = statSync7(join19(c.subagentsDir, name));
10914
10976
  size = st.size;
10915
10977
  mtimeMs = st.mtimeMs;
10916
10978
  } catch {
@@ -10955,11 +11017,11 @@ app5.get("/stream", requireAdminSession, (c) => {
10955
11017
  const sessionId = c.req.query("sessionId") ?? "";
10956
11018
  const projectDir = c.req.query("projectDir") ?? "";
10957
11019
  const cfg = claudeConfigDir();
10958
- const projectsRoot = cfg ? resolve13(join18(cfg, "projects")) : null;
11020
+ const projectsRoot = cfg ? resolve13(join19(cfg, "projects")) : null;
10959
11021
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
10960
11022
  return c.json({ error: "bad session reference" }, 400);
10961
11023
  }
10962
- const jsonlPath = resolve13(join18(projectDir, `${sessionId}.jsonl`));
11024
+ const jsonlPath = resolve13(join19(projectDir, `${sessionId}.jsonl`));
10963
11025
  if (!jsonlPath.startsWith(projectsRoot + sep3)) {
10964
11026
  return c.json({ error: "bad session reference" }, 400);
10965
11027
  }
@@ -10978,7 +11040,7 @@ data: ${JSON.stringify(turn)}
10978
11040
  start(controller) {
10979
11041
  const fileEnd0 = (() => {
10980
11042
  try {
10981
- return statSync6(jsonlPath).size;
11043
+ return statSync7(jsonlPath).size;
10982
11044
  } catch {
10983
11045
  return 0;
10984
11046
  }
@@ -10986,9 +11048,9 @@ data: ${JSON.stringify(turn)}
10986
11048
  let offset = resumeOffset(lastEventId, fileEnd0);
10987
11049
  console.log(`[wa-stream] op=open conn=${connId} sessionId=${sessionId} channel=reader resume=${offset}`);
10988
11050
  const sessionKey = c.req.query("session_key") ?? "";
10989
- const subagentsDir = resolve13(join18(projectDir, sessionId, "subagents"));
11051
+ const subagentsDir = resolve13(join19(projectDir, sessionId, "subagents"));
10990
11052
  console.log(
10991
- `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync12(subagentsDir)}`
11053
+ `[webchat-activity] op=watch-subagents key=${sessionKey} dir=${subagentsDir} exists=${existsSync13(subagentsDir)}`
10992
11054
  );
10993
11055
  const actx = makeActivityCtx({
10994
11056
  subagentsDir,
@@ -11102,10 +11164,10 @@ app5.get("/directives", requireAdminSession, (c) => {
11102
11164
  const sessionId = c.req.query("sessionId") ?? "";
11103
11165
  if (!SESSION_ID_RE2.test(sessionId)) return c.json({ error: "bad session reference" }, 400);
11104
11166
  const dir = directiveStoreDir(sessionId);
11105
- if (!dir || !existsSync12(dir)) return c.json({ entries: [] });
11167
+ if (!dir || !existsSync13(dir)) return c.json({ entries: [] });
11106
11168
  let names;
11107
11169
  try {
11108
- names = readdirSync13(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
11170
+ names = readdirSync14(dir).filter((n) => DIRECTIVE_NAME_RE.test(n));
11109
11171
  } catch {
11110
11172
  return c.json({ entries: [] });
11111
11173
  }
@@ -11115,7 +11177,7 @@ app5.get("/directives", requireAdminSession, (c) => {
11115
11177
  const pid = Number(pidPart);
11116
11178
  let len = 0;
11117
11179
  try {
11118
- len = statSync6(join18(dir, name)).size;
11180
+ len = statSync7(join19(dir, name)).size;
11119
11181
  } catch {
11120
11182
  }
11121
11183
  return { name, secs, pid, ts: Number.isFinite(secs) ? new Date(secs * 1e3).toISOString() : null, len };
@@ -11130,7 +11192,7 @@ app5.get("/directive", requireAdminSession, (c) => {
11130
11192
  }
11131
11193
  const dir = directiveStoreDir(sessionId);
11132
11194
  if (!dir) return c.json({ error: "no account" }, 404);
11133
- const path3 = resolve13(join18(dir, name));
11195
+ const path3 = resolve13(join19(dir, name));
11134
11196
  if (!path3.startsWith(dir + sep3)) return c.json({ error: "bad reference" }, 400);
11135
11197
  let body;
11136
11198
  try {
@@ -11188,7 +11250,7 @@ app5.get("/store-stream", requireAdminSession, (c) => {
11188
11250
  console.log(`[wa-reader] op=store-quote msgId=${r.msgKeyId} quoted=${!!q}`);
11189
11251
  }
11190
11252
  if (r.attachmentId) {
11191
- const meta = readAttachmentMeta(join18(uploadsBase, r.attachmentId));
11253
+ const meta = readAttachmentMeta(join19(uploadsBase, r.attachmentId));
11192
11254
  if (meta) return { ...turn, attachments: [meta] };
11193
11255
  }
11194
11256
  return turn;
@@ -11221,7 +11283,7 @@ data: ${JSON.stringify(payload)}
11221
11283
  };
11222
11284
  const fileEnd0 = (() => {
11223
11285
  try {
11224
- return statSync6(file).size;
11286
+ return statSync7(file).size;
11225
11287
  } catch {
11226
11288
  return 0;
11227
11289
  }
@@ -11439,7 +11501,7 @@ app5.post("/reply", requireAdminSession, async (c) => {
11439
11501
  const absolute = resolved.absolute;
11440
11502
  let size = -1;
11441
11503
  try {
11442
- const st = statSync6(absolute);
11504
+ const st = statSync7(absolute);
11443
11505
  size = st.isFile() ? st.size : -1;
11444
11506
  } catch {
11445
11507
  size = -1;
@@ -11563,8 +11625,8 @@ app5.post("/reply", requireAdminSession, async (c) => {
11563
11625
  var whatsapp_reader_default = app5;
11564
11626
 
11565
11627
  // server/routes/public-reader.ts
11566
- import { statSync as statSync7, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync20, readdirSync as readdirSync14 } from "fs";
11567
- import { basename as basename5, dirname as dirname6, join as join19, resolve as resolve14, sep as sep4 } from "path";
11628
+ import { statSync as statSync8, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, watch as watch2, readFileSync as readFileSync20, readdirSync as readdirSync15 } from "fs";
11629
+ import { basename as basename5, dirname as dirname6, join as join20, resolve as resolve14, sep as sep4 } from "path";
11568
11630
 
11569
11631
  // app/lib/whatsapp-reader/delivered-kinds.ts
11570
11632
  var PUBLIC_DELIVERED_KINDS = /* @__PURE__ */ new Set([
@@ -11638,10 +11700,10 @@ function enumeratePublicRows() {
11638
11700
  const cfg = claudeConfigDir();
11639
11701
  if (!cfg) return [];
11640
11702
  const rows = [];
11641
- for (const { path: path3 } of enumerateJsonls(join19(cfg, "projects"))) {
11703
+ for (const { path: path3 } of enumerateJsonls(join20(cfg, "projects"))) {
11642
11704
  const sessionId = basename5(path3).replace(/\.jsonl$/, "");
11643
11705
  const projectDir = dirname6(path3);
11644
- const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
11706
+ const meta = readSidecarMeta(join20(projectDir, `${sessionId}.meta.json`));
11645
11707
  rows.push({
11646
11708
  sessionId,
11647
11709
  projectDir,
@@ -11697,7 +11759,7 @@ function enrichPublicAttachments(turns, sessionAttachments, cursor) {
11697
11759
  }
11698
11760
  }
11699
11761
  function readFrom2(path3, from) {
11700
- const end = statSync7(path3).size;
11762
+ const end = statSync8(path3).size;
11701
11763
  if (end <= from) return { buf: Buffer.alloc(0), end: from };
11702
11764
  const fd = openSync2(path3, "r");
11703
11765
  try {
@@ -11717,15 +11779,15 @@ app6.get("/stream", (c) => {
11717
11779
  const sessionId = c.req.query("sessionId") ?? "";
11718
11780
  const projectDir = c.req.query("projectDir") ?? "";
11719
11781
  const cfg = claudeConfigDir();
11720
- const projectsRoot = cfg ? resolve14(join19(cfg, "projects")) : null;
11782
+ const projectsRoot = cfg ? resolve14(join20(cfg, "projects")) : null;
11721
11783
  if (!cfg || !projectsRoot || !SESSION_ID_RE2.test(sessionId)) {
11722
11784
  return c.json({ error: "bad session reference" }, 400);
11723
11785
  }
11724
- const jsonlPath = resolve14(join19(projectDir, `${sessionId}.jsonl`));
11786
+ const jsonlPath = resolve14(join20(projectDir, `${sessionId}.jsonl`));
11725
11787
  if (!jsonlPath.startsWith(projectsRoot + sep4)) {
11726
11788
  return c.json({ error: "bad session reference" }, 400);
11727
11789
  }
11728
- const meta = readSidecarMeta(join19(projectDir, `${sessionId}.meta.json`));
11790
+ const meta = readSidecarMeta(join20(projectDir, `${sessionId}.meta.json`));
11729
11791
  const isPublicWebchat = meta.role === "public" && meta.channel === "webchat";
11730
11792
  const owns = visitor.kind === "person" ? meta.personId === visitor.personId : meta.personId === null && meta.visitorId === visitor.visitorId;
11731
11793
  if (!(isPublicWebchat && owns)) {
@@ -11838,7 +11900,7 @@ app6.get("/attachment/:attachmentId", (c) => {
11838
11900
  let dataFile;
11839
11901
  let buffer;
11840
11902
  try {
11841
- dataFile = readdirSync14(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
11903
+ dataFile = readdirSync15(dir).find((f) => !f.endsWith(".meta.json") && !f.endsWith(EXTRACTED_TEXT_SUFFIX));
11842
11904
  if (!dataFile) throw new Error("no data file");
11843
11905
  buffer = readFileSync20(resolve14(dir, dataFile));
11844
11906
  } catch {
@@ -11862,16 +11924,16 @@ var public_reader_default = app6;
11862
11924
 
11863
11925
  // server/routes/webchat.ts
11864
11926
  import { basename as basename6, dirname as dirname7 } from "path";
11865
- import { join as join22 } from "path";
11866
- import { existsSync as existsSync14, readdirSync as readdirSync16, readFileSync as readFileSync23, renameSync as renameSync4, statSync as statSync8, writeFileSync as writeFileSync8 } from "fs";
11927
+ import { join as join23 } from "path";
11928
+ import { existsSync as existsSync15, readdirSync as readdirSync17, readFileSync as readFileSync23, renameSync as renameSync4, statSync as statSync9, writeFileSync as writeFileSync8 } from "fs";
11867
11929
 
11868
11930
  // server/canonical-webchat-override.ts
11869
11931
  import { readFileSync as readFileSync21, writeFileSync as writeFileSync6, renameSync as renameSync2 } from "fs";
11870
- import { join as join20 } from "path";
11932
+ import { join as join21 } from "path";
11871
11933
  var FILE = "canonical-webchat-session.json";
11872
11934
  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}$/;
11873
11935
  function canonicalOverridePath(accountDir) {
11874
- return join20(accountDir, FILE);
11936
+ return join21(accountDir, FILE);
11875
11937
  }
11876
11938
  function readRaw(accountDir) {
11877
11939
  try {
@@ -11950,8 +12012,8 @@ function isNewSessionEffortLevel(value) {
11950
12012
  }
11951
12013
 
11952
12014
  // ../services/claude-session-manager/src/sidecar-store.ts
11953
- import { existsSync as existsSync13, mkdirSync as mkdirSync4, readdirSync as readdirSync15, readFileSync as readFileSync22, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
11954
- import { join as join21 } from "path";
12015
+ import { existsSync as existsSync14, mkdirSync as mkdirSync4, readdirSync as readdirSync16, readFileSync as readFileSync22, renameSync as renameSync3, unlinkSync as unlinkSync2, writeFileSync as writeFileSync7 } from "fs";
12016
+ import { join as join22 } from "path";
11955
12017
  function escapeRegExp(s) {
11956
12018
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
11957
12019
  }
@@ -11959,7 +12021,7 @@ function createSidecarStore(config) {
11959
12021
  const { suffix, validate: validate2 } = config;
11960
12022
  const suffixRe = new RegExp(`${escapeRegExp(suffix)}$`);
11961
12023
  function pathFor(sessionsDir, id) {
11962
- return join21(sessionsDir, `${id}${suffix}`);
12024
+ return join22(sessionsDir, `${id}${suffix}`);
11963
12025
  }
11964
12026
  function write(sessionsDir, id, record) {
11965
12027
  mkdirSync4(sessionsDir, { recursive: true });
@@ -11971,7 +12033,7 @@ function createSidecarStore(config) {
11971
12033
  return { ok: true };
11972
12034
  } catch (error) {
11973
12035
  try {
11974
- if (existsSync13(tmp)) unlinkSync2(tmp);
12036
+ if (existsSync14(tmp)) unlinkSync2(tmp);
11975
12037
  } catch {
11976
12038
  }
11977
12039
  return { ok: false, error };
@@ -11996,14 +12058,14 @@ function createSidecarStore(config) {
11996
12058
  function readAll(sessionsDir, onSkip) {
11997
12059
  let names;
11998
12060
  try {
11999
- names = readdirSync15(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
12061
+ names = readdirSync16(sessionsDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name);
12000
12062
  } catch {
12001
12063
  return [];
12002
12064
  }
12003
12065
  const out = [];
12004
12066
  for (const name of names) {
12005
12067
  if (!suffixRe.test(name)) continue;
12006
- const path3 = join21(sessionsDir, name);
12068
+ const path3 = join22(sessionsDir, name);
12007
12069
  let raw;
12008
12070
  try {
12009
12071
  raw = readFileSync22(path3, "utf8");
@@ -12027,7 +12089,7 @@ function createSidecarStore(config) {
12027
12089
  function clear(sessionsDir, id) {
12028
12090
  const path3 = pathFor(sessionsDir, id);
12029
12091
  try {
12030
- if (existsSync13(path3)) {
12092
+ if (existsSync14(path3)) {
12031
12093
  unlinkSync2(path3);
12032
12094
  return { ok: true, removed: true };
12033
12095
  }
@@ -12080,22 +12142,22 @@ var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9
12080
12142
  function locateSession(sessionId) {
12081
12143
  const dir = findSessionProjectDir(sessionId);
12082
12144
  if (!dir) return { projectDir: null, channel: null, accountId: null };
12083
- const meta = readSidecarMeta(join22(dir, `${sessionId}.meta.json`));
12145
+ const meta = readSidecarMeta(join23(dir, `${sessionId}.meta.json`));
12084
12146
  return { projectDir: dir, channel: meta.channel, accountId: meta.accountId };
12085
12147
  }
12086
12148
  function locateSidecar(sessionId) {
12087
12149
  const cfg = claudeConfigDir();
12088
12150
  if (!cfg) return null;
12089
- const projectsRoot = join22(cfg, "projects");
12151
+ const projectsRoot = join23(cfg, "projects");
12090
12152
  let slugs;
12091
12153
  try {
12092
- slugs = readdirSync16(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12154
+ slugs = readdirSync17(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
12093
12155
  } catch {
12094
12156
  return null;
12095
12157
  }
12096
12158
  for (const slug of slugs) {
12097
- const metaPath = join22(projectsRoot, slug, `${sessionId}.meta.json`);
12098
- if (existsSync14(metaPath)) {
12159
+ const metaPath = join23(projectsRoot, slug, `${sessionId}.meta.json`);
12160
+ if (existsSync15(metaPath)) {
12099
12161
  const meta = readSidecarMeta(metaPath);
12100
12162
  return { channel: meta.channel, adminUserId: meta.adminUserId, accountId: meta.accountId };
12101
12163
  }
@@ -12107,7 +12169,7 @@ function readTargetOwner(sessionId) {
12107
12169
  if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
12108
12170
  const { projectDir } = locateSession(sessionId);
12109
12171
  if (projectDir !== null) {
12110
- return { found: true, owner: readSidecarMeta(join22(projectDir, `${sessionId}.meta.json`)).adminUserId };
12172
+ return { found: true, owner: readSidecarMeta(join23(projectDir, `${sessionId}.meta.json`)).adminUserId };
12111
12173
  }
12112
12174
  return { found: false, owner: null };
12113
12175
  }
@@ -12121,7 +12183,7 @@ function sessionSidecarExists(sessionId) {
12121
12183
  function jsonlSizeBytes(projectDir, sessionId) {
12122
12184
  if (projectDir === null) return null;
12123
12185
  try {
12124
- return statSync8(join22(projectDir, `${sessionId}.jsonl`)).size;
12186
+ return statSync9(join23(projectDir, `${sessionId}.jsonl`)).size;
12125
12187
  } catch {
12126
12188
  return null;
12127
12189
  }
@@ -12257,15 +12319,15 @@ function latestAdminWebchatSessionId(requesterUserId, primaryUserId, scopeAccoun
12257
12319
  const cfg = claudeConfigDir();
12258
12320
  if (!cfg) return null;
12259
12321
  let best = null;
12260
- for (const { path: path3, isSubagent, archived } of enumerateJsonls(join22(cfg, "projects"))) {
12322
+ for (const { path: path3, isSubagent, archived } of enumerateJsonls(join23(cfg, "projects"))) {
12261
12323
  if (isSubagent || archived) continue;
12262
12324
  const id = basename6(path3).slice(0, -".jsonl".length);
12263
- const meta = readSidecarMeta(join22(dirname7(path3), `${id}.meta.json`));
12325
+ const meta = readSidecarMeta(join23(dirname7(path3), `${id}.meta.json`));
12264
12326
  if (meta.role !== "admin" || meta.channel !== "webchat") continue;
12265
12327
  if (multiAccount && meta.accountId !== scopeAccountId) continue;
12266
12328
  let mtimeMs;
12267
12329
  try {
12268
- mtimeMs = statSync8(path3).mtimeMs;
12330
+ mtimeMs = statSync9(path3).mtimeMs;
12269
12331
  } catch {
12270
12332
  continue;
12271
12333
  }
@@ -12582,7 +12644,7 @@ ${note}` : note;
12582
12644
  console.error(`[webchat:settings] op=${op} outcome=refused value=${value} reason=account-unresolved`);
12583
12645
  return c.json({ error: "account unresolved" }, 503);
12584
12646
  }
12585
- const accountJsonPath = join22(account.accountDir, "account.json");
12647
+ const accountJsonPath = join23(account.accountDir, "account.json");
12586
12648
  try {
12587
12649
  const parsed = JSON.parse(readFileSync23(accountJsonPath, "utf8"));
12588
12650
  if (op === "model") parsed.adminModel = value;
@@ -12630,7 +12692,7 @@ ${note}` : note;
12630
12692
  const cfg2 = claudeConfigDir();
12631
12693
  if (cfg2) {
12632
12694
  const source2 = resolveBridgeSource(
12633
- join22(cfg2, "sessions"),
12695
+ join23(cfg2, "sessions"),
12634
12696
  target,
12635
12697
  (id) => locateSession(id).projectDir !== null
12636
12698
  );
@@ -12662,7 +12724,7 @@ ${note}` : note;
12662
12724
  const cfg = claudeConfigDir();
12663
12725
  let projectDir = null;
12664
12726
  if (cfg) {
12665
- for (const { path: path3 } of enumerateJsonls(join22(cfg, "projects"))) {
12727
+ for (const { path: path3 } of enumerateJsonls(join23(cfg, "projects"))) {
12666
12728
  if (basename6(path3) === `${sessionId}.jsonl`) {
12667
12729
  projectDir = dirname7(path3);
12668
12730
  break;
@@ -12670,7 +12732,7 @@ ${note}` : note;
12670
12732
  }
12671
12733
  }
12672
12734
  if (source === "latest" && requesterUserId !== null) {
12673
- const owner = readSidecarMeta(join22(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
12735
+ const owner = readSidecarMeta(join23(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
12674
12736
  if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
12675
12737
  console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
12676
12738
  }
@@ -12702,8 +12764,8 @@ ${note}` : note;
12702
12764
  import { resolve as resolve15 } from "path";
12703
12765
 
12704
12766
  // app/lib/claude-agent/specialist-roster.ts
12705
- import { existsSync as existsSync15, readFileSync as readFileSync24, readdirSync as readdirSync17 } from "fs";
12706
- import { join as join23 } from "path";
12767
+ import { existsSync as existsSync16, readFileSync as readFileSync24, readdirSync as readdirSync18 } from "fs";
12768
+ import { join as join24 } from "path";
12707
12769
  function field(fm, name) {
12708
12770
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
12709
12771
  if (!m) return null;
@@ -12714,15 +12776,15 @@ function field(fm, name) {
12714
12776
  return value || null;
12715
12777
  }
12716
12778
  function readSpecialistRoster(specialistsDir) {
12717
- if (!existsSync15(specialistsDir)) return { specialists: [], skipped: [] };
12718
- const entries = readdirSync17(specialistsDir);
12779
+ if (!existsSync16(specialistsDir)) return { specialists: [], skipped: [] };
12780
+ const entries = readdirSync18(specialistsDir);
12719
12781
  const specialists = [];
12720
12782
  const skipped = [];
12721
12783
  for (const file of entries.sort()) {
12722
12784
  if (!file.endsWith(".md")) continue;
12723
12785
  let raw;
12724
12786
  try {
12725
- raw = readFileSync24(join23(specialistsDir, file), "utf-8");
12787
+ raw = readFileSync24(join24(specialistsDir, file), "utf-8");
12726
12788
  } catch (err) {
12727
12789
  skipped.push({ file, reason: err instanceof Error ? err.message : String(err) });
12728
12790
  continue;
@@ -12839,8 +12901,8 @@ var webchat_greeting_default = app7;
12839
12901
 
12840
12902
  // server/routes/telegram.ts
12841
12903
  import { homedir as homedir2 } from "os";
12842
- import { resolve as resolve16, join as join24 } from "path";
12843
- import { existsSync as existsSync16, readFileSync as readFileSync25 } from "fs";
12904
+ import { resolve as resolve16, join as join25 } from "path";
12905
+ import { existsSync as existsSync17, readFileSync as readFileSync25 } from "fs";
12844
12906
 
12845
12907
  // app/lib/telegram/gateway/instance.ts
12846
12908
  var instance = null;
@@ -12899,8 +12961,8 @@ function routeTelegramUpdate(input) {
12899
12961
  var TAG27 = "[telegram-inbound]";
12900
12962
  function configDirName() {
12901
12963
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT ?? resolve16(process.cwd(), "..");
12902
- const brandPath = join24(platformRoot5, "config", "brand.json");
12903
- if (existsSync16(brandPath)) {
12964
+ const brandPath = join25(platformRoot5, "config", "brand.json");
12965
+ if (existsSync17(brandPath)) {
12904
12966
  try {
12905
12967
  return JSON.parse(readFileSync25(brandPath, "utf-8")).configDir ?? ".maxy";
12906
12968
  } catch {
@@ -12921,7 +12983,7 @@ app8.post("/", async (c) => {
12921
12983
  return c.json({ ok: false }, 400);
12922
12984
  }
12923
12985
  const sp = secretPath(botType);
12924
- if (!existsSync16(sp)) {
12986
+ if (!existsSync17(sp)) {
12925
12987
  console.error(`${TAG27} op=reject reason=no-secret-file botType=${botType}`);
12926
12988
  return c.json({ ok: false }, 401);
12927
12989
  }
@@ -12988,21 +13050,21 @@ app8.post("/", async (c) => {
12988
13050
  var telegram_default = app8;
12989
13051
 
12990
13052
  // server/routes/quickbooks.ts
12991
- import { join as join25 } from "path";
12992
- import { existsSync as existsSync17, readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5, rmSync, renameSync as renameSync5 } from "fs";
13053
+ import { join as join26 } from "path";
13054
+ import { existsSync as existsSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5, rmSync, renameSync as renameSync5 } from "fs";
12993
13055
  var TAG28 = "[quickbooks]";
12994
13056
  var INTUIT_TOKEN_URL = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
12995
13057
  var STATE_RE = /^[A-Za-z0-9_-]+$/;
12996
13058
  function pendingPath(accountDir, state) {
12997
- return join25(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
13059
+ return join26(accountDir, "secrets", "quickbooks-pending", `${state}.json`);
12998
13060
  }
12999
13061
  function storePath(accountDir) {
13000
- return join25(accountDir, "secrets", "quickbooks.json");
13062
+ return join26(accountDir, "secrets", "quickbooks.json");
13001
13063
  }
13002
13064
  async function completeConsent(args) {
13003
13065
  const { accountDir, code, realmId } = args;
13004
13066
  const state = args.state;
13005
- if (!state || !STATE_RE.test(state) || !existsSync17(pendingPath(accountDir, state))) {
13067
+ if (!state || !STATE_RE.test(state) || !existsSync18(pendingPath(accountDir, state))) {
13006
13068
  console.error(`${TAG28} op=callback state=${state ?? ""} stateValid=false realmId=${realmId ?? ""}`);
13007
13069
  return { ok: false, status: 400, message: "Invalid or unknown authorization state.", stateValid: false };
13008
13070
  }
@@ -13029,7 +13091,7 @@ async function completeConsent(args) {
13029
13091
  if (!code || !realmId) {
13030
13092
  return { ok: false, status: 400, message: "Missing code or realmId in the callback.", stateValid: true };
13031
13093
  }
13032
- if (!existsSync17(storePath(accountDir))) {
13094
+ if (!existsSync18(storePath(accountDir))) {
13033
13095
  return { ok: false, status: 500, message: "No QuickBooks credentials are stored for this account.", stateValid: true };
13034
13096
  }
13035
13097
  const store2 = JSON.parse(readFileSync26(storePath(accountDir), "utf-8"));
@@ -13064,7 +13126,7 @@ async function completeConsent(args) {
13064
13126
  refreshTokenExpiry: now + (body.x_refresh_token_expires_in ?? 864e4) * 1e3,
13065
13127
  lastRefresh: now
13066
13128
  };
13067
- mkdirSync5(join25(accountDir, "secrets"), { recursive: true });
13129
+ mkdirSync5(join26(accountDir, "secrets"), { recursive: true });
13068
13130
  writeFileSync9(storePath(accountDir), JSON.stringify(store2, null, 2), { mode: 384 });
13069
13131
  const persisted = JSON.parse(readFileSync26(storePath(accountDir), "utf-8")).connections?.[realmId]?.refreshToken === body.refresh_token;
13070
13132
  console.error(`${TAG28} op=token-exchange realmId=${realmId} persisted=${persisted}`);
@@ -13097,7 +13159,7 @@ var quickbooks_default = app9;
13097
13159
 
13098
13160
  // server/routes/onboarding.ts
13099
13161
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync3 } from "child_process";
13100
- 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";
13162
+ 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";
13101
13163
  import { createHash as createHash4, randomUUID as randomUUID8 } from "crypto";
13102
13164
 
13103
13165
  // app/lib/claude-spawn-env.ts
@@ -13106,7 +13168,7 @@ function claudeBin() {
13106
13168
  }
13107
13169
 
13108
13170
  // server/routes/onboarding.ts
13109
- import { dirname as dirname9, join as join27 } from "path";
13171
+ import { dirname as dirname9, join as join28 } from "path";
13110
13172
 
13111
13173
  // app/lib/claude-keychain.ts
13112
13174
  import { execFileSync as execFileSync2 } from "child_process";
@@ -13235,8 +13297,8 @@ function readHostCredsBlob(service) {
13235
13297
  }
13236
13298
 
13237
13299
  // ../lib/admins-write/src/index.ts
13238
- 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";
13239
- import { dirname as dirname8, join as join26 } from "path";
13300
+ 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";
13301
+ import { dirname as dirname8, join as join27 } from "path";
13240
13302
  function id8(value) {
13241
13303
  return value.slice(0, 8);
13242
13304
  }
@@ -13277,7 +13339,7 @@ function writeAdminEntry(input) {
13277
13339
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
13278
13340
  try {
13279
13341
  let users = [];
13280
- if (existsSync18(input.usersFile)) {
13342
+ if (existsSync19(input.usersFile)) {
13281
13343
  const raw = readFileSync27(input.usersFile, "utf-8").trim();
13282
13344
  if (raw) {
13283
13345
  const parsed = JSON.parse(raw);
@@ -13309,8 +13371,8 @@ function writeAdminEntry(input) {
13309
13371
  return result;
13310
13372
  }
13311
13373
  try {
13312
- const accountJsonPath = join26(input.accountDir, "account.json");
13313
- if (!existsSync18(accountJsonPath)) {
13374
+ const accountJsonPath = join27(input.accountDir, "account.json");
13375
+ if (!existsSync19(accountJsonPath)) {
13314
13376
  throw new Error(`account.json not found at ${accountJsonPath}`);
13315
13377
  }
13316
13378
  const config = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
@@ -13333,7 +13395,7 @@ function writeAdminEntry(input) {
13333
13395
  function computeAdminStoreDivergence(input) {
13334
13396
  const result = { divergences: 0, accountWithoutUsers: [], usersWithoutAccount: [], errors: [] };
13335
13397
  const usersUserIds = /* @__PURE__ */ new Set();
13336
- if (existsSync18(input.usersFile)) {
13398
+ if (existsSync19(input.usersFile)) {
13337
13399
  try {
13338
13400
  const raw = readFileSync27(input.usersFile, "utf-8").trim();
13339
13401
  if (raw) {
@@ -13347,24 +13409,24 @@ function computeAdminStoreDivergence(input) {
13347
13409
  }
13348
13410
  }
13349
13411
  const accountUserIds = /* @__PURE__ */ new Set();
13350
- if (existsSync18(input.accountsDir)) {
13412
+ if (existsSync19(input.accountsDir)) {
13351
13413
  let entries;
13352
13414
  try {
13353
- entries = readdirSync18(input.accountsDir);
13415
+ entries = readdirSync19(input.accountsDir);
13354
13416
  } catch (err) {
13355
13417
  result.errors.push({ source: input.accountsDir, detail: err instanceof Error ? err.message : String(err) });
13356
13418
  return result;
13357
13419
  }
13358
13420
  for (const entry of entries) {
13359
13421
  if (entry.startsWith(".")) continue;
13360
- const accountDir = join26(input.accountsDir, entry);
13422
+ const accountDir = join27(input.accountsDir, entry);
13361
13423
  try {
13362
- if (!statSync9(accountDir).isDirectory()) continue;
13424
+ if (!statSync10(accountDir).isDirectory()) continue;
13363
13425
  } catch {
13364
13426
  continue;
13365
13427
  }
13366
- const accountJsonPath = join26(accountDir, "account.json");
13367
- if (!existsSync18(accountJsonPath)) continue;
13428
+ const accountJsonPath = join27(accountDir, "account.json");
13429
+ if (!existsSync19(accountJsonPath)) continue;
13368
13430
  let admins = [];
13369
13431
  try {
13370
13432
  const config = JSON.parse(readFileSync27(accountJsonPath, "utf-8"));
@@ -13415,7 +13477,7 @@ function hashPin2(pin) {
13415
13477
  return createHash4("sha256").update(pin).digest("hex");
13416
13478
  }
13417
13479
  function readUsersFile2() {
13418
- if (!existsSync19(USERS_FILE)) return null;
13480
+ if (!existsSync20(USERS_FILE)) return null;
13419
13481
  const raw = readFileSync28(USERS_FILE, "utf-8").trim();
13420
13482
  if (!raw) return [];
13421
13483
  return JSON.parse(raw);
@@ -13475,7 +13537,7 @@ app10.post("/claude-auth", async (c) => {
13475
13537
  } catch (err) {
13476
13538
  logoutError = err instanceof Error ? err.message : String(err);
13477
13539
  }
13478
- const credentialsPresent = existsSync19(CLAUDE_CREDENTIALS_FILE);
13540
+ const credentialsPresent = existsSync20(CLAUDE_CREDENTIALS_FILE);
13479
13541
  const ranMs = Date.now() - start;
13480
13542
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
13481
13543
  return c.json({ logged_out: !credentialsPresent });
@@ -13541,7 +13603,7 @@ app10.post("/claude-auth", async (c) => {
13541
13603
  });
13542
13604
  persistKeychainService(
13543
13605
  writebackResult,
13544
- (service) => writeFileSync11(join27(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13606
+ (service) => writeFileSync11(join28(dirname9(CLAUDE_CREDENTIALS_FILE), ".keychain-service"), service, { mode: 384 }),
13545
13607
  (line) => console.log(line)
13546
13608
  );
13547
13609
  if (darwinAuthChild === claudeProc2) darwinAuthChild = null;
@@ -13624,7 +13686,7 @@ app10.post("/set-pin", async (c) => {
13624
13686
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
13625
13687
  if (process.platform === "linux") {
13626
13688
  let installOwner = null;
13627
- if (existsSync19(INSTALL_OWNER_FILE)) {
13689
+ if (existsSync20(INSTALL_OWNER_FILE)) {
13628
13690
  try {
13629
13691
  const raw = readFileSync28(INSTALL_OWNER_FILE, "utf-8").trim();
13630
13692
  if (raw.length > 0) installOwner = raw;
@@ -13772,7 +13834,7 @@ app10.put("/set-pin", requireAdminSession, async (c) => {
13772
13834
  console.log(`[set-pin] changed PIN in place: userId=${sessionUserId.slice(0, 8)}\u2026`);
13773
13835
  if (process.platform === "linux") {
13774
13836
  let installOwner = null;
13775
- if (existsSync19(INSTALL_OWNER_FILE)) {
13837
+ if (existsSync20(INSTALL_OWNER_FILE)) {
13776
13838
  try {
13777
13839
  const raw = readFileSync28(INSTALL_OWNER_FILE, "utf-8").trim();
13778
13840
  if (raw.length > 0) installOwner = raw;
@@ -13806,9 +13868,9 @@ ${body.newPin}
13806
13868
  var onboarding_default = app10;
13807
13869
 
13808
13870
  // server/routes/client-error.ts
13809
- import { appendFileSync as appendFileSync4, existsSync as existsSync20, renameSync as renameSync8, statSync as statSync10 } from "fs";
13810
- import { join as join28 } from "path";
13811
- var CLIENT_ERRORS_LOG = join28(LOG_DIR, "client-errors.log");
13871
+ import { appendFileSync as appendFileSync4, existsSync as existsSync21, renameSync as renameSync8, statSync as statSync11 } from "fs";
13872
+ import { join as join29 } from "path";
13873
+ var CLIENT_ERRORS_LOG = join29(LOG_DIR, "client-errors.log");
13812
13874
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
13813
13875
  var MAX_BODY_SIZE = 8 * 1024;
13814
13876
  var MAX_STACK_LEN = 2e3;
@@ -13856,8 +13918,8 @@ function stackHead(stack) {
13856
13918
  }
13857
13919
  function rotateIfNeeded() {
13858
13920
  try {
13859
- if (!existsSync20(CLIENT_ERRORS_LOG)) return;
13860
- const stats = statSync10(CLIENT_ERRORS_LOG);
13921
+ if (!existsSync21(CLIENT_ERRORS_LOG)) return;
13922
+ const stats = statSync11(CLIENT_ERRORS_LOG);
13861
13923
  if (stats.size < MAX_LOG_SIZE) return;
13862
13924
  renameSync8(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
13863
13925
  } catch (err) {
@@ -14183,18 +14245,18 @@ app13.get("/", requireAdminSession, async (c) => {
14183
14245
  var accounts_default = app13;
14184
14246
 
14185
14247
  // server/routes/admin/logs.ts
14186
- import { existsSync as existsSync22, readdirSync as readdirSync19, readFileSync as readFileSync29, statSync as statSync11 } from "fs";
14248
+ import { existsSync as existsSync23, readdirSync as readdirSync20, readFileSync as readFileSync29, statSync as statSync12 } from "fs";
14187
14249
  import { resolve as resolve17, basename as basename7 } from "path";
14188
14250
 
14189
14251
  // app/lib/logs-read-resolve.ts
14190
- import { existsSync as existsSync21 } from "fs";
14191
- import { join as join29 } from "path";
14252
+ import { existsSync as existsSync22 } from "fs";
14253
+ import { join as join30 } from "path";
14192
14254
  function resolveSessionLogPaths(filename, logDirs) {
14193
14255
  const tried = [filename];
14194
14256
  const hits = [];
14195
14257
  for (const dir of logDirs) {
14196
- const fullPath = join29(dir, filename);
14197
- if (existsSync21(fullPath)) {
14258
+ const fullPath = join30(dir, filename);
14259
+ if (existsSync22(fullPath)) {
14198
14260
  hits.push({ path: fullPath, dir });
14199
14261
  }
14200
14262
  }
@@ -14223,7 +14285,7 @@ app14.get("/", async (c) => {
14223
14285
  searched.push(filePath);
14224
14286
  try {
14225
14287
  const buffer = readFileSync29(filePath);
14226
- const onDiskBytes = statSync11(filePath).size;
14288
+ const onDiskBytes = statSync12(filePath).size;
14227
14289
  const headers = {
14228
14290
  "Content-Type": "text/plain; charset=utf-8",
14229
14291
  "Content-Length": String(buffer.byteLength)
@@ -14288,7 +14350,7 @@ app14.get("/", async (c) => {
14288
14350
  try {
14289
14351
  const filename = basename7(hit.path);
14290
14352
  const buffer = readFileSync29(hit.path);
14291
- const onDiskBytes = statSync11(hit.path).size;
14353
+ const onDiskBytes = statSync12(hit.path).size;
14292
14354
  const headers = {
14293
14355
  "Content-Type": "text/plain; charset=utf-8",
14294
14356
  "Content-Length": String(buffer.byteLength)
@@ -14322,16 +14384,16 @@ app14.get("/", async (c) => {
14322
14384
  const seen = /* @__PURE__ */ new Set();
14323
14385
  const logs = {};
14324
14386
  for (const dir of logDirs) {
14325
- if (!existsSync22(dir)) continue;
14387
+ if (!existsSync23(dir)) continue;
14326
14388
  let files;
14327
14389
  try {
14328
- files = readdirSync19(dir).filter((f) => f.endsWith(".log"));
14390
+ files = readdirSync20(dir).filter((f) => f.endsWith(".log"));
14329
14391
  } catch (err) {
14330
14392
  const reason = err instanceof Error ? err.message : String(err);
14331
14393
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
14332
14394
  continue;
14333
14395
  }
14334
- 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 }) => {
14396
+ 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 }) => {
14335
14397
  seen.add(name);
14336
14398
  try {
14337
14399
  const content = readFileSync29(resolve17(dir, name));
@@ -14374,7 +14436,7 @@ var claude_info_default = app15;
14374
14436
 
14375
14437
  // server/routes/admin/attachment.ts
14376
14438
  import { readFile as readFile2, readdir } from "fs/promises";
14377
- import { existsSync as existsSync23 } from "fs";
14439
+ import { existsSync as existsSync24 } from "fs";
14378
14440
  import { resolve as resolve18 } from "path";
14379
14441
  var app16 = new Hono();
14380
14442
  var ATTACHMENT_ID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
@@ -14397,12 +14459,12 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14397
14459
  }
14398
14460
  let accountId = pinnedAccountId;
14399
14461
  let dir = uploadsDirFor2(accountId, attachmentId);
14400
- let found = existsSync23(dir);
14462
+ let found = existsSync24(dir);
14401
14463
  if (!found) {
14402
14464
  for (const candidate of listValidAccounts()) {
14403
14465
  if (candidate.accountId === pinnedAccountId) continue;
14404
14466
  const candidateDir = uploadsDirFor2(candidate.accountId, attachmentId);
14405
- if (existsSync23(candidateDir)) {
14467
+ if (existsSync24(candidateDir)) {
14406
14468
  accountId = candidate.accountId;
14407
14469
  dir = candidateDir;
14408
14470
  found = true;
@@ -14417,7 +14479,7 @@ app16.get("/:attachmentId", requireAdminSession, async (c) => {
14417
14479
  return new Response("Not found", { status: 404 });
14418
14480
  }
14419
14481
  const metaPath = resolve18(dir, `${attachmentId}.meta.json`);
14420
- if (!existsSync23(metaPath)) {
14482
+ if (!existsSync24(metaPath)) {
14421
14483
  return new Response("Not found", { status: 404 });
14422
14484
  }
14423
14485
  let meta;
@@ -14451,21 +14513,21 @@ var attachment_default = app16;
14451
14513
 
14452
14514
  // server/routes/admin/agents.ts
14453
14515
  import { resolve as resolve19 } from "path";
14454
- import { readdirSync as readdirSync20, readFileSync as readFileSync30, existsSync as existsSync24, rmSync as rmSync2 } from "fs";
14516
+ import { readdirSync as readdirSync21, readFileSync as readFileSync30, existsSync as existsSync25, rmSync as rmSync2 } from "fs";
14455
14517
  var app17 = new Hono();
14456
14518
  app17.get("/", (c) => {
14457
14519
  const account = resolveAccount();
14458
14520
  if (!account) return c.json({ agents: [] });
14459
14521
  const agentsDir = resolve19(account.accountDir, "agents");
14460
- if (!existsSync24(agentsDir)) return c.json({ agents: [] });
14522
+ if (!existsSync25(agentsDir)) return c.json({ agents: [] });
14461
14523
  const agents = [];
14462
14524
  try {
14463
- const entries = readdirSync20(agentsDir, { withFileTypes: true });
14525
+ const entries = readdirSync21(agentsDir, { withFileTypes: true });
14464
14526
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
14465
14527
  if (!entry.isDirectory()) continue;
14466
14528
  if (entry.name === "admin") continue;
14467
14529
  const configPath2 = resolve19(agentsDir, entry.name, "config.json");
14468
- if (!existsSync24(configPath2)) continue;
14530
+ if (!existsSync25(configPath2)) continue;
14469
14531
  try {
14470
14532
  const config = JSON.parse(readFileSync30(configPath2, "utf-8"));
14471
14533
  agents.push({
@@ -14494,7 +14556,7 @@ app17.delete("/:slug", async (c) => {
14494
14556
  return c.json({ error: "Invalid agent slug" }, 400);
14495
14557
  }
14496
14558
  const agentDir = resolve19(account.accountDir, "agents", slug);
14497
- if (!existsSync24(agentDir)) {
14559
+ if (!existsSync25(agentDir)) {
14498
14560
  return c.json({ error: "Agent not found" }, 404);
14499
14561
  }
14500
14562
  try {
@@ -14524,7 +14586,7 @@ app17.post("/:slug/project", async (c) => {
14524
14586
  return c.json({ error: "Invalid agent slug" }, 400);
14525
14587
  }
14526
14588
  const agentDir = resolve19(account.accountDir, "agents", slug);
14527
- if (!existsSync24(agentDir)) {
14589
+ if (!existsSync25(agentDir)) {
14528
14590
  return c.json({ error: "Agent not found on disk" }, 404);
14529
14591
  }
14530
14592
  try {
@@ -14540,7 +14602,7 @@ var agents_default = app17;
14540
14602
  // server/routes/admin/sessions.ts
14541
14603
  import crypto2 from "crypto";
14542
14604
  import { resolve as resolvePath } from "path";
14543
- import { existsSync as existsSync25, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14605
+ import { existsSync as existsSync26, mkdirSync as mkdirSync7, createWriteStream } from "fs";
14544
14606
 
14545
14607
  // ../lib/admin-conversation-purge/src/index.ts
14546
14608
  async function purgeAdminConversationJsonls(args) {
@@ -14700,7 +14762,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
14700
14762
  let reason = null;
14701
14763
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
14702
14764
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
14703
- else if (!existsSync25(a.storagePath)) reason = "missing-file";
14765
+ else if (!existsSync26(a.storagePath)) reason = "missing-file";
14704
14766
  if (reason) {
14705
14767
  invalid++;
14706
14768
  try {
@@ -15226,8 +15288,8 @@ app18.put("/:id/label", requireAdminSession, async (c) => {
15226
15288
  var sessions_default = app18;
15227
15289
 
15228
15290
  // app/lib/claude-agent/spawn-context.ts
15229
- import { existsSync as existsSync26, readFileSync as readFileSync31, readdirSync as readdirSync21, statSync as statSync12 } from "fs";
15230
- import { dirname as dirname10, resolve as resolve20, join as join30 } from "path";
15291
+ import { existsSync as existsSync27, readFileSync as readFileSync31, readdirSync as readdirSync22, statSync as statSync13 } from "fs";
15292
+ import { dirname as dirname10, resolve as resolve20, join as join31 } from "path";
15231
15293
  async function resolveOwnerProfileBlock(accountId, userId) {
15232
15294
  if (!userId) return { ok: false, reason: "missing-user-id" };
15233
15295
  try {
@@ -15268,12 +15330,12 @@ function frontmatterField(manifest, field2) {
15268
15330
  function extractPluginToolDescriptions(pluginDir) {
15269
15331
  const out = /* @__PURE__ */ new Map();
15270
15332
  const candidates = [
15271
- join30(pluginDir, "mcp/dist/index.js"),
15272
- join30(pluginDir, "mcp/src/index.ts")
15333
+ join31(pluginDir, "mcp/dist/index.js"),
15334
+ join31(pluginDir, "mcp/src/index.ts")
15273
15335
  ];
15274
15336
  let raw = null;
15275
15337
  for (const path3 of candidates) {
15276
- if (!existsSync26(path3)) continue;
15338
+ if (!existsSync27(path3)) continue;
15277
15339
  try {
15278
15340
  raw = readFileSync31(path3, "utf-8");
15279
15341
  break;
@@ -15325,25 +15387,25 @@ function parseSkillPathsFromFrontmatter(fm) {
15325
15387
  function listPluginDirs() {
15326
15388
  const out = /* @__PURE__ */ new Map();
15327
15389
  const platformPlugins = resolve20(PLATFORM_ROOT, "plugins");
15328
- if (existsSync26(platformPlugins)) {
15329
- for (const name of readdirSync21(platformPlugins)) {
15330
- const dir = join30(platformPlugins, name);
15390
+ if (existsSync27(platformPlugins)) {
15391
+ for (const name of readdirSync22(platformPlugins)) {
15392
+ const dir = join31(platformPlugins, name);
15331
15393
  try {
15332
- if (statSync12(dir).isDirectory()) out.set(name, dir);
15394
+ if (statSync13(dir).isDirectory()) out.set(name, dir);
15333
15395
  } catch {
15334
15396
  }
15335
15397
  }
15336
15398
  }
15337
15399
  const premiumRoot = resolve20(dirname10(PLATFORM_ROOT), "premium-plugins");
15338
- if (existsSync26(premiumRoot)) {
15339
- for (const bundle of readdirSync21(premiumRoot)) {
15340
- const bundlePlugins = join30(premiumRoot, bundle, "plugins");
15341
- if (!existsSync26(bundlePlugins)) continue;
15400
+ if (existsSync27(premiumRoot)) {
15401
+ for (const bundle of readdirSync22(premiumRoot)) {
15402
+ const bundlePlugins = join31(premiumRoot, bundle, "plugins");
15403
+ if (!existsSync27(bundlePlugins)) continue;
15342
15404
  try {
15343
- for (const name of readdirSync21(bundlePlugins)) {
15344
- const dir = join30(bundlePlugins, name);
15405
+ for (const name of readdirSync22(bundlePlugins)) {
15406
+ const dir = join31(bundlePlugins, name);
15345
15407
  try {
15346
- if (statSync12(dir).isDirectory()) out.set(name, dir);
15408
+ if (statSync13(dir).isDirectory()) out.set(name, dir);
15347
15409
  } catch {
15348
15410
  }
15349
15411
  }
@@ -15355,7 +15417,7 @@ function listPluginDirs() {
15355
15417
  }
15356
15418
  function readEnabledPlugins(accountId) {
15357
15419
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15358
- if (!existsSync26(accountFile)) return /* @__PURE__ */ new Set();
15420
+ if (!existsSync27(accountFile)) return /* @__PURE__ */ new Set();
15359
15421
  try {
15360
15422
  const parsed = JSON.parse(readFileSync31(accountFile, "utf-8"));
15361
15423
  return new Set(
@@ -15366,7 +15428,7 @@ function readEnabledPlugins(accountId) {
15366
15428
  }
15367
15429
  }
15368
15430
  function readFrontmatter(path3) {
15369
- if (!existsSync26(path3)) return null;
15431
+ if (!existsSync27(path3)) return null;
15370
15432
  let raw;
15371
15433
  try {
15372
15434
  raw = readFileSync31(path3, "utf-8");
@@ -15384,7 +15446,7 @@ function computeActivePlugins(accountId) {
15384
15446
  for (const name of Array.from(enabled).sort()) {
15385
15447
  const dir = pluginDirs.get(name);
15386
15448
  if (!dir) continue;
15387
- const fm = readFrontmatter(join30(dir, "PLUGIN.md"));
15449
+ const fm = readFrontmatter(join31(dir, "PLUGIN.md"));
15388
15450
  if (!fm) continue;
15389
15451
  const description = frontmatterField(`---
15390
15452
  ${fm}
@@ -15401,7 +15463,7 @@ ${fm}
15401
15463
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
15402
15464
  );
15403
15465
  if (toolNames.length > 0 && descMap.size === 0) {
15404
- const hasSource = existsSync26(join30(dir, "mcp/dist/index.js")) || existsSync26(join30(dir, "mcp/src/index.ts"));
15466
+ const hasSource = existsSync27(join31(dir, "mcp/dist/index.js")) || existsSync27(join31(dir, "mcp/src/index.ts"));
15405
15467
  if (hasSource) {
15406
15468
  console.warn(
15407
15469
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -15411,7 +15473,7 @@ ${fm}
15411
15473
  const skillPaths = parseSkillPathsFromFrontmatter(fm);
15412
15474
  const skills = [];
15413
15475
  for (const relPath of skillPaths) {
15414
- const skillPath = join30(dir, relPath);
15476
+ const skillPath = join31(dir, relPath);
15415
15477
  const skillFm = readFrontmatter(skillPath);
15416
15478
  if (!skillFm) continue;
15417
15479
  const skillName = frontmatterField(`---
@@ -15428,10 +15490,10 @@ ${skillFm}
15428
15490
  }
15429
15491
  function computeSpecialistDomains(accountId) {
15430
15492
  const specialistsDir = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
15431
- if (!existsSync26(specialistsDir)) return [];
15493
+ if (!existsSync27(specialistsDir)) return [];
15432
15494
  let entries;
15433
15495
  try {
15434
- entries = readdirSync21(specialistsDir);
15496
+ entries = readdirSync22(specialistsDir);
15435
15497
  } catch {
15436
15498
  return [];
15437
15499
  }
@@ -15455,7 +15517,7 @@ function computeSpecialistDomains(accountId) {
15455
15517
  const out = [];
15456
15518
  for (const file of entries.sort()) {
15457
15519
  if (!file.endsWith(".md")) continue;
15458
- const fm = readFrontmatter(join30(specialistsDir, file));
15520
+ const fm = readFrontmatter(join31(specialistsDir, file));
15459
15521
  if (!fm) continue;
15460
15522
  const wrapped = `---
15461
15523
  ${fm}
@@ -15474,7 +15536,7 @@ ${fm}
15474
15536
  }
15475
15537
  function computeDormantPlugins(accountId) {
15476
15538
  const accountFile = resolve20(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
15477
- if (!existsSync26(accountFile)) return [];
15539
+ if (!existsSync27(accountFile)) return [];
15478
15540
  let enabled;
15479
15541
  try {
15480
15542
  const raw = readFileSync31(accountFile, "utf-8");
@@ -15489,10 +15551,10 @@ function computeDormantPlugins(accountId) {
15489
15551
  return [];
15490
15552
  }
15491
15553
  const pluginsDir = resolve20(PLATFORM_ROOT, "plugins");
15492
- if (!existsSync26(pluginsDir)) return [];
15554
+ if (!existsSync27(pluginsDir)) return [];
15493
15555
  let entries;
15494
15556
  try {
15495
- entries = readdirSync21(pluginsDir);
15557
+ entries = readdirSync22(pluginsDir);
15496
15558
  } catch {
15497
15559
  return [];
15498
15560
  }
@@ -15500,7 +15562,7 @@ function computeDormantPlugins(accountId) {
15500
15562
  for (const name of entries) {
15501
15563
  if (enabled.has(name)) continue;
15502
15564
  const manifestPath = resolve20(pluginsDir, name, "PLUGIN.md");
15503
- if (!existsSync26(manifestPath)) continue;
15565
+ if (!existsSync27(manifestPath)) continue;
15504
15566
  let manifest;
15505
15567
  try {
15506
15568
  manifest = readFileSync31(manifestPath, "utf-8");
@@ -15517,11 +15579,11 @@ function computeDormantPlugins(accountId) {
15517
15579
  }
15518
15580
 
15519
15581
  // server/routes/admin/claude-sessions.ts
15520
- import { existsSync as existsSync27, readFileSync as readFileSync32 } from "fs";
15582
+ import { existsSync as existsSync28, readFileSync as readFileSync32 } from "fs";
15521
15583
  import { resolve as resolve21 } from "path";
15522
15584
  function readTunnelState(brandConfigDir) {
15523
15585
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
15524
- if (!existsSync27(statePath)) return null;
15586
+ if (!existsSync28(statePath)) return null;
15525
15587
  try {
15526
15588
  const parsed = JSON.parse(readFileSync32(statePath, "utf-8"));
15527
15589
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
@@ -15779,11 +15841,11 @@ app21.post("/", async (c) => {
15779
15841
  var events_default = app21;
15780
15842
 
15781
15843
  // server/routes/admin/files.ts
15782
- import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync28 } from "fs";
15844
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync29 } from "fs";
15783
15845
  import { readdir as readdir3, readFile as readFile4, stat as stat4, mkdir as mkdir3, unlink as unlink2, rename, rmdir } from "fs/promises";
15784
15846
  import { realpathSync as realpathSync6 } from "fs";
15785
15847
  import { randomUUID as randomUUID10 } from "crypto";
15786
- import { basename as basename9, dirname as dirname11, join as join32, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15848
+ import { basename as basename9, dirname as dirname11, join as join33, relative as relative4, resolve as resolve23, sep as sep6 } from "path";
15787
15849
  import { Readable as Readable2 } from "stream";
15788
15850
 
15789
15851
  // ../lib/graph-trash/src/index.ts
@@ -16020,7 +16082,7 @@ async function restoreNode(params) {
16020
16082
  }
16021
16083
 
16022
16084
  // app/lib/file-delete-cascade.ts
16023
- var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16085
+ var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16024
16086
  function parseAttachmentPath(relPath) {
16025
16087
  const segments = relPath.split("/").filter(Boolean);
16026
16088
  if (segments.length !== 5) return null;
@@ -16028,7 +16090,7 @@ function parseAttachmentPath(relPath) {
16028
16090
  const accountId = segments[1];
16029
16091
  const attachmentId = segments[3];
16030
16092
  const filename = segments[4];
16031
- if (!UUID_RE2.test(accountId) || !UUID_RE2.test(attachmentId)) return null;
16093
+ if (!UUID_RE3.test(accountId) || !UUID_RE3.test(attachmentId)) return null;
16032
16094
  const dot = filename.lastIndexOf(".");
16033
16095
  if (dot === -1) return null;
16034
16096
  const stem = filename.slice(0, dot);
@@ -16101,7 +16163,7 @@ async function cascadeDeleteDocument(params) {
16101
16163
 
16102
16164
  // app/lib/file-index.ts
16103
16165
  import * as fsp from "fs/promises";
16104
- import { resolve as resolve22, relative as relative3, join as join31, basename as basename8, extname as extname2, sep as sep5 } from "path";
16166
+ import { resolve as resolve22, relative as relative3, join as join32, basename as basename8, extname as extname2, sep as sep5 } from "path";
16105
16167
  import { tmpdir as tmpdir2 } from "os";
16106
16168
  import { execFile as execFile2 } from "child_process";
16107
16169
  import { promisify as promisify2 } from "util";
@@ -16183,7 +16245,7 @@ async function extractPdf(absolute) {
16183
16245
  return stdout.trim();
16184
16246
  }
16185
16247
  async function ocrPdf(absolute) {
16186
- const outPdf = join31(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
16248
+ const outPdf = join32(tmpdir2(), `file-index-ocr-${process.pid}-${Date.now()}.pdf`);
16187
16249
  try {
16188
16250
  await execFileAsync2(
16189
16251
  "ocrmypdf",
@@ -16245,7 +16307,7 @@ async function readDisplayName(absolute) {
16245
16307
  const stem = dot === -1 ? base : base.slice(0, dot);
16246
16308
  if (base === `${stem}.meta.json`) return null;
16247
16309
  try {
16248
- const raw = await fsp.readFile(join31(dir, `${stem}.meta.json`), "utf-8");
16310
+ const raw = await fsp.readFile(join32(dir, `${stem}.meta.json`), "utf-8");
16249
16311
  const meta = JSON.parse(raw);
16250
16312
  const dn = meta.displayName ?? meta.filename;
16251
16313
  return typeof dn === "string" && dn.length > 0 ? dn : null;
@@ -16266,7 +16328,7 @@ async function walkSubtree(root, dataRoot, out) {
16266
16328
  for (const entry of entries) {
16267
16329
  if (entry.isSymbolicLink()) continue;
16268
16330
  if (entry.isDirectory() && entry.name === ".uploads-tmp") continue;
16269
- const abs = join31(root, entry.name);
16331
+ const abs = join32(root, entry.name);
16270
16332
  if (entry.isDirectory()) {
16271
16333
  const sub = await walkSubtree(abs, dataRoot, out);
16272
16334
  if (!sub.clean) clean = false;
@@ -16619,10 +16681,10 @@ function buildZip(entries) {
16619
16681
 
16620
16682
  // server/routes/admin/files.ts
16621
16683
  var UPLOAD_TMP_DIR = ".uploads-tmp";
16622
- var UUID_RE3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16684
+ var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16623
16685
  async function readMeta(absDir, baseName) {
16624
16686
  try {
16625
- const raw = await readFile4(join32(absDir, `${baseName}.meta.json`), "utf8");
16687
+ const raw = await readFile4(join33(absDir, `${baseName}.meta.json`), "utf8");
16626
16688
  const parsed = JSON.parse(raw);
16627
16689
  if (typeof parsed?.filename === "string") {
16628
16690
  return { filename: parsed.filename, mimeType: typeof parsed.mimeType === "string" ? parsed.mimeType : void 0 };
@@ -16641,7 +16703,7 @@ async function readAccountNames() {
16641
16703
  return map;
16642
16704
  }
16643
16705
  for (const name of names) {
16644
- if (!UUID_RE3.test(name)) continue;
16706
+ if (!UUID_RE4.test(name)) continue;
16645
16707
  const configPath2 = resolve23(accountsDir, name, "account.json");
16646
16708
  try {
16647
16709
  const raw = await readFile4(configPath2, "utf8");
@@ -16676,8 +16738,8 @@ async function servableFilesIn(dirAbs, uuid) {
16676
16738
  return out;
16677
16739
  }
16678
16740
  async function enrich(absolute, entry, accountNames) {
16679
- if (entry.kind === "directory" && UUID_RE3.test(entry.name)) {
16680
- const dirAbs = join32(absolute, entry.name);
16741
+ if (entry.kind === "directory" && UUID_RE4.test(entry.name)) {
16742
+ const dirAbs = join33(absolute, entry.name);
16681
16743
  const meta = await readMeta(dirAbs, entry.name);
16682
16744
  if (meta?.filename) {
16683
16745
  const servable = await servableFilesIn(dirAbs, entry.name);
@@ -16686,7 +16748,7 @@ async function enrich(absolute, entry, accountNames) {
16686
16748
  let size = null;
16687
16749
  let modifiedAt = entry.modifiedAt;
16688
16750
  try {
16689
- const st = await stat4(join32(dirAbs, innerName));
16751
+ const st = await stat4(join33(dirAbs, innerName));
16690
16752
  size = st.size;
16691
16753
  modifiedAt = st.mtime.toISOString();
16692
16754
  } catch {
@@ -16711,7 +16773,7 @@ async function enrich(absolute, entry, accountNames) {
16711
16773
  if (entry.kind === "file") {
16712
16774
  const dot = entry.name.lastIndexOf(".");
16713
16775
  const base = dot === -1 ? entry.name : entry.name.slice(0, dot);
16714
- if (UUID_RE3.test(base)) {
16776
+ if (UUID_RE4.test(base)) {
16715
16777
  const meta = await readMeta(absolute, base);
16716
16778
  if (meta?.filename) {
16717
16779
  entry.displayName = meta.filename;
@@ -16724,7 +16786,7 @@ async function enrich(absolute, entry, accountNames) {
16724
16786
  function buildDisplayPath(relPath, accountNames) {
16725
16787
  if (relPath === "." || relPath === "") return [];
16726
16788
  return relPath.split("/").filter(Boolean).map((seg) => {
16727
- const dn = UUID_RE3.test(seg) ? accountNames.get(seg) : void 0;
16789
+ const dn = UUID_RE4.test(seg) ? accountNames.get(seg) : void 0;
16728
16790
  return dn ? { name: seg, displayName: dn } : { name: seg };
16729
16791
  });
16730
16792
  }
@@ -16774,11 +16836,11 @@ function isProtectedFromRename(relPath) {
16774
16836
  if (segments.length === 3 && segments[0] === "accounts" && segments[2] === "uploads") {
16775
16837
  return true;
16776
16838
  }
16777
- if (segments.length === 4 && segments[0] === "accounts" && segments[2] === "uploads" && UUID_RE3.test(segments[3])) {
16839
+ if (segments.length === 4 && segments[0] === "accounts" && segments[2] === "uploads" && UUID_RE4.test(segments[3])) {
16778
16840
  return true;
16779
16841
  }
16780
16842
  if (parseAttachmentPath(relPath) !== null) return true;
16781
- if (UUID_RE3.test(base.replace(/\.meta\.json$/, "")) && base.endsWith(".meta.json")) {
16843
+ if (UUID_RE4.test(base.replace(/\.meta\.json$/, "")) && base.endsWith(".meta.json")) {
16782
16844
  return true;
16783
16845
  }
16784
16846
  return false;
@@ -16852,16 +16914,16 @@ app22.get("/", requireAdminSession, async (c) => {
16852
16914
  const isAccountParent = segs.length === 1 && segs[0] === "accounts";
16853
16915
  const entries = [];
16854
16916
  for (const name of names) {
16855
- if (UUID_RE3.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
16917
+ if (UUID_RE4.test(name.replace(/\.meta\.json$/, "")) && name.endsWith(".meta.json")) {
16856
16918
  continue;
16857
16919
  }
16858
- if (isAccountParent && UUID_RE3.test(name) && name !== accountId) {
16920
+ if (isAccountParent && UUID_RE4.test(name) && name !== accountId) {
16859
16921
  continue;
16860
16922
  }
16861
16923
  const childRel = relPath === "" || relPath === "." ? name : `${relPath}/${name}`;
16862
16924
  const protectedEntry = isProtectedFromDeletion(childRel).protected;
16863
16925
  try {
16864
- const entryPath = join32(absolute, name);
16926
+ const entryPath = join33(absolute, name);
16865
16927
  const s = await stat4(entryPath);
16866
16928
  entries.push({
16867
16929
  name,
@@ -16924,7 +16986,7 @@ app22.get("/download", requireAdminSession, async (c) => {
16924
16986
  console.error(`[data] op=scratchpad-no-session sessionId="${sessionId.slice(0, 8)}\u2026"`);
16925
16987
  return c.json({ error: "Not found" }, 404);
16926
16988
  }
16927
- const meta = readSidecarMeta(join32(projectDir, `${sessionId}.meta.json`));
16989
+ const meta = readSidecarMeta(join33(projectDir, `${sessionId}.meta.json`));
16928
16990
  if (!meta.accountId || meta.accountId !== accountId) {
16929
16991
  console.error(`[data] account-scope-blocked root="scratchpad" sessionId="${sessionId.slice(0, 8)}\u2026" account=${accountId.slice(0, 8)}\u2026`);
16930
16992
  return c.json({ error: "Not found" }, 404);
@@ -17019,7 +17081,7 @@ async function* walkRegularFiles(dirAbsolute) {
17019
17081
  const dirents = await readdir3(dirAbsolute, { withFileTypes: true });
17020
17082
  for (const d of dirents) {
17021
17083
  if (d.isSymbolicLink()) continue;
17022
- const child = join32(dirAbsolute, d.name);
17084
+ const child = join33(dirAbsolute, d.name);
17023
17085
  if (d.isDirectory()) {
17024
17086
  yield* walkRegularFiles(child);
17025
17087
  continue;
@@ -17129,7 +17191,7 @@ async function resolveUploadTarget(c, accountId, uid) {
17129
17191
  const base = resolveOwnAccountWrite(rawDir, accountId, "POST /api/admin/files/upload");
17130
17192
  if (!base.ok) return { ok: false, status: base.status, error: base.error };
17131
17193
  const relDir = relpath ? dirname11(relpath) : ".";
17132
- const destRel = relDir === "." ? base.relative : join32(base.relative, relDir);
17194
+ const destRel = relDir === "." ? base.relative : join33(base.relative, relDir);
17133
17195
  if (crossesForeignAccountPartition(destRel, accountId)) {
17134
17196
  console.error(`[data] account-scope-blocked endpoint="POST /api/admin/files/upload" path="${destRel}" account=${accountId.slice(0, 8)}\u2026`);
17135
17197
  return { ok: false, status: 404, error: "Not found" };
@@ -17203,7 +17265,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
17203
17265
  });
17204
17266
  await unlink2(tmpPath).catch(() => {
17205
17267
  });
17206
- const tempRemoved = !existsSync28(tmpPath);
17268
+ const tempRemoved = !existsSync29(tmpPath);
17207
17269
  console.error(`[data-upload] op=cleanup uid=${uid} tempRemoved=${tempRemoved}`);
17208
17270
  };
17209
17271
  const reader = body.getReader();
@@ -17277,7 +17339,7 @@ async function discardChunkUpload(uploadId, state) {
17277
17339
  });
17278
17340
  await unlink2(state.tmpPath).catch(() => {
17279
17341
  });
17280
- const tempRemoved = !existsSync28(state.tmpPath);
17342
+ const tempRemoved = !existsSync29(state.tmpPath);
17281
17343
  console.error(`[data-upload] op=cleanup uid=${uploadId} tempRemoved=${tempRemoved}`);
17282
17344
  }
17283
17345
  async function writeChunkBody(body, out, alreadyReceived, ceiling) {
@@ -17506,8 +17568,8 @@ app22.delete("/", requireAdminSession, async (c) => {
17506
17568
  const dot = base.lastIndexOf(".");
17507
17569
  const stem = dot === -1 ? base : base.slice(0, dot);
17508
17570
  const containerDir = dirname11(absolute);
17509
- const sidecarPath = UUID_RE3.test(stem) && base !== `${stem}.meta.json` ? join32(containerDir, `${stem}.meta.json`) : null;
17510
- const isAttachmentContainer = UUID_RE3.test(stem) && basename9(containerDir) === stem;
17571
+ const sidecarPath = UUID_RE4.test(stem) && base !== `${stem}.meta.json` ? join33(containerDir, `${stem}.meta.json`) : null;
17572
+ const isAttachmentContainer = UUID_RE4.test(stem) && basename9(containerDir) === stem;
17511
17573
  await unlink2(absolute);
17512
17574
  if (sidecarPath) {
17513
17575
  try {
@@ -17516,7 +17578,7 @@ app22.delete("/", requireAdminSession, async (c) => {
17516
17578
  }
17517
17579
  }
17518
17580
  if (isAttachmentContainer) {
17519
- await unlink2(join32(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17581
+ await unlink2(join33(containerDir, `${stem}${EXTRACTED_TEXT_SUFFIX}`)).catch(() => {
17520
17582
  });
17521
17583
  await rmdir(containerDir).catch(() => {
17522
17584
  });
@@ -18620,8 +18682,8 @@ function isHiddenByDefault(label) {
18620
18682
  }
18621
18683
 
18622
18684
  // server/lib/top-level-labels.ts
18623
- import { readdirSync as readdirSync22, readFileSync as readFileSync33 } from "fs";
18624
- import { join as join33, resolve as resolve24 } from "path";
18685
+ import { readdirSync as readdirSync23, readFileSync as readFileSync33 } from "fs";
18686
+ import { join as join34, resolve as resolve24 } from "path";
18625
18687
  var STATIC_TOP_LEVEL_LABELS = Object.freeze(
18626
18688
  /* @__PURE__ */ new Set([
18627
18689
  // Base-schema infra (schema-base.md has no top-level section).
@@ -18714,7 +18776,7 @@ function parseTopLevelLabels(content) {
18714
18776
  }
18715
18777
  function resolveReferencesDir() {
18716
18778
  if (process.env.MAXY_PLATFORM_ROOT) {
18717
- return join33(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18779
+ return join34(process.env.MAXY_PLATFORM_ROOT, "plugins", "memory", "references");
18718
18780
  }
18719
18781
  return resolve24(import.meta.dirname, "../../../plugins/memory/references");
18720
18782
  }
@@ -18722,9 +18784,9 @@ function parseTableTopLevelLabels(referencesDir) {
18722
18784
  const labels = /* @__PURE__ */ new Set();
18723
18785
  const contributingFiles = [];
18724
18786
  try {
18725
- const fileNames = readdirSync22(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18787
+ const fileNames = readdirSync23(referencesDir).filter((f) => f.startsWith("schema-") && f.endsWith(".md")).sort();
18726
18788
  for (const fileName of fileNames) {
18727
- const content = readFileSync33(join33(referencesDir, fileName), "utf-8");
18789
+ const content = readFileSync33(join34(referencesDir, fileName), "utf-8");
18728
18790
  const parsed = parseTopLevelLabels(content);
18729
18791
  if (parsed.length > 0) contributingFiles.push(fileName);
18730
18792
  for (const label of parsed) labels.add(label);
@@ -19878,7 +19940,7 @@ var graph_default_view_default = app28;
19878
19940
  // server/routes/admin/sidebar-artefacts.ts
19879
19941
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
19880
19942
  import { resolve as resolve25, relative as relative5, isAbsolute as isAbsolute2, sep as sep7, basename as basename10 } from "path";
19881
- import { existsSync as existsSync29 } from "fs";
19943
+ import { existsSync as existsSync30 } from "fs";
19882
19944
  var LIMIT = 50;
19883
19945
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
19884
19946
  function toDataRootRelPath(absPath) {
@@ -19985,7 +20047,7 @@ async function fetchAgentTemplateRows(accountDir) {
19985
20047
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
19986
20048
  const names = /* @__PURE__ */ new Set();
19987
20049
  for (const dir of [overrideDir, bundledDir]) {
19988
- if (!existsSync29(dir)) continue;
20050
+ if (!existsSync30(dir)) continue;
19989
20051
  try {
19990
20052
  const entries = await readdir4(dir);
19991
20053
  for (const entry of entries) {
@@ -20000,7 +20062,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
20000
20062
  }
20001
20063
  async function readAgentTemplateRow(inp) {
20002
20064
  let chosenPath = null;
20003
- if (existsSync29(inp.overridePath)) {
20065
+ if (existsSync30(inp.overridePath)) {
20004
20066
  try {
20005
20067
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
20006
20068
  chosenPath = inp.overridePath;
@@ -20011,7 +20073,7 @@ async function readAgentTemplateRow(inp) {
20011
20073
  );
20012
20074
  return null;
20013
20075
  }
20014
- } else if (existsSync29(inp.bundledPath)) {
20076
+ } else if (existsSync30(inp.bundledPath)) {
20015
20077
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
20016
20078
  console.error(
20017
20079
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -20613,12 +20675,12 @@ app37.get("/", async (c) => {
20613
20675
  var system_stats_default = app37;
20614
20676
 
20615
20677
  // server/routes/admin/health.ts
20616
- import { existsSync as existsSync30, readFileSync as readFileSync34 } from "fs";
20617
- import { resolve as resolve26, join as join34 } from "path";
20678
+ import { existsSync as existsSync31, readFileSync as readFileSync34 } from "fs";
20679
+ import { resolve as resolve26, join as join35 } from "path";
20618
20680
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
20619
20681
  var brandHostname = "maxy";
20620
- var brandJsonPath = join34(PLATFORM_ROOT6, "config", "brand.json");
20621
- if (existsSync30(brandJsonPath)) {
20682
+ var brandJsonPath = join35(PLATFORM_ROOT6, "config", "brand.json");
20683
+ if (existsSync31(brandJsonPath)) {
20622
20684
  try {
20623
20685
  const brand = JSON.parse(readFileSync34(brandJsonPath, "utf-8"));
20624
20686
  if (brand.hostname) brandHostname = brand.hostname;
@@ -20629,7 +20691,7 @@ var VERSION_FILE = resolve26(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
20629
20691
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
20630
20692
  var PROBE_TIMEOUT_MS = 1e3;
20631
20693
  function readVersion() {
20632
- if (!existsSync30(VERSION_FILE)) return "unknown";
20694
+ if (!existsSync31(VERSION_FILE)) return "unknown";
20633
20695
  return readFileSync34(VERSION_FILE, "utf-8").trim() || "unknown";
20634
20696
  }
20635
20697
  async function probeConversationDb() {
@@ -20894,7 +20956,7 @@ function buildInitialMessage(env) {
20894
20956
  "Conservative-extraction rules apply (see Task 234 spec):",
20895
20957
  "- One :KnowledgeDocument MERGE keyed on sourceUrl=" + env.pageUrl + " with the verbatim transcript as body, plus one :Section:Note child with the summary.",
20896
20958
  "- (:KD)-[:PARTICIPANT]->(:Person) for each participant. MERGE :Person on (name, profileUrl) where present.",
20897
- "- MERGE any derived entity only when assertively stated. Whatever ontology label fits: :Event {startDate, endDate} with ATTENDED_BY edges for scheduled meetings; :Task {kind, name, status} with RAISED_BY/ABOUT edges for actions without a scheduled time; :Service/:PriceSpecification when an offer or price is discussed. Each carries sourceUrl=" + env.pageUrl + ".",
20959
+ "- MERGE any derived entity only when assertively stated. Whatever ontology label fits: :Event {startDate, endDate} with ATTENDED_BY edges for scheduled meetings; :Task {taskId: randomUUID(), kind, name, status} with RAISED_BY/ABOUT edges for actions without a scheduled time; :Service/:PriceSpecification when an offer or price is discussed. Each carries sourceUrl=" + env.pageUrl + ".",
20898
20960
  "- (:KD)-[:MENTIONS]->(<derived entity>) for every derived entity. Person-attached insights stay in the :Section:Note body plus a (:KD)-[:MENTIONS]->(:Person) edge \u2014 no standalone insight node.",
20899
20961
  "- No :Communication, :ConversationArchive rows (chat transcripts route through the conversation-archive skill), or :Message nodes \u2014 those belong to other flows.",
20900
20962
  "",
@@ -21406,8 +21468,8 @@ app45.post("/launch", requireAdminSession, async (c) => {
21406
21468
  var browser_default = app45;
21407
21469
 
21408
21470
  // server/routes/admin/calendar.ts
21409
- import { existsSync as existsSync31 } from "fs";
21410
- import { join as join36 } from "path";
21471
+ import { existsSync as existsSync32 } from "fs";
21472
+ import { join as join37 } from "path";
21411
21473
 
21412
21474
  // server/lib/calendar-ics.ts
21413
21475
  var CRLF = "\r\n";
@@ -21507,7 +21569,7 @@ function countVEvents(ics) {
21507
21569
 
21508
21570
  // server/lib/calendar-availability.ts
21509
21571
  import { readFileSync as readFileSync35 } from "fs";
21510
- import { join as join35 } from "path";
21572
+ import { join as join36 } from "path";
21511
21573
  var AVAILABILITY_FILENAME = "calendar-availability.json";
21512
21574
  var REQUIRED_KEYS = [
21513
21575
  "timezone",
@@ -21516,7 +21578,7 @@ var REQUIRED_KEYS = [
21516
21578
  "weekly"
21517
21579
  ];
21518
21580
  function readAvailabilityConfig(accountDir) {
21519
- const path3 = join35(accountDir, AVAILABILITY_FILENAME);
21581
+ const path3 = join36(accountDir, AVAILABILITY_FILENAME);
21520
21582
  let raw;
21521
21583
  try {
21522
21584
  raw = readFileSync35(path3, "utf-8");
@@ -21878,7 +21940,7 @@ app46.get("/booking-link", requireAdminSession, (c) => {
21878
21940
  console.error('[calendar] op=booking-link-fail err="no account configured"');
21879
21941
  return c.json({ bookingDomain: null });
21880
21942
  }
21881
- if (!existsSync31(join36(account.accountDir, AVAILABILITY_FILENAME))) {
21943
+ if (!existsSync32(join37(account.accountDir, AVAILABILITY_FILENAME))) {
21882
21944
  console.log("[calendar] op=booking-link bookingDomain=none source=availability-config");
21883
21945
  return c.json({ bookingDomain: null });
21884
21946
  }
@@ -21933,7 +21995,7 @@ app47.get("/", requireAdminSession, async (c) => {
21933
21995
  WHERE te.endedAt IS NULL
21934
21996
  WITH t, te ORDER BY te.startedAt
21935
21997
  WITH t, head(collect(te)) AS openTe
21936
- RETURN t.taskId AS taskId, t.name AS name, t.clientName AS clientName,
21998
+ RETURN t.taskId AS taskId, elementId(t) AS rowKey, t.name AS name, t.clientName AS clientName,
21937
21999
  t.propertyAddress AS propertyAddress, t.fee AS fee, t.status AS status,
21938
22000
  coalesce(t.secondsLogged, 0) AS secondsLogged,
21939
22001
  openTe.startedAt AS runningStartedAt
@@ -21942,12 +22004,17 @@ app47.get("/", requireAdminSession, async (c) => {
21942
22004
  );
21943
22005
  const open = [];
21944
22006
  const completed = [];
22007
+ let missingTaskId = 0;
21945
22008
  for (const rec of result.records) {
21946
22009
  const status = rec.get("status") ?? "pending";
21947
22010
  const runningStartedAt = rec.get("runningStartedAt") ?? null;
21948
22011
  const fee = rec.get("fee");
22012
+ const rawTaskId = rec.get("taskId");
22013
+ const taskId = typeof rawTaskId === "string" && rawTaskId !== "" ? rawTaskId : null;
22014
+ if (taskId === null) missingTaskId++;
21949
22015
  const row = {
21950
- taskId: rec.get("taskId"),
22016
+ taskId,
22017
+ rowKey: rec.get("rowKey"),
21951
22018
  name: rec.get("name") ?? "",
21952
22019
  clientName: rec.get("clientName") ?? null,
21953
22020
  propertyAddress: rec.get("propertyAddress") ?? null,
@@ -21960,7 +22027,7 @@ app47.get("/", requireAdminSession, async (c) => {
21960
22027
  if (COMPLETED.has(status)) completed.push(row);
21961
22028
  else if (!HIDDEN_FROM_OPEN.has(status)) open.push(row);
21962
22029
  }
21963
- console.log(`${TAG37} op=list account=${accountId} open=${open.length} completed=${completed.length}`);
22030
+ console.log(`${TAG37} op=list account=${accountId} open=${open.length} completed=${completed.length} missingTaskId=${missingTaskId}`);
21964
22031
  return c.json({ open, completed });
21965
22032
  } catch (err) {
21966
22033
  console.error(`${TAG37} op=list error="${err instanceof Error ? err.message : String(err)}"`);
@@ -21986,7 +22053,11 @@ app48.post("/", requireAdminSession, async (c) => {
21986
22053
  return c.json({ error: "invalid-json" }, 400);
21987
22054
  }
21988
22055
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
21989
- if (!taskId) return c.json({ error: "taskId required" }, 400);
22056
+ if (!taskId) {
22057
+ const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
22058
+ console.error(`${TAG38} op=timer-start rejected reason=${reason} account=${accountId}`);
22059
+ return c.json({ error: "taskId required" }, 400);
22060
+ }
21990
22061
  const now = (/* @__PURE__ */ new Date()).toISOString();
21991
22062
  const session = getSession();
21992
22063
  try {
@@ -22043,7 +22114,11 @@ app49.post("/", requireAdminSession, async (c) => {
22043
22114
  return c.json({ error: "invalid-json" }, 400);
22044
22115
  }
22045
22116
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
22046
- if (!taskId) return c.json({ error: "taskId required" }, 400);
22117
+ if (!taskId) {
22118
+ const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
22119
+ console.error(`${TAG39} op=timer-stop rejected reason=${reason} account=${accountId}`);
22120
+ return c.json({ error: "taskId required" }, 400);
22121
+ }
22047
22122
  const now = (/* @__PURE__ */ new Date()).toISOString();
22048
22123
  const session = getSession();
22049
22124
  try {
@@ -22111,7 +22186,11 @@ app50.post("/", requireAdminSession, async (c) => {
22111
22186
  return c.json({ error: "invalid-json" }, 400);
22112
22187
  }
22113
22188
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
22114
- if (!taskId) return c.json({ error: "taskId required" }, 400);
22189
+ if (!taskId) {
22190
+ const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
22191
+ console.error(`${TAG40} op=complete rejected reason=${reason} account=${accountId}`);
22192
+ return c.json({ error: "taskId required" }, 400);
22193
+ }
22115
22194
  const now = (/* @__PURE__ */ new Date()).toISOString();
22116
22195
  const session = getSession();
22117
22196
  try {
@@ -22154,7 +22233,8 @@ app51.post("/", requireAdminSession, async (c) => {
22154
22233
  }
22155
22234
  const taskId = typeof body.taskId === "string" ? body.taskId : "";
22156
22235
  if (!taskId) {
22157
- console.error(`${TAG41} op=reject reason=no-task`);
22236
+ const reason = body.taskId === null ? "null-taskId" : "missing-taskId";
22237
+ console.error(`${TAG41} op=time-adjust rejected reason=${reason} account=${accountId}`);
22158
22238
  return c.json({ error: "taskId required" }, 400);
22159
22239
  }
22160
22240
  const newSeconds = body.newSeconds;
@@ -22217,7 +22297,7 @@ app51.post("/", requireAdminSession, async (c) => {
22217
22297
  var task_time_adjust_default = app51;
22218
22298
 
22219
22299
  // server/routes/admin/activity.ts
22220
- import { readdirSync as readdirSync23 } from "fs";
22300
+ import { readdirSync as readdirSync24 } from "fs";
22221
22301
  var app52 = new Hono();
22222
22302
  var TAG42 = "[activity]";
22223
22303
  function resolveHouseAccountId(accounts) {
@@ -22233,7 +22313,7 @@ function requestToken() {
22233
22313
  var short = (id) => id ? id.slice(0, 8) : "unset";
22234
22314
  function countAccountDirsOnDisk() {
22235
22315
  try {
22236
- return readdirSync23(ACCOUNTS_DIR, { withFileTypes: true }).filter(
22316
+ return readdirSync24(ACCOUNTS_DIR, { withFileTypes: true }).filter(
22237
22317
  (e) => e.isDirectory() && !e.name.startsWith(".")
22238
22318
  ).length;
22239
22319
  } catch {
@@ -22288,8 +22368,10 @@ app52.get("/", requireAdminSession, async (c) => {
22288
22368
  const untaggedCount = rows.filter((r) => r.accountId === null).length;
22289
22369
  const meteringFailed = rows.filter((r) => r.meteringError !== null).length;
22290
22370
  const censusAgeMs = census ? Date.now() - census.sampleAtMs : null;
22371
+ const ageNull = rows.filter((r) => r.ageMs === null).length;
22372
+ const sidecarNull = rows.filter((r) => r.sidecarMissing).length;
22291
22373
  console.log(
22292
- `${TAG42} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"}`
22374
+ `${TAG42} op=census req=${req} ageMs=${censusAgeMs ?? "none"} live=${census?.live ?? "none"} cpuNull=${census?.cpuNull ?? "none"} rows=${rows.length} ageNull=${ageNull} sidecarNull=${sidecarNull}`
22293
22375
  );
22294
22376
  console.log(
22295
22377
  `${TAG42} op=response req=${req} rows=${rows.length} accounts=${valid.length} untagged=${untaggedCount} meteringFailed=${meteringFailed} ms=${Date.now() - start}`
@@ -22597,7 +22679,7 @@ app56.route("/request-magic-link", request_magic_link_default);
22597
22679
  var access_default = app56;
22598
22680
 
22599
22681
  // server/routes/sites.ts
22600
- import { existsSync as existsSync32, readFileSync as readFileSync36, realpathSync as realpathSync7, statSync as statSync13 } from "fs";
22682
+ import { existsSync as existsSync33, readFileSync as readFileSync36, realpathSync as realpathSync7, statSync as statSync14 } from "fs";
22601
22683
  import { resolve as resolve28 } from "path";
22602
22684
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
22603
22685
  var MIME = {
@@ -22663,7 +22745,7 @@ app57.get("/:rel{.*}", (c) => {
22663
22745
  }
22664
22746
  let stat8;
22665
22747
  try {
22666
- stat8 = existsSync32(filePath) ? statSync13(filePath) : null;
22748
+ stat8 = existsSync33(filePath) ? statSync14(filePath) : null;
22667
22749
  } catch {
22668
22750
  stat8 = null;
22669
22751
  }
@@ -22682,7 +22764,7 @@ app57.get("/:rel{.*}", (c) => {
22682
22764
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
22683
22765
  return c.text("Forbidden", 403);
22684
22766
  }
22685
- if (!existsSync32(filePath)) {
22767
+ if (!existsSync33(filePath)) {
22686
22768
  console.error(`[sites] not-found path=${reqPath} status=404`);
22687
22769
  return c.text("Not found", 404);
22688
22770
  }
@@ -22813,8 +22895,8 @@ var VISITOR_COOKIE_NAME = "mxy_v";
22813
22895
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
22814
22896
 
22815
22897
  // app/lib/brand-config.ts
22816
- import { existsSync as existsSync33, readFileSync as readFileSync38 } from "fs";
22817
- import { join as join37 } from "path";
22898
+ import { existsSync as existsSync34, readFileSync as readFileSync38 } from "fs";
22899
+ import { join as join38 } from "path";
22818
22900
  var cached2 = null;
22819
22901
  var cachedAttempted = false;
22820
22902
  function readBrandConfig() {
@@ -22822,8 +22904,8 @@ function readBrandConfig() {
22822
22904
  cachedAttempted = true;
22823
22905
  const platformRoot5 = process.env.MAXY_PLATFORM_ROOT;
22824
22906
  if (!platformRoot5) return null;
22825
- const brandPath = join37(platformRoot5, "config", "brand.json");
22826
- if (!existsSync33(brandPath)) return null;
22907
+ const brandPath = join38(platformRoot5, "config", "brand.json");
22908
+ if (!existsSync34(brandPath)) return null;
22827
22909
  try {
22828
22910
  cached2 = JSON.parse(readFileSync38(brandPath, "utf-8"));
22829
22911
  return cached2;
@@ -23314,8 +23396,8 @@ var visitor_event_default = app60;
23314
23396
 
23315
23397
  // server/routes/session.ts
23316
23398
  import { resolve as resolve29 } from "path";
23317
- import { existsSync as existsSync34, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9 } from "fs";
23318
- var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23399
+ import { existsSync as existsSync35, writeFileSync as writeFileSync13, mkdirSync as mkdirSync9 } from "fs";
23400
+ var UUID_RE5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23319
23401
  function writeBrandingCache(accountId, agentSlug, branding) {
23320
23402
  try {
23321
23403
  const cacheDir = resolve29(MAXY_DIR, "branding-cache", accountId);
@@ -23330,7 +23412,7 @@ function parseVisitorCookie2(cookieHeader) {
23330
23412
  const match = cookieHeader.match(/(?:^|;\s*)maxy_visitor=([^;]*)/);
23331
23413
  if (!match) return null;
23332
23414
  const value = decodeURIComponent(match[1]).trim();
23333
- return UUID_RE4.test(value) ? value : null;
23415
+ return UUID_RE5.test(value) ? value : null;
23334
23416
  }
23335
23417
  function parseAccessSessionId2(cookieHeader) {
23336
23418
  if (!cookieHeader) return null;
@@ -23398,7 +23480,7 @@ app61.post("/", async (c) => {
23398
23480
  let agentConfig = null;
23399
23481
  if (account) {
23400
23482
  const agentDir = resolve29(account.accountDir, "agents", agentSlug);
23401
- if (!existsSync34(agentDir) || !existsSync34(resolve29(agentDir, "config.json"))) {
23483
+ if (!existsSync35(agentDir) || !existsSync35(resolve29(agentDir, "config.json"))) {
23402
23484
  return c.json({ error: "Agent not found" }, 404);
23403
23485
  }
23404
23486
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -23428,7 +23510,7 @@ app61.post("/", async (c) => {
23428
23510
  );
23429
23511
  }
23430
23512
  }
23431
- if (body.session_key && typeof body.session_key === "string" && UUID_RE4.test(body.session_key)) {
23513
+ if (body.session_key && typeof body.session_key === "string" && UUID_RE5.test(body.session_key)) {
23432
23514
  if (visitorId) {
23433
23515
  const recent = await findRecentConversation(visitorId, accountId, agentSlug).catch(() => null);
23434
23516
  if (recent) {
@@ -23730,8 +23812,8 @@ function startTimeEntryCensus(openSession, opts = {}) {
23730
23812
  }
23731
23813
 
23732
23814
  // app/lib/ledger-census.ts
23733
- import { readdirSync as readdirSync24, readFileSync as readFileSync39, statSync as statSync14 } from "fs";
23734
- import { join as join38 } from "path";
23815
+ import { readdirSync as readdirSync25, readFileSync as readFileSync39, statSync as statSync15 } from "fs";
23816
+ import { join as join39 } from "path";
23735
23817
 
23736
23818
  // ../lib/ledger-core/dist/reconcile.js
23737
23819
  var LEDGER_INDEX_NAMES = [
@@ -23779,15 +23861,15 @@ var DAY_MS = 864e5;
23779
23861
  function countWriteRejects24h(logDir, now) {
23780
23862
  let entries;
23781
23863
  try {
23782
- entries = readdirSync24(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
23864
+ entries = readdirSync25(logDir).filter((f) => f.startsWith("mcp-ledger-") && f.endsWith(".log"));
23783
23865
  } catch {
23784
23866
  return 0;
23785
23867
  }
23786
23868
  let total = 0;
23787
23869
  for (const name of entries) {
23788
- const path3 = join38(logDir, name);
23870
+ const path3 = join39(logDir, name);
23789
23871
  try {
23790
- if (now - statSync14(path3).mtimeMs > DAY_MS) continue;
23872
+ if (now - statSync15(path3).mtimeMs > DAY_MS) continue;
23791
23873
  for (const line of readFileSync39(path3, "utf8").split("\n")) {
23792
23874
  if (line.includes("[graph-write] reject")) total += 1;
23793
23875
  }
@@ -24275,8 +24357,8 @@ async function migrateUploads(opts = {}) {
24275
24357
 
24276
24358
  // app/lib/migrate-admin-webchat-sidecars.ts
24277
24359
  import { readdir as readdir6, readFile as readFile6, rename as rename3, writeFile as writeFile4, unlink as unlink3 } from "fs/promises";
24278
- import { existsSync as existsSync35 } from "fs";
24279
- import { join as join39 } from "path";
24360
+ import { existsSync as existsSync36 } from "fs";
24361
+ import { join as join40 } from "path";
24280
24362
  var ADMIN_ROLE2 = "admin";
24281
24363
  var WEBCHAT_CHANNEL2 = "webchat";
24282
24364
  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;
@@ -24305,7 +24387,7 @@ async function writeRaw(path3, obj) {
24305
24387
  await rename3(tmp, path3);
24306
24388
  } catch (err) {
24307
24389
  try {
24308
- if (existsSync35(tmp)) await unlink3(tmp);
24390
+ if (existsSync36(tmp)) await unlink3(tmp);
24309
24391
  } catch {
24310
24392
  }
24311
24393
  throw err;
@@ -24321,7 +24403,7 @@ async function collectLiveSidecars(projectsRoot) {
24321
24403
  }
24322
24404
  for (const slug of slugs) {
24323
24405
  if (!slug.isDirectory()) continue;
24324
- const slugDir = join39(projectsRoot, slug.name);
24406
+ const slugDir = join40(projectsRoot, slug.name);
24325
24407
  let entries;
24326
24408
  try {
24327
24409
  entries = await readdir6(slugDir, { withFileTypes: true });
@@ -24330,9 +24412,9 @@ async function collectLiveSidecars(projectsRoot) {
24330
24412
  }
24331
24413
  for (const entry of entries) {
24332
24414
  if (entry.isFile() && SESSION_META_RE.test(entry.name)) {
24333
- out.push(join39(slugDir, entry.name));
24415
+ out.push(join40(slugDir, entry.name));
24334
24416
  } else if (entry.isDirectory() && entry.name === "subagents") {
24335
- const subDir = join39(slugDir, entry.name);
24417
+ const subDir = join40(slugDir, entry.name);
24336
24418
  let subs;
24337
24419
  try {
24338
24420
  subs = await readdir6(subDir, { withFileTypes: true });
@@ -24340,7 +24422,7 @@ async function collectLiveSidecars(projectsRoot) {
24340
24422
  continue;
24341
24423
  }
24342
24424
  for (const s of subs) {
24343
- if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join39(subDir, s.name));
24425
+ if (s.isFile() && SESSION_META_RE.test(s.name)) out.push(join40(subDir, s.name));
24344
24426
  }
24345
24427
  }
24346
24428
  }
@@ -24352,7 +24434,7 @@ function shortId(path3) {
24352
24434
  return base.slice(0, 8);
24353
24435
  }
24354
24436
  async function migrateAdminWebchatSidecars(opts = {}) {
24355
- const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join39(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
24437
+ const projectsRoot = opts.projectsRoot ?? (process.env.CLAUDE_CONFIG_DIR ? join40(process.env.CLAUDE_CONFIG_DIR, "projects") : null) ?? "";
24356
24438
  const usersFile = opts.usersFile ?? USERS_FILE;
24357
24439
  const accountId = opts.accountId ?? resolveAccount()?.accountId ?? null;
24358
24440
  const resolveName = opts.resolveName ?? defaultResolveName;
@@ -26715,12 +26797,12 @@ function startTelegramNativeFileFollower(input) {
26715
26797
  }
26716
26798
 
26717
26799
  // server/telegram-descriptor.ts
26718
- import { resolve as resolve34, join as join40 } from "path";
26800
+ import { resolve as resolve34, join as join41 } from "path";
26719
26801
  function telegramGatewayUrl() {
26720
26802
  return `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`;
26721
26803
  }
26722
26804
  function telegramServerPath() {
26723
- return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join40(__dirname, ".."), "services/telegram-channel/dist/server.js");
26805
+ return process.env.MAXY_TELEGRAM_CHANNEL_SERVER_PATH ?? resolve34(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."), "services/telegram-channel/dist/server.js");
26724
26806
  }
26725
26807
 
26726
26808
  // app/lib/channel-pty-bridge/public-session-end-review.ts
@@ -27007,7 +27089,7 @@ function broadcastAdminShutdown(reason) {
27007
27089
 
27008
27090
  // ../lib/entitlement/src/index.ts
27009
27091
  import { createPublicKey, createHash as createHash6, verify as cryptoVerify } from "crypto";
27010
- import { existsSync as existsSync36, readFileSync as readFileSync40, statSync as statSync15 } from "fs";
27092
+ import { existsSync as existsSync37, readFileSync as readFileSync40, statSync as statSync16 } from "fs";
27011
27093
  import { resolve as resolve35 } from "path";
27012
27094
 
27013
27095
  // ../lib/entitlement/src/canonicalize.ts
@@ -27056,10 +27138,10 @@ function resolveEntitlement(brand, account) {
27056
27138
  return logResolved(implicitTrust(account), null);
27057
27139
  }
27058
27140
  const entitlementPath = resolve35(brand.configDir, "entitlement.json");
27059
- if (!existsSync36(entitlementPath)) {
27141
+ if (!existsSync37(entitlementPath)) {
27060
27142
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
27061
27143
  }
27062
- const stat8 = statSync15(entitlementPath);
27144
+ const stat8 = statSync16(entitlementPath);
27063
27145
  const key = memoKey(stat8.mtimeMs, account);
27064
27146
  if (memo && memo.key === key) {
27065
27147
  return memo.result;
@@ -27247,12 +27329,12 @@ function clientFrom(c) {
27247
27329
  }
27248
27330
  installMediaDownloadGuard();
27249
27331
  var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT || "";
27250
- var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join41(PLATFORM_ROOT8, "config", "brand.json") : "";
27332
+ var BRAND_JSON_PATH = PLATFORM_ROOT8 ? join42(PLATFORM_ROOT8, "config", "brand.json") : "";
27251
27333
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
27252
- if (BRAND_JSON_PATH && !existsSync37(BRAND_JSON_PATH)) {
27334
+ if (BRAND_JSON_PATH && !existsSync38(BRAND_JSON_PATH)) {
27253
27335
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
27254
27336
  }
27255
- if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
27337
+ if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
27256
27338
  try {
27257
27339
  const parsed = JSON.parse(readFileSync41(BRAND_JSON_PATH, "utf-8"));
27258
27340
  BRAND = { ...BRAND, ...parsed };
@@ -27286,10 +27368,10 @@ var brandLoginOpts = {
27286
27368
  appleTouchIconPath: brandAppIcon512Path,
27287
27369
  themeColor: BRAND.defaultColors?.primary
27288
27370
  };
27289
- var ALIAS_DOMAINS_PATH = join41(homedir4(), BRAND.configDir, "alias-domains.json");
27371
+ var ALIAS_DOMAINS_PATH = join42(homedir4(), BRAND.configDir, "alias-domains.json");
27290
27372
  function loadAliasDomains() {
27291
27373
  try {
27292
- if (!existsSync37(ALIAS_DOMAINS_PATH)) return null;
27374
+ if (!existsSync38(ALIAS_DOMAINS_PATH)) return null;
27293
27375
  const parsed = JSON.parse(readFileSync41(ALIAS_DOMAINS_PATH, "utf-8"));
27294
27376
  if (!Array.isArray(parsed)) {
27295
27377
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -27354,7 +27436,7 @@ async function recordPassiveDispatch(input) {
27354
27436
  var waGateway = new WaGateway({
27355
27437
  fetchStandingRules: fetchAccountStandingRules,
27356
27438
  gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
27357
- serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
27439
+ serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
27358
27440
  // Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
27359
27441
  // path-validation scope) is the sender's effective SESSION account, resolved
27360
27442
  // once at the inbound gate and threaded here via the gateway's per-sender doc
@@ -27369,7 +27451,7 @@ var waGateway = new WaGateway({
27369
27451
  caption,
27370
27452
  accountId,
27371
27453
  maxyAccountId,
27372
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, ".."))
27454
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, ".."))
27373
27455
  });
27374
27456
  return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
27375
27457
  },
@@ -27473,7 +27555,7 @@ function runDuplicateSenderAudit() {
27473
27555
  try {
27474
27556
  const configDir2 = process.env.CLAUDE_CONFIG_DIR;
27475
27557
  if (!configDir2) return;
27476
- const projectsRoot = join41(configDir2, "projects");
27558
+ const projectsRoot = join42(configDir2, "projects");
27477
27559
  const records = [];
27478
27560
  for (const { path: jsonlPath, isSubagent, archived } of enumerateJsonls(projectsRoot)) {
27479
27561
  if (isSubagent || archived) continue;
@@ -28025,7 +28107,7 @@ app63.get("/agent-assets/:slug/:filename", (c) => {
28025
28107
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
28026
28108
  return c.text("Forbidden", 403);
28027
28109
  }
28028
- if (!existsSync37(filePath)) {
28110
+ if (!existsSync38(filePath)) {
28029
28111
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
28030
28112
  return c.text("Not found", 404);
28031
28113
  }
@@ -28055,7 +28137,7 @@ app63.get("/generated/:filename", (c) => {
28055
28137
  console.error(`[generated] serve file=${filename} status=403`);
28056
28138
  return c.text("Forbidden", 403);
28057
28139
  }
28058
- if (!existsSync37(filePath)) {
28140
+ if (!existsSync38(filePath)) {
28059
28141
  console.error(`[generated] serve file=${filename} status=404`);
28060
28142
  return c.text("Not found", 404);
28061
28143
  }
@@ -28075,7 +28157,7 @@ app63.route("/v", visitor_consent_default);
28075
28157
  var htmlCache = /* @__PURE__ */ new Map();
28076
28158
  var brandLogoPath = "/brand/maxy-monochrome.png";
28077
28159
  var brandIconPath = "/brand/maxy-monochrome.png";
28078
- if (BRAND_JSON_PATH && existsSync37(BRAND_JSON_PATH)) {
28160
+ if (BRAND_JSON_PATH && existsSync38(BRAND_JSON_PATH)) {
28079
28161
  try {
28080
28162
  const fullBrand = JSON.parse(readFileSync41(BRAND_JSON_PATH, "utf-8"));
28081
28163
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -28104,7 +28186,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
28104
28186
  var brandThemeColor = BRAND.defaultColors?.primary ?? "#000000";
28105
28187
  var brandBackgroundColor = BRAND.defaultColors?.background ?? "#ffffff";
28106
28188
  var brandAppIconsExist = [brandAppIcon192Path, brandAppIcon512Path, brandMaskableIconPath].every(
28107
- (p) => existsSync37(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
28189
+ (p) => existsSync38(resolve36(process.cwd(), "public", p.replace(/^\//, "")))
28108
28190
  );
28109
28191
  var SW_SOURCE = (() => {
28110
28192
  try {
@@ -28116,8 +28198,8 @@ var SW_SOURCE = (() => {
28116
28198
  function readInstalledVersion() {
28117
28199
  try {
28118
28200
  if (!PLATFORM_ROOT8) return "unknown";
28119
- const versionFile = join41(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
28120
- if (!existsSync37(versionFile)) return "unknown";
28201
+ const versionFile = join42(PLATFORM_ROOT8, "config", `.${BRAND.hostname}-version`);
28202
+ if (!existsSync38(versionFile)) return "unknown";
28121
28203
  const content = readFileSync41(versionFile, "utf-8").trim();
28122
28204
  return content || "unknown";
28123
28205
  } catch {
@@ -28176,12 +28258,12 @@ ${clientErrorReporterScript}
28176
28258
  return html;
28177
28259
  }
28178
28260
  function loadBrandingCache(agentSlug) {
28179
- const configDir2 = join41(homedir4(), BRAND.configDir);
28261
+ const configDir2 = join42(homedir4(), BRAND.configDir);
28180
28262
  try {
28181
28263
  const accountId = getDefaultAccountId();
28182
28264
  if (!accountId) return null;
28183
- const cachePath = join41(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
28184
- if (!existsSync37(cachePath)) return null;
28265
+ const cachePath = join42(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
28266
+ if (!existsSync38(cachePath)) return null;
28185
28267
  return JSON.parse(readFileSync41(cachePath, "utf-8"));
28186
28268
  } catch {
28187
28269
  return null;
@@ -28414,11 +28496,11 @@ var hostname = process.env.HOSTNAME ?? "127.0.0.1";
28414
28496
  var httpServer = serve({ fetch: app63.fetch, port, hostname });
28415
28497
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28416
28498
  {
28417
- const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28499
+ const reconcilePlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28418
28500
  const reconcileScript = resolve36(reconcilePlatformRoot, "plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js");
28419
28501
  const RECONCILE_INTERVAL_MS = 12e4;
28420
28502
  const runReconcile = () => {
28421
- if (!existsSync37(reconcileScript)) return;
28503
+ if (!existsSync38(reconcileScript)) return;
28422
28504
  try {
28423
28505
  const child = spawn3(process.execPath, [reconcileScript], {
28424
28506
  env: { ...process.env, PLATFORM_ROOT: reconcilePlatformRoot },
@@ -28436,11 +28518,11 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28436
28518
  loop.unref();
28437
28519
  }
28438
28520
  {
28439
- const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28521
+ const outlookPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28440
28522
  const outlookScript = resolve36(outlookPlatformRoot, "plugins/outlook/mcp/dist/scripts/complete-registration.js");
28441
28523
  const OUTLOOK_COMPLETE_INTERVAL_MS = 3e4;
28442
28524
  const runOutlookComplete = () => {
28443
- if (!existsSync37(outlookScript)) return;
28525
+ if (!existsSync38(outlookScript)) return;
28444
28526
  try {
28445
28527
  const child = spawn3(process.execPath, [outlookScript], {
28446
28528
  env: { ...process.env, PLATFORM_ROOT: outlookPlatformRoot },
@@ -28458,20 +28540,20 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28458
28540
  outlookLoop.unref();
28459
28541
  }
28460
28542
  {
28461
- const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28543
+ const auditRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28462
28544
  const strandedAccountsDir = resolve36(auditRoot, "..", "data/accounts");
28463
28545
  const STRANDED_AUDIT_INTERVAL_MS = 3e5;
28464
28546
  const STRANDED_AGE_MS = 16 * 6e4;
28465
28547
  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;
28466
28548
  const runStrandedAudit = () => {
28467
28549
  try {
28468
- if (!existsSync37(strandedAccountsDir)) return;
28550
+ if (!existsSync38(strandedAccountsDir)) return;
28469
28551
  const now = Date.now();
28470
- for (const name of readdirSync25(strandedAccountsDir)) {
28552
+ for (const name of readdirSync26(strandedAccountsDir)) {
28471
28553
  if (!STRANDED_UUID_RE.test(name)) continue;
28472
28554
  const pendingPath2 = resolve36(strandedAccountsDir, name, "secrets/outlook/pending-devicecode.enc");
28473
- if (!existsSync37(pendingPath2)) continue;
28474
- const ageMs = now - statSync16(pendingPath2).mtimeMs;
28555
+ if (!existsSync38(pendingPath2)) continue;
28556
+ const ageMs = now - statSync17(pendingPath2).mtimeMs;
28475
28557
  if (ageMs > STRANDED_AGE_MS) {
28476
28558
  console.error(`[outlook-mcp] devicecode-stranded account=${name} ageSec=${Math.floor(ageMs / 1e3)}`);
28477
28559
  }
@@ -28486,7 +28568,45 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28486
28568
  strandedLoop.unref();
28487
28569
  }
28488
28570
  {
28489
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28571
+ const googleRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28572
+ const googleAccountsDir = resolve36(googleRoot, "..", "data/accounts");
28573
+ const GOOGLE_PENDING_AUDIT_INTERVAL_MS = 3e5;
28574
+ const runGooglePendingAuditSafe = () => {
28575
+ try {
28576
+ runGooglePendingAudit(googleAccountsDir, Date.now(), (line) => console.error(line));
28577
+ } catch (err) {
28578
+ console.error(`[google-oauth] op=pending-audit-error error="${err.message}"`);
28579
+ }
28580
+ };
28581
+ const googlePendingFirst = setTimeout(runGooglePendingAuditSafe, 27e3);
28582
+ googlePendingFirst.unref();
28583
+ const googlePendingLoop = setInterval(runGooglePendingAuditSafe, GOOGLE_PENDING_AUDIT_INTERVAL_MS);
28584
+ googlePendingLoop.unref();
28585
+ const googleAuditScript = resolve36(googleRoot, "plugins/google/mcp/dist/scripts/account-audit.js");
28586
+ const GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS = 36e5;
28587
+ const runGoogleAccountAudit = () => {
28588
+ if (!existsSync38(googleAuditScript)) return;
28589
+ try {
28590
+ const child = spawn3(process.execPath, [googleAuditScript], {
28591
+ env: { ...process.env, PLATFORM_ROOT: googleRoot },
28592
+ stdio: "inherit"
28593
+ });
28594
+ child.unref();
28595
+ child.on(
28596
+ "error",
28597
+ (err) => console.error(`[google-account-audit] op=spawn-failed error="${err.message}"`)
28598
+ );
28599
+ } catch (err) {
28600
+ console.error(`[google-account-audit] op=spawn-failed error="${err.message}"`);
28601
+ }
28602
+ };
28603
+ const googleAuditFirst = setTimeout(runGoogleAccountAudit, 45e3);
28604
+ googleAuditFirst.unref();
28605
+ const googleAuditLoop = setInterval(runGoogleAccountAudit, GOOGLE_ACCOUNT_AUDIT_INTERVAL_MS);
28606
+ googleAuditLoop.unref();
28607
+ }
28608
+ {
28609
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28490
28610
  const STORAGE_AUDIT_INTERVAL_MS = 3e5;
28491
28611
  const runStorageAuditSafe = () => {
28492
28612
  runStorageAudit(auditPlatformRoot).catch(
@@ -28508,7 +28628,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28508
28628
  pagesAuditLoop.unref();
28509
28629
  }
28510
28630
  {
28511
- const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28631
+ const publishPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28512
28632
  const publishScript = resolve36(publishPlatformRoot, "plugins/scheduling/mcp/dist/scripts/publish-availability.js");
28513
28633
  const PUBLISH_INTERVAL_MS = 3e5;
28514
28634
  const currentAccount = () => {
@@ -28520,7 +28640,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28520
28640
  }
28521
28641
  };
28522
28642
  const spawnPublish = (account) => {
28523
- if (!existsSync37(publishScript)) return;
28643
+ if (!existsSync38(publishScript)) return;
28524
28644
  try {
28525
28645
  const child = spawn3(process.execPath, [publishScript], {
28526
28646
  env: {
@@ -28541,7 +28661,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28541
28661
  const availPath = resolve36(account.accountDir, "calendar-availability.json");
28542
28662
  let hasBookingSite = false;
28543
28663
  try {
28544
- if (existsSync37(availPath)) {
28664
+ if (existsSync38(availPath)) {
28545
28665
  const cfg = JSON.parse(readFileSync41(availPath, "utf-8"));
28546
28666
  hasBookingSite = typeof cfg.bookingDbName === "string" && cfg.bookingDbName.length > 0;
28547
28667
  }
@@ -28550,7 +28670,7 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28550
28670
  if (!hasBookingSite) return;
28551
28671
  const statePath = resolve36(account.accountDir, "state", "booking-availability", "last-publish.json");
28552
28672
  let lastSuccessAt = null;
28553
- if (existsSync37(statePath)) {
28673
+ if (existsSync38(statePath)) {
28554
28674
  try {
28555
28675
  const rec = JSON.parse(readFileSync41(statePath, "utf-8"));
28556
28676
  lastSuccessAt = rec.lastSuccessAt ?? null;
@@ -28577,12 +28697,12 @@ console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
28577
28697
  startTimeEntryCensus(() => getSession());
28578
28698
  startLedgerCensus(() => getSession());
28579
28699
  {
28580
- const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..");
28700
+ const auditPlatformRoot = process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..");
28581
28701
  const auditScript = resolve36(auditPlatformRoot, "plugins/connector/mcp/dist/scripts/audit-connectors.js");
28582
28702
  const auditLogDir = process.env.LOG_DIR ?? LOG_DIR;
28583
28703
  const CONNECTOR_AUDIT_INTERVAL_MS = 3e5;
28584
28704
  const runConnectorAudit = () => {
28585
- if (!existsSync37(auditScript)) return;
28705
+ if (!existsSync38(auditScript)) return;
28586
28706
  try {
28587
28707
  const child = spawn3(process.execPath, [auditScript], {
28588
28708
  env: { ...process.env, PLATFORM_ROOT: auditPlatformRoot, LOG_DIR: auditLogDir },
@@ -28693,7 +28813,7 @@ try {
28693
28813
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28694
28814
  async function runAdminUserReconcileTick() {
28695
28815
  try {
28696
- if (!existsSync37(USERS_FILE)) {
28816
+ if (!existsSync38(USERS_FILE)) {
28697
28817
  console.error("[adminuser-self-heal] skip reason=no-users-file");
28698
28818
  return;
28699
28819
  }
@@ -28738,7 +28858,7 @@ var ingestAuditTimer = setInterval(runIngestAuditTick, INGEST_AUDIT_INTERVAL_MS)
28738
28858
  if (typeof ingestAuditTimer.unref === "function") ingestAuditTimer.unref();
28739
28859
  var USERS_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
28740
28860
  function countUsersRows() {
28741
- if (!existsSync37(USERS_FILE)) return 0;
28861
+ if (!existsSync38(USERS_FILE)) return 0;
28742
28862
  const raw = readFileSync41(USERS_FILE, "utf-8").trim();
28743
28863
  if (!raw) return 0;
28744
28864
  const users = JSON.parse(raw);
@@ -28859,7 +28979,7 @@ if (bootAccountConfig?.whatsapp) {
28859
28979
  }
28860
28980
  init({
28861
28981
  configDir: configDirForWhatsApp,
28862
- platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join41(__dirname, "..")),
28982
+ platformRoot: resolve36(process.env.MAXY_PLATFORM_ROOT ?? join42(__dirname, "..")),
28863
28983
  accountConfig: bootAccountConfig,
28864
28984
  onMessage: async (msg) => {
28865
28985
  if (msg.isOwnerMirror) {