@rubytech/create-maxy-code 0.1.299 → 0.1.300

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 (151) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/cloudflare/references/manual-setup.md +31 -16
  3. package/payload/platform/plugins/cloudflare/references/reset-guide.md +19 -1
  4. package/payload/platform/plugins/cloudflare/skills/cloudflare/SKILL.md +16 -3
  5. package/payload/platform/scripts/check-no-esm-require.mjs +4 -0
  6. package/payload/server/{chunk-7H4KMTMC.js → chunk-JHSF5VPE.js} +171 -95
  7. package/payload/server/maxy-edge.js +19 -1
  8. package/payload/server/public/assets/AdminShell-BFdBxg4P.js +1 -0
  9. package/payload/server/public/assets/{Checkbox-DHnspkuk.js → Checkbox-BZ1XbA1t.js} +1 -1
  10. package/payload/server/public/assets/{Transcript-9FlneAzM.js → Transcript-CaVix6W0.js} +1 -1
  11. package/payload/server/public/assets/admin-BK7xIr3o.js +1 -0
  12. package/payload/server/public/assets/{arc-CPOhuw1V.js → arc-DxSm8tli.js} +1 -1
  13. package/payload/server/public/assets/architecture-YZFGNWBL-6g9jRVgc.js +1 -0
  14. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BaR37f-j.js → architectureDiagram-Q4EWVU46-7JSAh0vL.js} +1 -1
  15. package/payload/server/public/assets/audio-attachment-mime-CFyc3gpD.js +30 -0
  16. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-Du7NMQfQ.js → blockDiagram-DXYQGD6D-DLoVmHKD.js} +1 -1
  17. package/payload/server/public/assets/{browser--bCCzvRh.js → browser-ClnGUKp-.js} +1 -1
  18. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-F3GnFLbs.js → c4Diagram-AHTNJAMY-Nv1G0o9P.js} +1 -1
  19. package/payload/server/public/assets/channel-BgQLJanG.js +1 -0
  20. package/payload/server/public/assets/chat-ZTAhSoJV.js +1 -0
  21. package/payload/server/public/assets/{chunk-2KRD3SAO-SUv9UlAA.js → chunk-2KRD3SAO-BpqPMhoA.js} +1 -1
  22. package/payload/server/public/assets/chunk-336JU56O-DgXHlVU_.js +2 -0
  23. package/payload/server/public/assets/chunk-426QAEUC-Dr_XVuUq.js +1 -0
  24. package/payload/server/public/assets/{chunk-4BX2VUAB-D5iKMyHO.js → chunk-4BX2VUAB-nwyZSZH8.js} +1 -1
  25. package/payload/server/public/assets/{chunk-4TB4RGXK-BahbQ7-Z.js → chunk-4TB4RGXK-Tfxz9LHX.js} +1 -1
  26. package/payload/server/public/assets/{chunk-55IACEB6-DfF9myIx.js → chunk-55IACEB6-6FMJQGXG.js} +1 -1
  27. package/payload/server/public/assets/{chunk-5FUZZQ4R-jF6a9UVe.js → chunk-5FUZZQ4R-g2FgZF3D.js} +1 -1
  28. package/payload/server/public/assets/{chunk-5PVQY5BW-BOCI-roy.js → chunk-5PVQY5BW-DtLwXsPH.js} +1 -1
  29. package/payload/server/public/assets/{chunk-67CJDMHE-E5wGK0dP.js → chunk-67CJDMHE-K91CP5ZU.js} +1 -1
  30. package/payload/server/public/assets/{chunk-7N4EOEYR-CtT0GsUT.js → chunk-7N4EOEYR-BGpCQhqK.js} +1 -1
  31. package/payload/server/public/assets/{chunk-AA7GKIK3-CGUj8eo-.js → chunk-AA7GKIK3-jkDbInck.js} +1 -1
  32. package/payload/server/public/assets/{chunk-BSJP7CBP-OPAIjvSk.js → chunk-BSJP7CBP-mDosdzGs.js} +1 -1
  33. package/payload/server/public/assets/{chunk-CIAEETIT-S_D8FhIT.js → chunk-CIAEETIT-DhBxewpQ.js} +1 -1
  34. package/payload/server/public/assets/{chunk-EDXVE4YY-CkD4AyZi.js → chunk-EDXVE4YY-B7c-9Emg.js} +1 -1
  35. package/payload/server/public/assets/{chunk-ENJZ2VHE-CmoK-c5f.js → chunk-ENJZ2VHE-Cqhhncox.js} +1 -1
  36. package/payload/server/public/assets/{chunk-FMBD7UC4-DcyogdNf.js → chunk-FMBD7UC4-BpDq6wj1.js} +1 -1
  37. package/payload/server/public/assets/{chunk-FOC6F5B3-8iNobZdv.js → chunk-FOC6F5B3-Ds02-ktu.js} +1 -1
  38. package/payload/server/public/assets/{chunk-ICPOFSXX-DeGZE9pw.js → chunk-ICPOFSXX-BTX5POFr.js} +2 -2
  39. package/payload/server/public/assets/{chunk-K5T4RW27-CkoKFdgU.js → chunk-K5T4RW27-Du1PXXBU.js} +1 -1
  40. package/payload/server/public/assets/{chunk-KGLVRYIC-DyNP1efP.js → chunk-KGLVRYIC-siasOAf8.js} +1 -1
  41. package/payload/server/public/assets/{chunk-LIHQZDEY-WZPpo5Dd.js → chunk-LIHQZDEY-xf1rbZtf.js} +1 -1
  42. package/payload/server/public/assets/{chunk-ORNJ4GCN-Cr7E0-Df.js → chunk-ORNJ4GCN-DeTLQ_LD.js} +1 -1
  43. package/payload/server/public/assets/{chunk-OYMX7WX6-BPjxo1Oc.js → chunk-OYMX7WX6-DQ7_oVJn.js} +1 -1
  44. package/payload/server/public/assets/chunk-QZHKN3VN-DF4o9HRJ.js +1 -0
  45. package/payload/server/public/assets/{chunk-U2HBQHQK-CuDS7yVX.js → chunk-U2HBQHQK-CXmFUKgn.js} +1 -1
  46. package/payload/server/public/assets/{chunk-X2U36JSP-DEkde3xe.js → chunk-X2U36JSP-Bj8-8Wkz.js} +1 -1
  47. package/payload/server/public/assets/{chunk-XPW4576I-BwRCuKyu.js → chunk-XPW4576I-Con3TXqt.js} +1 -1
  48. package/payload/server/public/assets/{chunk-YZCP3GAM-DD9nUp-w.js → chunk-YZCP3GAM-Dx8BHGWf.js} +1 -1
  49. package/payload/server/public/assets/{chunk-ZZ45TVLE-BDH9b11G.js → chunk-ZZ45TVLE-Dp4Q5Y-f.js} +1 -1
  50. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DAbPKU6u.js +1 -0
  51. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BKuFQLcv.js +1 -0
  52. package/payload/server/public/assets/clone-DnNHGhNe.js +1 -0
  53. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-CfeophtW.js → cose-bilkent-S5V4N54A-pZiCv69E.js} +1 -1
  54. package/payload/server/public/assets/{dagre-CVxEmku2.js → dagre-CLqhEgbL.js} +1 -1
  55. package/payload/server/public/assets/{dagre-KV5264BT-TOuVLdjq.js → dagre-KV5264BT-BCxE8iyk.js} +1 -1
  56. package/payload/server/public/assets/{data-B8Waqy4Q.js → data-DDjeQQ7e.js} +1 -1
  57. package/payload/server/public/assets/{diagram-5BDNPKRD-BJQnfJjx.js → diagram-5BDNPKRD-slUEdZzz.js} +1 -1
  58. package/payload/server/public/assets/{diagram-G4DWMVQ6-CqK94J29.js → diagram-G4DWMVQ6-DPcraMfu.js} +1 -1
  59. package/payload/server/public/assets/{diagram-MMDJMWI5-BCnATv2X.js → diagram-MMDJMWI5-DR6luhGK.js} +1 -1
  60. package/payload/server/public/assets/{diagram-TYMM5635-Cl3BUrVs.js → diagram-TYMM5635-Jap1B4wA.js} +1 -1
  61. package/payload/server/public/assets/{erDiagram-SMLLAGMA--Uw0kvib.js → erDiagram-SMLLAGMA-DJKUs2hO.js} +1 -1
  62. package/payload/server/public/assets/{file-download-Pk6cNtuB.js → file-download-DBMW0BNz.js} +1 -1
  63. package/payload/server/public/assets/{flatten-DtM0XAMt.js → flatten-Cl1Bc3dR.js} +1 -1
  64. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-B_VGZIbJ.js → flowDiagram-DWJPFMVM-C8W-ZZ9W.js} +1 -1
  65. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-D-vdf1dC.js → ganttDiagram-T4ZO3ILL-DYCX4Xu2.js} +1 -1
  66. package/payload/server/public/assets/gitGraph-7Q5UKJZL-g7mvu6IY.js +1 -0
  67. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-CpyAlvu3.js → gitGraphDiagram-UUTBAWPF-CZu_fpgS.js} +1 -1
  68. package/payload/server/public/assets/{graph-D-VQpkaS.js → graph-CR74qec3.js} +1 -1
  69. package/payload/server/public/assets/{graph-labels-cJvlyVxD.js → graph-labels-1Uz0ZBRd.js} +1 -1
  70. package/payload/server/public/assets/{graphlib-DaV4XyBp.js → graphlib-Bdp7TA4y.js} +1 -1
  71. package/payload/server/public/assets/info-OMHHGYJF-DZqJuIkB.js +1 -0
  72. package/payload/server/public/assets/infoDiagram-42DDH7IO-cGfGccHz.js +2 -0
  73. package/payload/server/public/assets/{isEmpty-D__iH1WQ.js → isEmpty-D1pGOD1J.js} +1 -1
  74. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-_4NvfwwU.js → ishikawaDiagram-UXIWVN3A-B7KfIX6z.js} +1 -1
  75. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-PJQ-tPWv.js → journeyDiagram-VCZTEJTY-CSDwBfhF.js} +1 -1
  76. package/payload/server/public/assets/{jsx-runtime-BjFkEGXb.css → jsx-runtime-BqGVUT1h.css} +1 -1
  77. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-asCNlyH4.js → kanban-definition-6JOO6SKY-CWzcEKTr.js} +1 -1
  78. package/payload/server/public/assets/{line-BSXr2IPU.js → line-BNQSlbYn.js} +1 -1
  79. package/payload/server/public/assets/{linear-CSAKvvko.js → linear-BN6kGN93.js} +1 -1
  80. package/payload/server/public/assets/mermaid-parser.core-CcFhkElq.js +4 -0
  81. package/payload/server/public/assets/mermaid.core-BsIeJ7Cc.js +11 -0
  82. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-IxwnMT2Q.js → mindmap-definition-QFDTVHPH-CQVzj6D_.js} +1 -1
  83. package/payload/server/public/assets/operator-QP_z97s8.js +1 -0
  84. package/payload/server/public/assets/{ordinal-BRQ5CzZY.js → ordinal-CBZeH4Yp.js} +1 -1
  85. package/payload/server/public/assets/packet-4T2RLAQJ-Hn8rlHpy.js +1 -0
  86. package/payload/server/public/assets/{page-CFgywgGE.js → page-CLijftr1.js} +1 -1
  87. package/payload/server/public/assets/pie-ZZUOXDRM-BPGWVqBm.js +1 -0
  88. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DFqSnPPB.js → pieDiagram-DEJITSTG-DnrQ9fyn.js} +1 -1
  89. package/payload/server/public/assets/preload-helper-CQ36nxok.js +1 -0
  90. package/payload/server/public/assets/public-W-HholkU.js +6 -0
  91. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-1AB3hlEb.js → quadrantDiagram-34T5L4WZ-BQWlCyWi.js} +1 -1
  92. package/payload/server/public/assets/radar-PYXPWWZC-DMdLrj3E.js +1 -0
  93. package/payload/server/public/assets/{reduce-CkcXOmmJ.js → reduce-PuPlFPRX.js} +1 -1
  94. package/payload/server/public/assets/{requirementDiagram-MS252O5E-C2Zpzq3l.js → requirementDiagram-MS252O5E-Du_vZhU1.js} +1 -1
  95. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-DkmhPhwS.js → sankeyDiagram-XADWPNL6-Cf6Z8GPQ.js} +1 -1
  96. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-1hQLpeZ1.js → sequenceDiagram-FGHM5R23-CS8GVol8.js} +1 -1
  97. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-CBHIwm3f.js → stateDiagram-FHFEXIEX-Bv1NW2F1.js} +1 -1
  98. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BGUCxPmp.js +1 -0
  99. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-CLRWWipW.js → timeline-definition-GMOUNBTQ-ClGYAsr0.js} +1 -1
  100. package/payload/server/public/assets/treeView-SZITEDCU-CWxofUbI.js +1 -0
  101. package/payload/server/public/assets/treemap-W4RFUUIX-Cfgb_ZG0.js +1 -0
  102. package/payload/server/public/assets/{useSelectionMode-6fff2UIV.js → useSelectionMode-geYq13zs.js} +1 -1
  103. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-ByFoQMek.js → vennDiagram-DHZGUBPP-C2wTcxQT.js} +1 -1
  104. package/payload/server/public/assets/wardley-RL74JXVD-B45olYjj.js +1 -0
  105. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DIkXRSha.js → wardleyDiagram-NUSXRM2D-D86-ivEx.js} +1 -1
  106. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-BNdEcN73.js → xychartDiagram-5P7HB3ND-Ba5WAN8P.js} +1 -1
  107. package/payload/server/public/browser.html +6 -6
  108. package/payload/server/public/chat.html +9 -8
  109. package/payload/server/public/data.html +5 -5
  110. package/payload/server/public/graph.html +8 -8
  111. package/payload/server/public/index.html +9 -9
  112. package/payload/server/public/operator.html +9 -9
  113. package/payload/server/public/public.html +7 -6
  114. package/payload/server/server.js +117 -122
  115. package/payload/server/public/assets/AdminShell-Eo1RXZxq.js +0 -1
  116. package/payload/server/public/assets/admin-ORJGvOqo.js +0 -1
  117. package/payload/server/public/assets/architecture-YZFGNWBL-CQHotPO2.js +0 -1
  118. package/payload/server/public/assets/audio-attachment-mime-CFRERhV0.js +0 -1
  119. package/payload/server/public/assets/channel-DfO_IgSU.js +0 -1
  120. package/payload/server/public/assets/chat-DIrzZjdO.js +0 -1
  121. package/payload/server/public/assets/chunk-336JU56O-DHUrM3QG.js +0 -2
  122. package/payload/server/public/assets/chunk-426QAEUC-CBo-Lx7X.js +0 -1
  123. package/payload/server/public/assets/chunk-QZHKN3VN-CNlL2tiW.js +0 -1
  124. package/payload/server/public/assets/classDiagram-6PBFFD2Q-Bo-iLGpk.js +0 -1
  125. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Bz7DNpvQ.js +0 -1
  126. package/payload/server/public/assets/clone-Bh_bM_44.js +0 -1
  127. package/payload/server/public/assets/gitGraph-7Q5UKJZL-Ds2hoRX4.js +0 -1
  128. package/payload/server/public/assets/info-OMHHGYJF-BuX4gDTt.js +0 -1
  129. package/payload/server/public/assets/infoDiagram-42DDH7IO-pcFw8-8F.js +0 -2
  130. package/payload/server/public/assets/mermaid-parser.core-DFxv-h16.js +0 -4
  131. package/payload/server/public/assets/mermaid.core-Be34BFtA.js +0 -11
  132. package/payload/server/public/assets/operator-DyLRFmNE.js +0 -1
  133. package/payload/server/public/assets/packet-4T2RLAQJ-9qQ2zAJ3.js +0 -1
  134. package/payload/server/public/assets/pie-ZZUOXDRM-aDbmozld.js +0 -1
  135. package/payload/server/public/assets/public-_pD6yEQ6.js +0 -35
  136. package/payload/server/public/assets/radar-PYXPWWZC-CEm-iLey.js +0 -1
  137. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-DHGLsXgi.js +0 -1
  138. package/payload/server/public/assets/treeView-SZITEDCU-DYa2gPJa.js +0 -1
  139. package/payload/server/public/assets/treemap-W4RFUUIX-D816ED1y.js +0 -1
  140. package/payload/server/public/assets/wardley-RL74JXVD-BniDWDlr.js +0 -1
  141. /package/payload/server/public/assets/{_baseFor-SRtUHe7G.js → _baseFor-brRjpUOX.js} +0 -0
  142. /package/payload/server/public/assets/{array-BpsnM-Py.js → array-BGFCBI0e.js} +0 -0
  143. /package/payload/server/public/assets/{cytoscape.esm-D4Rl1H5h.js → cytoscape.esm-TvRJ2tGX.js} +0 -0
  144. /package/payload/server/public/assets/{defaultLocale-C7sQPl-O.js → defaultLocale-CRZydyG6.js} +0 -0
  145. /package/payload/server/public/assets/{dist-BXJR8AkG.js → dist-Dbh7HrZX.js} +0 -0
  146. /package/payload/server/public/assets/{init-BydxaDEV.js → init-B8gtcn7T.js} +0 -0
  147. /package/payload/server/public/assets/{jsx-runtime-B54kfC3e.js → jsx-runtime-D3JkFIbi.js} +0 -0
  148. /package/payload/server/public/assets/{katex-B0fVeDx4.js → katex-RxgSu_dy.js} +0 -0
  149. /package/payload/server/public/assets/{path-jlWYQ2i9.js → path-DZF-JdEe.js} +0 -0
  150. /package/payload/server/public/assets/{rough.esm-c4PR5shF.js → rough.esm-6CnTHTkH.js} +0 -0
  151. /package/payload/server/public/assets/{src-CPkr6SrY.js → src-BoaldmnP.js} +0 -0
@@ -1,6 +1,7 @@
1
1
  import { createRequire as __createRequire } from 'node:module'; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  ACCOUNTS_DIR,
4
+ AGENT_SLUG_PATTERN,
4
5
  BIN_DIR,
5
6
  BRAND_NAME,
6
7
  CDP_PORT,
@@ -15,6 +16,8 @@ import {
15
16
  LOG_DIR,
16
17
  MAXY_DIR,
17
18
  PLATFORM_ROOT,
19
+ PUBLIC_ALLOWED_EXACT,
20
+ PUBLIC_ALLOWED_PREFIXES,
18
21
  RFB_PORT,
19
22
  SYSTEM_PATH_SLUGS,
20
23
  USERS_FILE,
@@ -26,6 +29,7 @@ import {
26
29
  canAccessAdmin,
27
30
  checkGroupMembership,
28
31
  checkRateLimit,
32
+ classifyHost,
29
33
  cleanupLeakedPremiumSubs,
30
34
  clearRateLimit,
31
35
  clientIpMiddleware,
@@ -45,6 +49,7 @@ import {
45
49
  getConversationClaudeSessionIds,
46
50
  getDefaultAccountId,
47
51
  getGroupParticipants,
52
+ getOperatorDomains,
48
53
  getRecentMessages,
49
54
  getRoleForSession,
50
55
  getSession,
@@ -55,7 +60,9 @@ import {
55
60
  getUserTimezone,
56
61
  httpLog,
57
62
  isActiveAgentSlug,
63
+ isOperatorHost,
58
64
  isPasswordValid,
65
+ isPublicPathAllowed,
59
66
  isRemoteAuthConfigured,
60
67
  linkConversationTranscript,
61
68
  listAdminSessions,
@@ -97,7 +104,7 @@ import {
97
104
  vncLog,
98
105
  walkPremiumBundles,
99
106
  writeAdminUserAndPerson
100
- } from "./chunk-7H4KMTMC.js";
107
+ } from "./chunk-JHSF5VPE.js";
101
108
  import {
102
109
  __commonJS,
103
110
  __toESM
@@ -1214,40 +1221,11 @@ var serveStatic = (options = { root: "" }) => {
1214
1221
  };
1215
1222
 
1216
1223
  // server/index.ts
1217
- import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
1224
+ import { readFileSync as readFileSync26, existsSync as existsSync27, watchFile } from "fs";
1218
1225
  import { resolve as resolve29, join as join22, basename as basename8 } from "path";
1219
1226
  import { homedir as homedir3 } from "os";
1220
1227
  import { monitorEventLoopDelay } from "perf_hooks";
1221
1228
 
1222
- // app/lib/agent-slug-pattern.ts
1223
- var AGENT_SLUG_PATTERN = /^\/([a-z][a-z0-9-]{2,49})$/;
1224
-
1225
- // server/public-host-gate.ts
1226
- var PUBLIC_ALLOWED_PREFIXES = [
1227
- "/api/session",
1228
- "/api/chat",
1229
- "/api/access/",
1230
- "/api/health",
1231
- "/api/group/",
1232
- "/api/telegram/",
1233
- "/assets/",
1234
- "/brand/",
1235
- "/agent-assets/",
1236
- "/generated/",
1237
- "/g/",
1238
- "/sites/"
1239
- ];
1240
- var PUBLIC_ALLOWED_EXACT = ["/favicon.ico", "/brand-defaults.css"];
1241
- function isPublicPathAllowed(path2) {
1242
- if (path2 === "/") return true;
1243
- if (PUBLIC_ALLOWED_EXACT.includes(path2)) return true;
1244
- if (PUBLIC_ALLOWED_PREFIXES.some((prefix) => path2.startsWith(prefix))) return true;
1245
- return AGENT_SLUG_PATTERN.test(path2);
1246
- }
1247
- function isOperatorHost(host) {
1248
- return host.startsWith("operator.");
1249
- }
1250
-
1251
1229
  // server/webchat-descriptor.ts
1252
1230
  import { resolve, join as join2 } from "path";
1253
1231
  function webchatGatewayUrl() {
@@ -7732,7 +7710,7 @@ var whatsapp_reader_default = app5;
7732
7710
  // server/routes/webchat.ts
7733
7711
  import { basename as basename3, dirname as dirname2 } from "path";
7734
7712
  import { join as join11 } from "path";
7735
- import { readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync5 } from "fs";
7713
+ import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync5 } from "fs";
7736
7714
  var WEBCHAT_ADMIN_KEY = "webchat-admin";
7737
7715
  var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
7738
7716
  function locateSession(sessionId) {
@@ -7747,6 +7725,18 @@ function locateSession(sessionId) {
7747
7725
  }
7748
7726
  return { projectDir: null, channel: null };
7749
7727
  }
7728
+ function sessionSidecarExists(sessionId) {
7729
+ const cfg = claudeConfigDir();
7730
+ if (!cfg) return false;
7731
+ const projectsRoot = join11(cfg, "projects");
7732
+ let slugs;
7733
+ try {
7734
+ slugs = readdirSync7(projectsRoot, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
7735
+ } catch {
7736
+ return false;
7737
+ }
7738
+ return slugs.some((slug) => existsSync8(join11(projectsRoot, slug, `${sessionId}.meta.json`)));
7739
+ }
7750
7740
  function conflictingBinding(channel) {
7751
7741
  return channel !== null && channel !== "webchat" ? channel : null;
7752
7742
  }
@@ -8006,8 +7996,9 @@ ${note}` : note;
8006
7996
  return c.json({ error: "invalid session id" }, 400);
8007
7997
  }
8008
7998
  const { projectDir: projectDir2, channel } = locateSession(target);
7999
+ const known = projectDir2 !== null || sessionSidecarExists(target);
8009
8000
  const indicators2 = await fetchComposerIndicators(target);
8010
- return c.json({ sessionId: target, projectDir: projectDir2, channelBinding: conflictingBinding(channel), ...indicators2 });
8001
+ return c.json({ sessionId: target, projectDir: projectDir2, channelBinding: conflictingBinding(channel), known, ...indicators2 });
8011
8002
  }
8012
8003
  const sessionId = adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY);
8013
8004
  const cfg = claudeConfigDir();
@@ -8030,7 +8021,7 @@ ${note}` : note;
8030
8021
  import { resolve as resolve11 } from "path";
8031
8022
 
8032
8023
  // app/lib/claude-agent/specialist-roster.ts
8033
- import { existsSync as existsSync8, readFileSync as readFileSync12, readdirSync as readdirSync7 } from "fs";
8024
+ import { existsSync as existsSync9, readFileSync as readFileSync12, readdirSync as readdirSync8 } from "fs";
8034
8025
  import { join as join12 } from "path";
8035
8026
  function field(fm, name) {
8036
8027
  const m = fm.match(new RegExp(`^${name}:\\s*(.*?)\\r?$`, "m"));
@@ -8042,8 +8033,8 @@ function field(fm, name) {
8042
8033
  return value || null;
8043
8034
  }
8044
8035
  function readSpecialistRoster(specialistsDir) {
8045
- if (!existsSync8(specialistsDir)) return { specialists: [], skipped: [] };
8046
- const entries = readdirSync7(specialistsDir);
8036
+ if (!existsSync9(specialistsDir)) return { specialists: [], skipped: [] };
8037
+ const entries = readdirSync8(specialistsDir);
8047
8038
  const specialists = [];
8048
8039
  const skipped = [];
8049
8040
  for (const file of entries.sort()) {
@@ -8168,7 +8159,7 @@ var webchat_greeting_default = app6;
8168
8159
  // server/routes/telegram.ts
8169
8160
  import { homedir } from "os";
8170
8161
  import { resolve as resolve12, join as join13 } from "path";
8171
- import { existsSync as existsSync9, readFileSync as readFileSync13 } from "fs";
8162
+ import { existsSync as existsSync10, readFileSync as readFileSync13 } from "fs";
8172
8163
 
8173
8164
  // app/lib/telegram/access-control.ts
8174
8165
  function checkTelegramAccess(params) {
@@ -8220,7 +8211,7 @@ var DISPATCH_TIMEOUT_MS = 12e4;
8220
8211
  function configDirName() {
8221
8212
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT ?? resolve12(process.cwd(), "..");
8222
8213
  const brandPath = join13(platformRoot2, "config", "brand.json");
8223
- if (existsSync9(brandPath)) {
8214
+ if (existsSync10(brandPath)) {
8224
8215
  try {
8225
8216
  return JSON.parse(readFileSync13(brandPath, "utf-8")).configDir ?? ".maxy";
8226
8217
  } catch {
@@ -8254,7 +8245,7 @@ app7.post("/", async (c) => {
8254
8245
  return c.json({ ok: false }, 400);
8255
8246
  }
8256
8247
  const sp = secretPath(botType);
8257
- if (!existsSync9(sp)) {
8248
+ if (!existsSync10(sp)) {
8258
8249
  console.error(`${TAG22} op=reject reason=no-secret-file botType=${botType}`);
8259
8250
  return c.json({ ok: false }, 401);
8260
8251
  }
@@ -8321,11 +8312,11 @@ var telegram_default = app7;
8321
8312
 
8322
8313
  // server/routes/onboarding.ts
8323
8314
  import { spawn, spawnSync as spawnSync2, execFileSync as execFileSync2 } from "child_process";
8324
- import { openSync as openSync2, closeSync as closeSync2, writeFileSync as writeFileSync7, writeSync, existsSync as existsSync11, readFileSync as readFileSync15, unlinkSync } from "fs";
8315
+ import { openSync as openSync2, closeSync as closeSync2, writeFileSync as writeFileSync7, writeSync, existsSync as existsSync12, readFileSync as readFileSync15, unlinkSync } from "fs";
8325
8316
  import { createHash as createHash3, randomUUID as randomUUID7 } from "crypto";
8326
8317
 
8327
8318
  // ../lib/admins-write/src/index.ts
8328
- import { existsSync as existsSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync6, renameSync as renameSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync8, statSync as statSync5 } from "fs";
8319
+ import { existsSync as existsSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync6, renameSync as renameSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync9, statSync as statSync5 } from "fs";
8329
8320
  import { dirname as dirname3, join as join14 } from "path";
8330
8321
  function logLine(input, result) {
8331
8322
  const userIdShort = input.userId.slice(0, 8);
@@ -8343,7 +8334,7 @@ function writeAdminEntry(input) {
8343
8334
  const result = { usersJsonResult: "noop", accountJsonResult: "noop" };
8344
8335
  try {
8345
8336
  let users = [];
8346
- if (existsSync10(input.usersFile)) {
8337
+ if (existsSync11(input.usersFile)) {
8347
8338
  const raw = readFileSync14(input.usersFile, "utf-8").trim();
8348
8339
  if (raw) {
8349
8340
  const parsed = JSON.parse(raw);
@@ -8369,7 +8360,7 @@ function writeAdminEntry(input) {
8369
8360
  }
8370
8361
  try {
8371
8362
  const accountJsonPath = join14(input.accountDir, "account.json");
8372
- if (!existsSync10(accountJsonPath)) {
8363
+ if (!existsSync11(accountJsonPath)) {
8373
8364
  throw new Error(`account.json not found at ${accountJsonPath}`);
8374
8365
  }
8375
8366
  const config = JSON.parse(readFileSync14(accountJsonPath, "utf-8"));
@@ -8396,7 +8387,7 @@ function checkAdminAuthInvariant(input) {
8396
8387
  usersWithoutAccount: []
8397
8388
  };
8398
8389
  const usersUserIds = /* @__PURE__ */ new Set();
8399
- if (existsSync10(input.usersFile)) {
8390
+ if (existsSync11(input.usersFile)) {
8400
8391
  try {
8401
8392
  const raw = readFileSync14(input.usersFile, "utf-8").trim();
8402
8393
  if (raw) {
@@ -8411,10 +8402,10 @@ function checkAdminAuthInvariant(input) {
8411
8402
  }
8412
8403
  }
8413
8404
  const accountUserIds = /* @__PURE__ */ new Set();
8414
- if (existsSync10(input.accountsDir)) {
8405
+ if (existsSync11(input.accountsDir)) {
8415
8406
  let entries;
8416
8407
  try {
8417
- entries = readdirSync8(input.accountsDir);
8408
+ entries = readdirSync9(input.accountsDir);
8418
8409
  } catch (err) {
8419
8410
  const msg = err instanceof Error ? err.message : String(err);
8420
8411
  console.error(`[${input.tag}] accounts-dir unreadable accountsDir=${input.accountsDir} error=${msg}`);
@@ -8430,7 +8421,7 @@ function checkAdminAuthInvariant(input) {
8430
8421
  continue;
8431
8422
  }
8432
8423
  const accountJsonPath = join14(accountDir, "account.json");
8433
- if (!existsSync10(accountJsonPath)) continue;
8424
+ if (!existsSync11(accountJsonPath)) continue;
8434
8425
  let admins = [];
8435
8426
  try {
8436
8427
  const config = JSON.parse(readFileSync14(accountJsonPath, "utf-8"));
@@ -8473,7 +8464,7 @@ function hashPin2(pin) {
8473
8464
  return createHash3("sha256").update(pin).digest("hex");
8474
8465
  }
8475
8466
  function readUsersFile2() {
8476
- if (!existsSync11(USERS_FILE)) return null;
8467
+ if (!existsSync12(USERS_FILE)) return null;
8477
8468
  const raw = readFileSync15(USERS_FILE, "utf-8").trim();
8478
8469
  if (!raw) return [];
8479
8470
  return JSON.parse(raw);
@@ -8527,7 +8518,7 @@ app8.post("/claude-auth", async (c) => {
8527
8518
  } catch (err) {
8528
8519
  logoutError = err instanceof Error ? err.message : String(err);
8529
8520
  }
8530
- const credentialsPresent = existsSync11(CLAUDE_CREDENTIALS_FILE);
8521
+ const credentialsPresent = existsSync12(CLAUDE_CREDENTIALS_FILE);
8531
8522
  const ranMs = Date.now() - start;
8532
8523
  console.log(`[onboarding] op=claude-logout credentialsPresent=${credentialsPresent} ranMs=${ranMs} logoutError=${logoutError ? JSON.stringify(logoutError.slice(0, 120)) : "none"}`);
8533
8524
  return c.json({ logged_out: !credentialsPresent });
@@ -8634,7 +8625,7 @@ app8.post("/set-pin", async (c) => {
8634
8625
  console.log(`[set-pin] wrote users.json + account.json admins: userId=${userId.slice(0, 8)}\u2026 role=owner`);
8635
8626
  if (process.platform === "linux") {
8636
8627
  let installOwner = null;
8637
- if (existsSync11(INSTALL_OWNER_FILE)) {
8628
+ if (existsSync12(INSTALL_OWNER_FILE)) {
8638
8629
  try {
8639
8630
  const raw = readFileSync15(INSTALL_OWNER_FILE, "utf-8").trim();
8640
8631
  if (raw.length > 0) installOwner = raw;
@@ -8717,7 +8708,7 @@ app8.delete("/set-pin", async (c) => {
8717
8708
  var onboarding_default = app8;
8718
8709
 
8719
8710
  // server/routes/client-error.ts
8720
- import { appendFileSync, existsSync as existsSync12, renameSync as renameSync3, statSync as statSync6 } from "fs";
8711
+ import { appendFileSync, existsSync as existsSync13, renameSync as renameSync3, statSync as statSync6 } from "fs";
8721
8712
  import { join as join15 } from "path";
8722
8713
  var CLIENT_ERRORS_LOG = join15(LOG_DIR, "client-errors.log");
8723
8714
  var MAX_LOG_SIZE = 10 * 1024 * 1024;
@@ -8762,7 +8753,7 @@ function stackHead(stack) {
8762
8753
  }
8763
8754
  function rotateIfNeeded() {
8764
8755
  try {
8765
- if (!existsSync12(CLIENT_ERRORS_LOG)) return;
8756
+ if (!existsSync13(CLIENT_ERRORS_LOG)) return;
8766
8757
  const stats = statSync6(CLIENT_ERRORS_LOG);
8767
8758
  if (stats.size < MAX_LOG_SIZE) return;
8768
8759
  renameSync3(CLIENT_ERRORS_LOG, CLIENT_ERRORS_LOG + ".1");
@@ -9044,18 +9035,18 @@ app10.post("/", async (c) => {
9044
9035
  var session_default = app10;
9045
9036
 
9046
9037
  // server/routes/admin/logs.ts
9047
- import { existsSync as existsSync14, readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
9038
+ import { existsSync as existsSync15, readdirSync as readdirSync10, readFileSync as readFileSync16, statSync as statSync7 } from "fs";
9048
9039
  import { resolve as resolve13, basename as basename4 } from "path";
9049
9040
 
9050
9041
  // app/lib/logs-read-resolve.ts
9051
- import { existsSync as existsSync13 } from "fs";
9042
+ import { existsSync as existsSync14 } from "fs";
9052
9043
  import { join as join16 } from "path";
9053
9044
  function resolveSessionLogPaths(filename, logDirs) {
9054
9045
  const tried = [filename];
9055
9046
  const hits = [];
9056
9047
  for (const dir of logDirs) {
9057
9048
  const fullPath = join16(dir, filename);
9058
- if (existsSync13(fullPath)) {
9049
+ if (existsSync14(fullPath)) {
9059
9050
  hits.push({ path: fullPath, dir });
9060
9051
  }
9061
9052
  }
@@ -9183,10 +9174,10 @@ app11.get("/", async (c) => {
9183
9174
  const seen = /* @__PURE__ */ new Set();
9184
9175
  const logs = {};
9185
9176
  for (const dir of logDirs) {
9186
- if (!existsSync14(dir)) continue;
9177
+ if (!existsSync15(dir)) continue;
9187
9178
  let files;
9188
9179
  try {
9189
- files = readdirSync9(dir).filter((f) => f.endsWith(".log"));
9180
+ files = readdirSync10(dir).filter((f) => f.endsWith(".log"));
9190
9181
  } catch (err) {
9191
9182
  const reason = err instanceof Error ? err.message : String(err);
9192
9183
  console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
@@ -9234,7 +9225,7 @@ var claude_info_default = app12;
9234
9225
 
9235
9226
  // server/routes/admin/attachment.ts
9236
9227
  import { readFile as readFile2, readdir } from "fs/promises";
9237
- import { existsSync as existsSync15 } from "fs";
9228
+ import { existsSync as existsSync16 } from "fs";
9238
9229
  import { resolve as resolve14 } from "path";
9239
9230
  var app13 = new Hono();
9240
9231
  app13.get("/:attachmentId", requireAdminSession, async (c) => {
@@ -9248,11 +9239,11 @@ app13.get("/:attachmentId", requireAdminSession, async (c) => {
9248
9239
  return new Response("Not found", { status: 404 });
9249
9240
  }
9250
9241
  const dir = resolve14(ATTACHMENTS_ROOT, accountId, attachmentId);
9251
- if (!existsSync15(dir)) {
9242
+ if (!existsSync16(dir)) {
9252
9243
  return new Response("Not found", { status: 404 });
9253
9244
  }
9254
9245
  const metaPath = resolve14(dir, `${attachmentId}.meta.json`);
9255
- if (!existsSync15(metaPath)) {
9246
+ if (!existsSync16(metaPath)) {
9256
9247
  return new Response("Not found", { status: 404 });
9257
9248
  }
9258
9249
  let meta;
@@ -9280,21 +9271,21 @@ var attachment_default = app13;
9280
9271
 
9281
9272
  // server/routes/admin/agents.ts
9282
9273
  import { resolve as resolve15 } from "path";
9283
- import { readdirSync as readdirSync10, readFileSync as readFileSync17, existsSync as existsSync16, rmSync } from "fs";
9274
+ import { readdirSync as readdirSync11, readFileSync as readFileSync17, existsSync as existsSync17, rmSync } from "fs";
9284
9275
  var app14 = new Hono();
9285
9276
  app14.get("/", (c) => {
9286
9277
  const account = resolveAccount();
9287
9278
  if (!account) return c.json({ agents: [] });
9288
9279
  const agentsDir = resolve15(account.accountDir, "agents");
9289
- if (!existsSync16(agentsDir)) return c.json({ agents: [] });
9280
+ if (!existsSync17(agentsDir)) return c.json({ agents: [] });
9290
9281
  const agents = [];
9291
9282
  try {
9292
- const entries = readdirSync10(agentsDir, { withFileTypes: true });
9283
+ const entries = readdirSync11(agentsDir, { withFileTypes: true });
9293
9284
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
9294
9285
  if (!entry.isDirectory()) continue;
9295
9286
  if (entry.name === "admin") continue;
9296
9287
  const configPath2 = resolve15(agentsDir, entry.name, "config.json");
9297
- if (!existsSync16(configPath2)) continue;
9288
+ if (!existsSync17(configPath2)) continue;
9298
9289
  try {
9299
9290
  const config = JSON.parse(readFileSync17(configPath2, "utf-8"));
9300
9291
  agents.push({
@@ -9323,7 +9314,7 @@ app14.delete("/:slug", async (c) => {
9323
9314
  return c.json({ error: "Invalid agent slug" }, 400);
9324
9315
  }
9325
9316
  const agentDir = resolve15(account.accountDir, "agents", slug);
9326
- if (!existsSync16(agentDir)) {
9317
+ if (!existsSync17(agentDir)) {
9327
9318
  return c.json({ error: "Agent not found" }, 404);
9328
9319
  }
9329
9320
  try {
@@ -9353,7 +9344,7 @@ app14.post("/:slug/project", async (c) => {
9353
9344
  return c.json({ error: "Invalid agent slug" }, 400);
9354
9345
  }
9355
9346
  const agentDir = resolve15(account.accountDir, "agents", slug);
9356
- if (!existsSync16(agentDir)) {
9347
+ if (!existsSync17(agentDir)) {
9357
9348
  return c.json({ error: "Agent not found on disk" }, 404);
9358
9349
  }
9359
9350
  try {
@@ -9369,7 +9360,7 @@ var agents_default = app14;
9369
9360
  // server/routes/admin/sessions.ts
9370
9361
  import crypto2 from "crypto";
9371
9362
  import { resolve as resolvePath } from "path";
9372
- import { existsSync as existsSync17, mkdirSync as mkdirSync3, createWriteStream } from "fs";
9363
+ import { existsSync as existsSync18, mkdirSync as mkdirSync3, createWriteStream } from "fs";
9373
9364
 
9374
9365
  // ../lib/admin-conversation-purge/src/index.ts
9375
9366
  async function purgeAdminConversationJsonls(args) {
@@ -9529,7 +9520,7 @@ function validateAndShapeAttachments(raws, conversationAccountId, sessionId, mes
9529
9520
  let reason = null;
9530
9521
  if (!a.attachmentId || !a.filename || !a.mimeType || !a.storagePath) reason = "schema-fail";
9531
9522
  else if (a.accountId !== conversationAccountId) reason = "account-mismatch";
9532
- else if (!existsSync17(a.storagePath)) reason = "missing-file";
9523
+ else if (!existsSync18(a.storagePath)) reason = "missing-file";
9533
9524
  if (reason) {
9534
9525
  invalid++;
9535
9526
  try {
@@ -10055,7 +10046,7 @@ app15.put("/:id/label", requireAdminSession, async (c) => {
10055
10046
  var sessions_default = app15;
10056
10047
 
10057
10048
  // app/lib/claude-agent/spawn-context.ts
10058
- import { existsSync as existsSync18, readFileSync as readFileSync18, readdirSync as readdirSync11, statSync as statSync8 } from "fs";
10049
+ import { existsSync as existsSync19, readFileSync as readFileSync18, readdirSync as readdirSync12, statSync as statSync8 } from "fs";
10059
10050
  import { dirname as dirname4, resolve as resolve16, join as join17 } from "path";
10060
10051
  async function resolveOwnerProfileBlock(accountId, userId) {
10061
10052
  if (!userId) return { ok: false, reason: "missing-user-id" };
@@ -10090,7 +10081,7 @@ function extractPluginToolDescriptions(pluginDir) {
10090
10081
  ];
10091
10082
  let raw = null;
10092
10083
  for (const path2 of candidates) {
10093
- if (!existsSync18(path2)) continue;
10084
+ if (!existsSync19(path2)) continue;
10094
10085
  try {
10095
10086
  raw = readFileSync18(path2, "utf-8");
10096
10087
  break;
@@ -10142,8 +10133,8 @@ function parseSkillPathsFromFrontmatter(fm) {
10142
10133
  function listPluginDirs() {
10143
10134
  const out = /* @__PURE__ */ new Map();
10144
10135
  const platformPlugins = resolve16(PLATFORM_ROOT, "plugins");
10145
- if (existsSync18(platformPlugins)) {
10146
- for (const name of readdirSync11(platformPlugins)) {
10136
+ if (existsSync19(platformPlugins)) {
10137
+ for (const name of readdirSync12(platformPlugins)) {
10147
10138
  const dir = join17(platformPlugins, name);
10148
10139
  try {
10149
10140
  if (statSync8(dir).isDirectory()) out.set(name, dir);
@@ -10152,12 +10143,12 @@ function listPluginDirs() {
10152
10143
  }
10153
10144
  }
10154
10145
  const premiumRoot = resolve16(dirname4(PLATFORM_ROOT), "premium-plugins");
10155
- if (existsSync18(premiumRoot)) {
10156
- for (const bundle of readdirSync11(premiumRoot)) {
10146
+ if (existsSync19(premiumRoot)) {
10147
+ for (const bundle of readdirSync12(premiumRoot)) {
10157
10148
  const bundlePlugins = join17(premiumRoot, bundle, "plugins");
10158
- if (!existsSync18(bundlePlugins)) continue;
10149
+ if (!existsSync19(bundlePlugins)) continue;
10159
10150
  try {
10160
- for (const name of readdirSync11(bundlePlugins)) {
10151
+ for (const name of readdirSync12(bundlePlugins)) {
10161
10152
  const dir = join17(bundlePlugins, name);
10162
10153
  try {
10163
10154
  if (statSync8(dir).isDirectory()) out.set(name, dir);
@@ -10172,7 +10163,7 @@ function listPluginDirs() {
10172
10163
  }
10173
10164
  function readEnabledPlugins(accountId) {
10174
10165
  const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10175
- if (!existsSync18(accountFile)) return /* @__PURE__ */ new Set();
10166
+ if (!existsSync19(accountFile)) return /* @__PURE__ */ new Set();
10176
10167
  try {
10177
10168
  const parsed = JSON.parse(readFileSync18(accountFile, "utf-8"));
10178
10169
  return new Set(
@@ -10183,7 +10174,7 @@ function readEnabledPlugins(accountId) {
10183
10174
  }
10184
10175
  }
10185
10176
  function readFrontmatter(path2) {
10186
- if (!existsSync18(path2)) return null;
10177
+ if (!existsSync19(path2)) return null;
10187
10178
  let raw;
10188
10179
  try {
10189
10180
  raw = readFileSync18(path2, "utf-8");
@@ -10218,7 +10209,7 @@ ${fm}
10218
10209
  `plugin-manifest-tool-coverage plugin=${name} tools=${tools.length} with-desc=${withDesc}`
10219
10210
  );
10220
10211
  if (toolNames.length > 0 && descMap.size === 0) {
10221
- const hasSource = existsSync18(join17(dir, "mcp/dist/index.js")) || existsSync18(join17(dir, "mcp/src/index.ts"));
10212
+ const hasSource = existsSync19(join17(dir, "mcp/dist/index.js")) || existsSync19(join17(dir, "mcp/src/index.ts"));
10222
10213
  if (hasSource) {
10223
10214
  console.warn(
10224
10215
  `[spawn-context] WARN plugin=${name} mcp source present but tool-description regex matched zero entries \u2014 SDK upgrade may have changed the registration shape`
@@ -10245,10 +10236,10 @@ ${skillFm}
10245
10236
  }
10246
10237
  function computeSpecialistDomains(accountId) {
10247
10238
  const specialistsDir = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "specialists", "agents");
10248
- if (!existsSync18(specialistsDir)) return [];
10239
+ if (!existsSync19(specialistsDir)) return [];
10249
10240
  let entries;
10250
10241
  try {
10251
- entries = readdirSync11(specialistsDir);
10242
+ entries = readdirSync12(specialistsDir);
10252
10243
  } catch {
10253
10244
  return [];
10254
10245
  }
@@ -10291,7 +10282,7 @@ ${fm}
10291
10282
  }
10292
10283
  function computeDormantPlugins(accountId) {
10293
10284
  const accountFile = resolve16(PLATFORM_ROOT, "..", "data/accounts", accountId, "account.json");
10294
- if (!existsSync18(accountFile)) return [];
10285
+ if (!existsSync19(accountFile)) return [];
10295
10286
  let enabled;
10296
10287
  try {
10297
10288
  const raw = readFileSync18(accountFile, "utf-8");
@@ -10306,10 +10297,10 @@ function computeDormantPlugins(accountId) {
10306
10297
  return [];
10307
10298
  }
10308
10299
  const pluginsDir = resolve16(PLATFORM_ROOT, "plugins");
10309
- if (!existsSync18(pluginsDir)) return [];
10300
+ if (!existsSync19(pluginsDir)) return [];
10310
10301
  let entries;
10311
10302
  try {
10312
- entries = readdirSync11(pluginsDir);
10303
+ entries = readdirSync12(pluginsDir);
10313
10304
  } catch {
10314
10305
  return [];
10315
10306
  }
@@ -10317,7 +10308,7 @@ function computeDormantPlugins(accountId) {
10317
10308
  for (const name of entries) {
10318
10309
  if (enabled.has(name)) continue;
10319
10310
  const manifestPath = resolve16(pluginsDir, name, "PLUGIN.md");
10320
- if (!existsSync18(manifestPath)) continue;
10311
+ if (!existsSync19(manifestPath)) continue;
10321
10312
  let manifest;
10322
10313
  try {
10323
10314
  manifest = readFileSync18(manifestPath, "utf-8");
@@ -10334,11 +10325,11 @@ function computeDormantPlugins(accountId) {
10334
10325
  }
10335
10326
 
10336
10327
  // server/routes/admin/claude-sessions.ts
10337
- import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
10328
+ import { existsSync as existsSync20, readFileSync as readFileSync19 } from "fs";
10338
10329
  import { resolve as resolve17 } from "path";
10339
10330
  function readTunnelState(brandConfigDir) {
10340
10331
  const statePath = `${process.env.HOME ?? ""}/${brandConfigDir}/cloudflared/tunnel.state`;
10341
- if (!existsSync19(statePath)) return null;
10332
+ if (!existsSync20(statePath)) return null;
10342
10333
  try {
10343
10334
  const parsed = JSON.parse(readFileSync19(statePath, "utf-8"));
10344
10335
  const tunnelId = typeof parsed.tunnelId === "string" ? parsed.tunnelId : null;
@@ -13780,7 +13771,7 @@ var graph_default_view_default = app25;
13780
13771
  // server/routes/admin/sidebar-artefacts.ts
13781
13772
  import { readdir as readdir4, stat as stat5 } from "fs/promises";
13782
13773
  import { resolve as resolve21, relative as relative3, isAbsolute, sep as sep6, basename as basename7 } from "path";
13783
- import { existsSync as existsSync20 } from "fs";
13774
+ import { existsSync as existsSync21 } from "fs";
13784
13775
  var LIMIT = 50;
13785
13776
  var ADMIN_AGENT_FILES = ["IDENTITY.md", "SOUL.md", "KNOWLEDGE.md"];
13786
13777
  function toDataRootRelPath(absPath) {
@@ -13886,7 +13877,7 @@ async function fetchAgentTemplateRows(accountDir) {
13886
13877
  async function unionSpecialistFilenames(overrideDir, bundledDir) {
13887
13878
  const names = /* @__PURE__ */ new Set();
13888
13879
  for (const dir of [overrideDir, bundledDir]) {
13889
- if (!existsSync20(dir)) continue;
13880
+ if (!existsSync21(dir)) continue;
13890
13881
  try {
13891
13882
  const entries = await readdir4(dir);
13892
13883
  for (const entry of entries) {
@@ -13901,7 +13892,7 @@ async function unionSpecialistFilenames(overrideDir, bundledDir) {
13901
13892
  }
13902
13893
  async function readAgentTemplateRow(inp) {
13903
13894
  let chosenPath = null;
13904
- if (existsSync20(inp.overridePath)) {
13895
+ if (existsSync21(inp.overridePath)) {
13905
13896
  try {
13906
13897
  validateFilePathInAccount(inp.overridePath, inp.overrideRoot);
13907
13898
  chosenPath = inp.overridePath;
@@ -13912,7 +13903,7 @@ async function readAgentTemplateRow(inp) {
13912
13903
  );
13913
13904
  return null;
13914
13905
  }
13915
- } else if (existsSync20(inp.bundledPath)) {
13906
+ } else if (existsSync21(inp.bundledPath)) {
13916
13907
  if (!isWithin(inp.bundledPath, inp.bundledRoot)) {
13917
13908
  console.error(
13918
13909
  `[admin/sidebar-artefacts] agent-template-read-failed agent=${inp.displayName} kind=${inp.logName} error="bundled path outside PLATFORM_ROOT"`
@@ -14078,8 +14069,8 @@ var session_archive_default = app29;
14078
14069
 
14079
14070
  // server/routes/admin/session-rc-spawn.ts
14080
14071
  import { randomUUID as randomUUID9 } from "crypto";
14081
- function resolveSpawnPlan(host, body, mintId = randomUUID9) {
14082
- const operator = isOperatorHost(host);
14072
+ function resolveSpawnPlan(host, operatorDomains, body, mintId = randomUUID9) {
14073
+ const operator = isOperatorHost(host, operatorDomains);
14083
14074
  const resumeId = typeof body.sessionId === "string" && body.sessionId.length > 0 ? body.sessionId : void 0;
14084
14075
  const name = typeof body.name === "string" && body.name.length > 0 ? body.name : void 0;
14085
14076
  const webchatBind = resumeId === void 0 || operator;
@@ -14115,8 +14106,8 @@ app30.post("/", requireAdminSession, async (c) => {
14115
14106
  } catch {
14116
14107
  body = {};
14117
14108
  }
14118
- const host = c.req.header("host") ?? "";
14119
- const plan = resolveSpawnPlan(host, body);
14109
+ const host = (c.req.header("host") ?? "").split(":")[0];
14110
+ const plan = resolveSpawnPlan(host, getOperatorDomains(), body);
14120
14111
  const spawnReqId = randomUUID9();
14121
14112
  console.log(
14122
14113
  `[chat-spawn] op=request spawnReqId=${spawnReqId} origin=${plan.origin} kind=${plan.kind} sessionId=${plan.kind === "new" ? "new" : plan.sessionId}`
@@ -14283,12 +14274,12 @@ app31.get("/", async (c) => {
14283
14274
  var system_stats_default = app31;
14284
14275
 
14285
14276
  // server/routes/admin/health.ts
14286
- import { existsSync as existsSync21, readFileSync as readFileSync20 } from "fs";
14277
+ import { existsSync as existsSync22, readFileSync as readFileSync20 } from "fs";
14287
14278
  import { resolve as resolve22, join as join20 } from "path";
14288
14279
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT ?? resolve22(process.cwd(), "..");
14289
14280
  var brandHostname = "maxy";
14290
14281
  var brandJsonPath = join20(PLATFORM_ROOT6, "config", "brand.json");
14291
- if (existsSync21(brandJsonPath)) {
14282
+ if (existsSync22(brandJsonPath)) {
14292
14283
  try {
14293
14284
  const brand = JSON.parse(readFileSync20(brandJsonPath, "utf-8"));
14294
14285
  if (brand.hostname) brandHostname = brand.hostname;
@@ -14299,7 +14290,7 @@ var VERSION_FILE = resolve22(PLATFORM_ROOT6, `config/.${brandHostname}-version`)
14299
14290
  var PROCESS_STARTED_AT = (/* @__PURE__ */ new Date()).toISOString();
14300
14291
  var PROBE_TIMEOUT_MS = 1e3;
14301
14292
  function readVersion() {
14302
- if (!existsSync21(VERSION_FILE)) return "unknown";
14293
+ if (!existsSync22(VERSION_FILE)) return "unknown";
14303
14294
  return readFileSync20(VERSION_FILE, "utf-8").trim() || "unknown";
14304
14295
  }
14305
14296
  async function probeConversationDb() {
@@ -15283,7 +15274,7 @@ app42.route("/request-magic-link", request_magic_link_default);
15283
15274
  var access_default = app42;
15284
15275
 
15285
15276
  // server/routes/sites.ts
15286
- import { existsSync as existsSync22, readFileSync as readFileSync22, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
15277
+ import { existsSync as existsSync23, readFileSync as readFileSync22, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
15287
15278
  import { resolve as resolve25 } from "path";
15288
15279
  var SAFE_SEG_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15289
15280
  var MIME = {
@@ -15349,7 +15340,7 @@ app43.get("/:rel{.*}", (c) => {
15349
15340
  }
15350
15341
  let stat7;
15351
15342
  try {
15352
- stat7 = existsSync22(filePath) ? statSync9(filePath) : null;
15343
+ stat7 = existsSync23(filePath) ? statSync9(filePath) : null;
15353
15344
  } catch {
15354
15345
  stat7 = null;
15355
15346
  }
@@ -15368,7 +15359,7 @@ app43.get("/:rel{.*}", (c) => {
15368
15359
  console.error(`[sites] path-traversal-rejected path=${reqPath} reason=escape status=403`);
15369
15360
  return c.text("Forbidden", 403);
15370
15361
  }
15371
- if (!existsSync22(filePath)) {
15362
+ if (!existsSync23(filePath)) {
15372
15363
  console.error(`[sites] not-found path=${reqPath} status=404`);
15373
15364
  return c.text("Not found", 404);
15374
15365
  }
@@ -15499,7 +15490,7 @@ var VISITOR_COOKIE_NAME = "mxy_v";
15499
15490
  var VISITOR_COOKIE_MAX_AGE_SECONDS = Math.floor(DEFAULT_TTL_MS / 1e3);
15500
15491
 
15501
15492
  // app/lib/brand-config.ts
15502
- import { existsSync as existsSync23, readFileSync as readFileSync24 } from "fs";
15493
+ import { existsSync as existsSync24, readFileSync as readFileSync24 } from "fs";
15503
15494
  import { join as join21 } from "path";
15504
15495
  var cached2 = null;
15505
15496
  var cachedAttempted = false;
@@ -15509,7 +15500,7 @@ function readBrandConfig() {
15509
15500
  const platformRoot2 = process.env.MAXY_PLATFORM_ROOT;
15510
15501
  if (!platformRoot2) return null;
15511
15502
  const brandPath = join21(platformRoot2, "config", "brand.json");
15512
- if (!existsSync23(brandPath)) return null;
15503
+ if (!existsSync24(brandPath)) return null;
15513
15504
  try {
15514
15505
  cached2 = JSON.parse(readFileSync24(brandPath, "utf-8"));
15515
15506
  return cached2;
@@ -16000,7 +15991,7 @@ var visitor_event_default = app46;
16000
15991
 
16001
15992
  // server/routes/session.ts
16002
15993
  import { resolve as resolve26 } from "path";
16003
- import { existsSync as existsSync24, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "fs";
15994
+ import { existsSync as existsSync25, writeFileSync as writeFileSync9, mkdirSync as mkdirSync5 } from "fs";
16004
15995
  var UUID_RE4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
16005
15996
  function writeBrandingCache(accountId, agentSlug, branding) {
16006
15997
  try {
@@ -16095,7 +16086,7 @@ app47.post("/", async (c) => {
16095
16086
  let agentConfig = null;
16096
16087
  if (account) {
16097
16088
  const agentDir = resolve26(account.accountDir, "agents", agentSlug);
16098
- if (!existsSync24(agentDir) || !existsSync24(resolve26(agentDir, "config.json"))) {
16089
+ if (!existsSync25(agentDir) || !existsSync25(resolve26(agentDir, "config.json"))) {
16099
16090
  return c.json({ error: "Agent not found" }, 404);
16100
16091
  }
16101
16092
  agentConfig = resolveAgentConfig(account.accountDir, agentSlug);
@@ -17333,7 +17324,7 @@ function broadcastAdminShutdown(reason) {
17333
17324
 
17334
17325
  // ../lib/entitlement/src/index.ts
17335
17326
  import { createPublicKey, createHash as createHash5, verify as cryptoVerify } from "crypto";
17336
- import { existsSync as existsSync25, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
17327
+ import { existsSync as existsSync26, readFileSync as readFileSync25, statSync as statSync10 } from "fs";
17337
17328
  import { resolve as resolve28 } from "path";
17338
17329
 
17339
17330
  // ../lib/entitlement/src/canonicalize.ts
@@ -17382,7 +17373,7 @@ function resolveEntitlement(brand, account) {
17382
17373
  return logResolved(implicitTrust(account), null);
17383
17374
  }
17384
17375
  const entitlementPath = resolve28(brand.configDir, "entitlement.json");
17385
- if (!existsSync25(entitlementPath)) {
17376
+ if (!existsSync26(entitlementPath)) {
17386
17377
  return logResolved(anonymousFallback("missing"), { reason: "missing" });
17387
17378
  }
17388
17379
  const stat7 = statSync10(entitlementPath);
@@ -17574,10 +17565,10 @@ function clientFrom(c) {
17574
17565
  var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
17575
17566
  var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join22(PLATFORM_ROOT9, "config", "brand.json") : "";
17576
17567
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", marketingUrl: "https://getmaxy.com" };
17577
- if (BRAND_JSON_PATH && !existsSync26(BRAND_JSON_PATH)) {
17568
+ if (BRAND_JSON_PATH && !existsSync27(BRAND_JSON_PATH)) {
17578
17569
  console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
17579
17570
  }
17580
- if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
17571
+ if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
17581
17572
  try {
17582
17573
  const parsed = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
17583
17574
  BRAND = { ...BRAND, ...parsed };
@@ -17601,7 +17592,7 @@ var brandLoginOpts = {
17601
17592
  var ALIAS_DOMAINS_PATH = join22(homedir3(), BRAND.configDir, "alias-domains.json");
17602
17593
  function loadAliasDomains() {
17603
17594
  try {
17604
- if (!existsSync26(ALIAS_DOMAINS_PATH)) return null;
17595
+ if (!existsSync27(ALIAS_DOMAINS_PATH)) return null;
17605
17596
  const parsed = JSON.parse(readFileSync26(ALIAS_DOMAINS_PATH, "utf-8"));
17606
17597
  if (!Array.isArray(parsed)) {
17607
17598
  console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
@@ -17738,7 +17729,7 @@ app48.use("*", async (c, next) => {
17738
17729
  });
17739
17730
  app48.use("*", async (c, next) => {
17740
17731
  const host = (c.req.header("host") ?? "").split(":")[0];
17741
- if (!isPublicHost(host)) {
17732
+ if (isOperatorHost(host, getOperatorDomains()) || !isPublicHost(host)) {
17742
17733
  await next();
17743
17734
  return;
17744
17735
  }
@@ -17970,7 +17961,10 @@ app48.use("*", async (c, next) => {
17970
17961
  remoteAddress: rawRemote,
17971
17962
  xForwardedFor: rawXff,
17972
17963
  cookieHeader: c.req.header("cookie"),
17973
- isPublicHost
17964
+ // Task 829 — operator-wins: an operator host is admin-gated, so it must not
17965
+ // be classified public here (which would bypass the admin gate). A host in
17966
+ // both operator-domains.json and alias-domains.json stays admin-gated.
17967
+ isPublicHost: (h) => !isOperatorHost(h, getOperatorDomains()) && isPublicHost(h)
17974
17968
  });
17975
17969
  if (decision.allow) {
17976
17970
  await next();
@@ -18033,7 +18027,7 @@ app48.get("/agent-assets/:slug/:filename", (c) => {
18033
18027
  console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
18034
18028
  return c.text("Forbidden", 403);
18035
18029
  }
18036
- if (!existsSync26(filePath)) {
18030
+ if (!existsSync27(filePath)) {
18037
18031
  console.error(`[agent-assets] serve slug=${slug} file=${filename} status=404`);
18038
18032
  return c.text("Not found", 404);
18039
18033
  }
@@ -18063,7 +18057,7 @@ app48.get("/generated/:filename", (c) => {
18063
18057
  console.error(`[generated] serve file=${filename} status=403`);
18064
18058
  return c.text("Forbidden", 403);
18065
18059
  }
18066
- if (!existsSync26(filePath)) {
18060
+ if (!existsSync27(filePath)) {
18067
18061
  console.error(`[generated] serve file=${filename} status=404`);
18068
18062
  return c.text("Not found", 404);
18069
18063
  }
@@ -18083,7 +18077,7 @@ app48.route("/v", visitor_consent_default);
18083
18077
  var htmlCache = /* @__PURE__ */ new Map();
18084
18078
  var brandLogoPath = "/brand/maxy-monochrome.png";
18085
18079
  var brandIconPath = "/brand/maxy-monochrome.png";
18086
- if (BRAND_JSON_PATH && existsSync26(BRAND_JSON_PATH)) {
18080
+ if (BRAND_JSON_PATH && existsSync27(BRAND_JSON_PATH)) {
18087
18081
  try {
18088
18082
  const fullBrand = JSON.parse(readFileSync26(BRAND_JSON_PATH, "utf-8"));
18089
18083
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
@@ -18103,7 +18097,7 @@ function readInstalledVersion() {
18103
18097
  try {
18104
18098
  if (!PLATFORM_ROOT9) return "unknown";
18105
18099
  const versionFile = join22(PLATFORM_ROOT9, "config", `.${BRAND.hostname}-version`);
18106
- if (!existsSync26(versionFile)) return "unknown";
18100
+ if (!existsSync27(versionFile)) return "unknown";
18107
18101
  const content = readFileSync26(versionFile, "utf-8").trim();
18108
18102
  return content || "unknown";
18109
18103
  } catch {
@@ -18166,7 +18160,7 @@ function loadBrandingCache(agentSlug) {
18166
18160
  const accountId = getDefaultAccountId();
18167
18161
  if (!accountId) return null;
18168
18162
  const cachePath = join22(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
18169
- if (!existsSync26(cachePath)) return null;
18163
+ if (!existsSync27(cachePath)) return null;
18170
18164
  return JSON.parse(readFileSync26(cachePath, "utf-8"));
18171
18165
  } catch {
18172
18166
  return null;
@@ -18212,11 +18206,12 @@ function agentUnavailableHtml() {
18212
18206
  }
18213
18207
  app48.get("/", (c) => {
18214
18208
  const host = (c.req.header("host") ?? "").split(":")[0];
18215
- if (isOperatorHost(host)) {
18209
+ const klass = classifyHost(host, getOperatorDomains(), isPublicHost);
18210
+ if (klass === "operator") {
18216
18211
  console.log(`[host-class] host=${host} class=operator served=operator.html`);
18217
18212
  return c.html(cachedHtml("operator.html"));
18218
18213
  }
18219
- if (isPublicHost(host)) {
18214
+ if (klass === "public") {
18220
18215
  const defaultSlug = resolveDefaultSlug();
18221
18216
  if (!defaultSlug) {
18222
18217
  console.error("[public-root] op=no-default");
@@ -18296,7 +18291,7 @@ app48.get("/g/:slug", (c) => {
18296
18291
  });
18297
18292
  app48.get("/graph", (c) => {
18298
18293
  const host = (c.req.header("host") ?? "").split(":")[0];
18299
- if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
18294
+ if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
18300
18295
  return c.html(cachedHtml("graph.html"));
18301
18296
  });
18302
18297
  app48.get("/chat", (c) => {
@@ -18311,7 +18306,7 @@ app48.get("/data", (c) => {
18311
18306
  });
18312
18307
  app48.get("/browser", (c) => {
18313
18308
  const host = (c.req.header("host") ?? "").split(":")[0];
18314
- if (isPublicHost(host) || isOperatorHost(host)) return c.text("Not found", 404);
18309
+ if (isPublicHost(host) || isOperatorHost(host, getOperatorDomains())) return c.text("Not found", 404);
18315
18310
  return c.html(cachedHtml("browser.html"));
18316
18311
  });
18317
18312
  app48.get("/:slug", async (c, next) => {
@@ -18416,7 +18411,7 @@ try {
18416
18411
  var ADMINUSER_RECONCILE_INTERVAL_MS = 60 * 60 * 1e3;
18417
18412
  async function runAdminUserReconcileTick() {
18418
18413
  try {
18419
- if (!existsSync26(USERS_FILE)) {
18414
+ if (!existsSync27(USERS_FILE)) {
18420
18415
  console.error("[adminuser-self-heal] skip reason=no-users-file");
18421
18416
  return;
18422
18417
  }