@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
@@ -2481,7 +2481,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
2481
2481
  });
2482
2482
  if (!chunk) {
2483
2483
  if (i === 1) {
2484
- await new Promise((resolve6) => setTimeout(resolve6));
2484
+ await new Promise((resolve7) => setTimeout(resolve7));
2485
2485
  maxReadCount = 3;
2486
2486
  continue;
2487
2487
  }
@@ -2778,10 +2778,10 @@ var SCRYPT_R = 8;
2778
2778
  var SCRYPT_P = 1;
2779
2779
  var SCRYPT_KEYLEN = 64;
2780
2780
  function scryptAsync(password, salt) {
2781
- return new Promise((resolve6, reject) => {
2781
+ return new Promise((resolve7, reject) => {
2782
2782
  scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
2783
2783
  if (err) reject(err);
2784
- else resolve6(key);
2784
+ else resolve7(key);
2785
2785
  });
2786
2786
  });
2787
2787
  }
@@ -3429,16 +3429,85 @@ function parseCookieValue(cookieHeader, name) {
3429
3429
  }
3430
3430
  }
3431
3431
 
3432
+ // app/lib/agent-slug-pattern.ts
3433
+ var AGENT_SLUG_PATTERN = /^\/([a-z][a-z0-9-]{2,49})$/;
3434
+
3432
3435
  // app/lib/system-path-slugs.ts
3433
3436
  var SYSTEM_PATH_SLUGS = ["public", "public-chat", "chat", "graph", "data", "browser"];
3434
3437
 
3438
+ // server/public-host-gate.ts
3439
+ var PUBLIC_ALLOWED_PREFIXES = [
3440
+ "/api/session",
3441
+ "/api/chat",
3442
+ "/api/access/",
3443
+ "/api/health",
3444
+ "/api/group/",
3445
+ "/api/telegram/",
3446
+ "/assets/",
3447
+ "/brand/",
3448
+ "/agent-assets/",
3449
+ "/generated/",
3450
+ "/g/",
3451
+ "/sites/"
3452
+ ];
3453
+ var PUBLIC_ALLOWED_EXACT = ["/favicon.ico", "/brand-defaults.css"];
3454
+ function isPublicPathAllowed(path) {
3455
+ if (path === "/") return true;
3456
+ if (PUBLIC_ALLOWED_EXACT.includes(path)) return true;
3457
+ if (PUBLIC_ALLOWED_PREFIXES.some((prefix) => path.startsWith(prefix))) return true;
3458
+ return AGENT_SLUG_PATTERN.test(path);
3459
+ }
3460
+ function isOperatorHost(host, operatorDomains2) {
3461
+ return operatorDomains2.has(host);
3462
+ }
3463
+ function classifyHost(host, operatorDomains2, isPublicHost) {
3464
+ if (operatorDomains2.has(host)) return "operator";
3465
+ if (isPublicHost(host)) return "public";
3466
+ return "admin";
3467
+ }
3468
+
3469
+ // server/operator-domains-reader.ts
3470
+ import { watchFile } from "fs";
3471
+
3472
+ // app/lib/operator-domains.ts
3473
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
3474
+ import { dirname as dirname2, resolve as resolve3 } from "path";
3475
+ var OPERATOR_DOMAINS_PATH = resolve3(MAXY_DIR, "operator-domains.json");
3476
+ function loadOperatorDomains() {
3477
+ if (!existsSync3(OPERATOR_DOMAINS_PATH)) return /* @__PURE__ */ new Set();
3478
+ try {
3479
+ const parsed = JSON.parse(readFileSync3(OPERATOR_DOMAINS_PATH, "utf-8"));
3480
+ if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
3481
+ return new Set(parsed.filter((h) => typeof h === "string"));
3482
+ } catch {
3483
+ return /* @__PURE__ */ new Set();
3484
+ }
3485
+ }
3486
+
3487
+ // server/operator-domains-reader.ts
3488
+ var operatorDomains = loadOperatorDomains();
3489
+ if (operatorDomains.size > 0) {
3490
+ console.log(
3491
+ `[operator-domains] loaded ${operatorDomains.size} operator domain(s): ${[...operatorDomains].join(", ")}`
3492
+ );
3493
+ }
3494
+ watchFile(OPERATOR_DOMAINS_PATH, { interval: 2e3 }, () => {
3495
+ operatorDomains = loadOperatorDomains();
3496
+ console.log(
3497
+ `[operator-domains] reloaded ${operatorDomains.size} operator domain(s): ${[...operatorDomains].join(", ")}`
3498
+ );
3499
+ });
3500
+ function getOperatorDomains() {
3501
+ return operatorDomains;
3502
+ }
3503
+
3435
3504
  // app/lib/claude-agent/account.ts
3436
- import { resolve as resolve3 } from "path";
3437
- import { readFileSync as readFileSync4, readdirSync, existsSync as existsSync4, statSync } from "fs";
3505
+ import { resolve as resolve4 } from "path";
3506
+ import { readFileSync as readFileSync5, readdirSync, existsSync as existsSync5, statSync } from "fs";
3438
3507
 
3439
3508
  // ../lib/brand-templating/src/index.ts
3440
3509
  import { join as join2 } from "path";
3441
- import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
3510
+ import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
3442
3511
  var PLACEHOLDER = "{{productName}}";
3443
3512
  var cachedProductName = null;
3444
3513
  function brandJsonPath() {
@@ -3453,12 +3522,12 @@ function brandJsonPath() {
3453
3522
  function getBrandProductName() {
3454
3523
  if (cachedProductName !== null) return cachedProductName;
3455
3524
  const path = brandJsonPath();
3456
- if (!existsSync3(path)) {
3525
+ if (!existsSync4(path)) {
3457
3526
  throw new Error(`[skill-loader] brand.json missing at ${path}`);
3458
3527
  }
3459
3528
  let parsed;
3460
3529
  try {
3461
- parsed = JSON.parse(readFileSync3(path, "utf-8"));
3530
+ parsed = JSON.parse(readFileSync4(path, "utf-8"));
3462
3531
  } catch (err) {
3463
3532
  throw new Error(
3464
3533
  `[skill-loader] brand.json unreadable at ${path}: ${err instanceof Error ? err.message : String(err)}`
@@ -3493,9 +3562,9 @@ function substituteBrandPlaceholders(content, sourcePath) {
3493
3562
  }
3494
3563
 
3495
3564
  // app/lib/claude-agent/account.ts
3496
- var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve3(process.cwd(), "..");
3497
- var ACCOUNTS_DIR = resolve3(PLATFORM_ROOT2, "..", "data/accounts");
3498
- if (!existsSync4(PLATFORM_ROOT2)) {
3565
+ var PLATFORM_ROOT2 = process.env.MAXY_PLATFORM_ROOT ?? resolve4(process.cwd(), "..");
3566
+ var ACCOUNTS_DIR = resolve4(PLATFORM_ROOT2, "..", "data/accounts");
3567
+ if (!existsSync5(PLATFORM_ROOT2)) {
3499
3568
  throw new Error(
3500
3569
  `PLATFORM_ROOT does not exist: ${PLATFORM_ROOT2}
3501
3570
  Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the platform directory.`
@@ -3503,15 +3572,15 @@ Set the MAXY_PLATFORM_ROOT environment variable to the absolute path of the plat
3503
3572
  }
3504
3573
  var _stubDirsLoggedThisBoot = /* @__PURE__ */ new Set();
3505
3574
  function listValidAccounts() {
3506
- if (!existsSync4(ACCOUNTS_DIR)) return [];
3575
+ if (!existsSync5(ACCOUNTS_DIR)) return [];
3507
3576
  const out = [];
3508
3577
  const entries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true });
3509
3578
  for (const entry of entries) {
3510
3579
  if (!entry.isDirectory()) continue;
3511
3580
  if (entry.name.startsWith(".")) continue;
3512
- const accountDir = resolve3(ACCOUNTS_DIR, entry.name);
3513
- const configPath = resolve3(accountDir, "account.json");
3514
- if (!existsSync4(configPath)) {
3581
+ const accountDir = resolve4(ACCOUNTS_DIR, entry.name);
3582
+ const configPath = resolve4(accountDir, "account.json");
3583
+ if (!existsSync5(configPath)) {
3515
3584
  if (!_stubDirsLoggedThisBoot.has(entry.name)) {
3516
3585
  console.error(
3517
3586
  `[platform] accounts-state STUB-DIR id=${entry.name} \u2014 onboarding leak; remove or repair`
@@ -3522,7 +3591,7 @@ function listValidAccounts() {
3522
3591
  }
3523
3592
  let config;
3524
3593
  try {
3525
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
3594
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
3526
3595
  } catch {
3527
3596
  console.error(
3528
3597
  `[platform] accounts-state CORRUPT-JSON id=${entry.name} \u2014 account.json failed to parse; treating as stub`
@@ -3534,11 +3603,11 @@ function listValidAccounts() {
3534
3603
  return out;
3535
3604
  }
3536
3605
  function resolveAccount() {
3537
- if (!existsSync4(ACCOUNTS_DIR)) return null;
3606
+ if (!existsSync5(ACCOUNTS_DIR)) return null;
3538
3607
  let usersJsonUserId = null;
3539
- if (existsSync4(USERS_FILE)) {
3608
+ if (existsSync5(USERS_FILE)) {
3540
3609
  try {
3541
- const raw2 = readFileSync4(USERS_FILE, "utf-8").trim();
3610
+ const raw2 = readFileSync5(USERS_FILE, "utf-8").trim();
3542
3611
  if (raw2) {
3543
3612
  const users = JSON.parse(raw2);
3544
3613
  if (users.length > 0) {
@@ -3552,9 +3621,9 @@ function resolveAccount() {
3552
3621
  let fallback = null;
3553
3622
  for (const entry of entries) {
3554
3623
  if (!entry.isDirectory()) continue;
3555
- const configPath = resolve3(ACCOUNTS_DIR, entry.name, "account.json");
3556
- if (!existsSync4(configPath)) continue;
3557
- const raw2 = readFileSync4(configPath, "utf-8");
3624
+ const configPath = resolve4(ACCOUNTS_DIR, entry.name, "account.json");
3625
+ if (!existsSync5(configPath)) continue;
3626
+ const raw2 = readFileSync5(configPath, "utf-8");
3558
3627
  let config;
3559
3628
  try {
3560
3629
  config = JSON.parse(raw2);
@@ -3569,7 +3638,7 @@ function resolveAccount() {
3569
3638
  }
3570
3639
  const result = {
3571
3640
  accountId: config.accountId,
3572
- accountDir: resolve3(ACCOUNTS_DIR, entry.name),
3641
+ accountDir: resolve4(ACCOUNTS_DIR, entry.name),
3573
3642
  config
3574
3643
  };
3575
3644
  if (usersJsonUserId && config.admins?.some((a) => a.userId === usersJsonUserId)) {
@@ -3587,9 +3656,9 @@ function resolveAccount() {
3587
3656
  return fallback;
3588
3657
  }
3589
3658
  function readAgentFile(accountDir, agentName, filename) {
3590
- const filePath = resolve3(accountDir, "agents", agentName, filename);
3591
- if (!existsSync4(filePath)) return null;
3592
- const raw2 = readFileSync4(filePath, "utf-8");
3659
+ const filePath = resolve4(accountDir, "agents", agentName, filename);
3660
+ if (!existsSync5(filePath)) return null;
3661
+ const raw2 = readFileSync5(filePath, "utf-8");
3593
3662
  if (filename.endsWith(".md")) {
3594
3663
  return substituteBrandPlaceholders(raw2, filePath);
3595
3664
  }
@@ -3611,14 +3680,14 @@ function validateAgentSlug(slug) {
3611
3680
  return true;
3612
3681
  }
3613
3682
  function resolveDefaultAgentSlug(accountDir) {
3614
- const configPath = resolve3(accountDir, "account.json");
3615
- if (!existsSync4(configPath)) {
3683
+ const configPath = resolve4(accountDir, "account.json");
3684
+ if (!existsSync5(configPath)) {
3616
3685
  console.error("[agent-resolve] account.json not found \u2014 cannot resolve defaultAgent");
3617
3686
  return null;
3618
3687
  }
3619
3688
  let config;
3620
3689
  try {
3621
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
3690
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
3622
3691
  } catch (err) {
3623
3692
  console.error("[agent-resolve] failed to read account.json:", err);
3624
3693
  return null;
@@ -3627,8 +3696,8 @@ function resolveDefaultAgentSlug(accountDir) {
3627
3696
  console.error("[agent-resolve] defaultAgent not configured in account.json \u2014 set it via the connect-whatsapp skill");
3628
3697
  return null;
3629
3698
  }
3630
- const agentConfigPath = resolve3(accountDir, "agents", config.defaultAgent, "config.json");
3631
- if (!existsSync4(agentConfigPath)) {
3699
+ const agentConfigPath = resolve4(accountDir, "agents", config.defaultAgent, "config.json");
3700
+ if (!existsSync5(agentConfigPath)) {
3632
3701
  console.error(`[agent-resolve] defaultAgent="${config.defaultAgent}" has no config.json at ${agentConfigPath}`);
3633
3702
  return null;
3634
3703
  }
@@ -3684,23 +3753,23 @@ function resolveAgentConfig(accountDir, agentName) {
3684
3753
  }
3685
3754
  let knowledge = null;
3686
3755
  let knowledgeBaked = false;
3687
- const agentDir = resolve3(accountDir, "agents", agentName);
3688
- const knowledgePath = resolve3(agentDir, "KNOWLEDGE.md");
3689
- const summaryPath = resolve3(agentDir, "KNOWLEDGE-SUMMARY.md");
3690
- const hasKnowledge = existsSync4(knowledgePath);
3691
- const hasSummary = existsSync4(summaryPath);
3756
+ const agentDir = resolve4(accountDir, "agents", agentName);
3757
+ const knowledgePath = resolve4(agentDir, "KNOWLEDGE.md");
3758
+ const summaryPath = resolve4(agentDir, "KNOWLEDGE-SUMMARY.md");
3759
+ const hasKnowledge = existsSync5(knowledgePath);
3760
+ const hasSummary = existsSync5(summaryPath);
3692
3761
  if (hasKnowledge && hasSummary) {
3693
3762
  const knowledgeMtime = statSync(knowledgePath).mtimeMs;
3694
3763
  const summaryMtime = statSync(summaryPath).mtimeMs;
3695
3764
  if (summaryMtime >= knowledgeMtime) {
3696
- knowledge = readFileSync4(summaryPath, "utf-8");
3765
+ knowledge = readFileSync5(summaryPath, "utf-8");
3697
3766
  } else {
3698
3767
  console.warn(`[agent-config] ${agentName}: KNOWLEDGE-SUMMARY.md is stale (KNOWLEDGE.md is newer) \u2014 using full knowledge`);
3699
- knowledge = readFileSync4(knowledgePath, "utf-8");
3768
+ knowledge = readFileSync5(knowledgePath, "utf-8");
3700
3769
  }
3701
3770
  knowledgeBaked = true;
3702
3771
  } else if (hasKnowledge) {
3703
- knowledge = readFileSync4(knowledgePath, "utf-8");
3772
+ knowledge = readFileSync5(knowledgePath, "utf-8");
3704
3773
  knowledgeBaked = true;
3705
3774
  }
3706
3775
  let budget = null;
@@ -3727,16 +3796,16 @@ function getDefaultAccountId() {
3727
3796
  return resolveAccount()?.accountId ?? null;
3728
3797
  }
3729
3798
  function resolveUserAccounts(userId) {
3730
- if (!existsSync4(ACCOUNTS_DIR)) return [];
3799
+ if (!existsSync5(ACCOUNTS_DIR)) return [];
3731
3800
  const results = [];
3732
3801
  const entries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true });
3733
3802
  for (const entry of entries) {
3734
3803
  if (!entry.isDirectory()) continue;
3735
- const configPath = resolve3(ACCOUNTS_DIR, entry.name, "account.json");
3736
- if (!existsSync4(configPath)) continue;
3804
+ const configPath = resolve4(ACCOUNTS_DIR, entry.name, "account.json");
3805
+ if (!existsSync5(configPath)) continue;
3737
3806
  let config;
3738
3807
  try {
3739
- config = JSON.parse(readFileSync4(configPath, "utf-8"));
3808
+ config = JSON.parse(readFileSync5(configPath, "utf-8"));
3740
3809
  } catch {
3741
3810
  console.error(`[session] account.json corrupt at ${configPath} \u2014 skipping`);
3742
3811
  continue;
@@ -3745,7 +3814,7 @@ function resolveUserAccounts(userId) {
3745
3814
  if (adminEntry) {
3746
3815
  results.push({
3747
3816
  accountId: config.accountId,
3748
- accountDir: resolve3(ACCOUNTS_DIR, entry.name),
3817
+ accountDir: resolve4(ACCOUNTS_DIR, entry.name),
3749
3818
  config,
3750
3819
  role: adminEntry.role
3751
3820
  });
@@ -3819,20 +3888,20 @@ function getSessionKeyBySessionId(_sessionId) {
3819
3888
  }
3820
3889
 
3821
3890
  // app/lib/claude-agent/plugin-manifest.ts
3822
- import { resolve as resolve4, join as join3 } from "path";
3891
+ import { resolve as resolve5, join as join3 } from "path";
3823
3892
  import {
3824
- readFileSync as readFileSync5,
3825
- writeFileSync as writeFileSync2,
3893
+ readFileSync as readFileSync6,
3894
+ writeFileSync as writeFileSync3,
3826
3895
  readdirSync as readdirSync2,
3827
- existsSync as existsSync5,
3896
+ existsSync as existsSync6,
3828
3897
  statSync as statSync2,
3829
3898
  rmSync
3830
3899
  } from "fs";
3831
3900
  import { createHash as createHash2 } from "crypto";
3832
3901
  function isMissingPluginDir(pluginDir) {
3833
- const pluginRoot = resolve4(PLATFORM_ROOT2, "plugins", pluginDir);
3834
- if (existsSync5(resolve4(pluginRoot, "PLUGIN.md"))) return false;
3835
- if (existsSync5(resolve4(pluginRoot, "mcp/dist/index.js"))) return false;
3902
+ const pluginRoot = resolve5(PLATFORM_ROOT2, "plugins", pluginDir);
3903
+ if (existsSync6(resolve5(pluginRoot, "PLUGIN.md"))) return false;
3904
+ if (existsSync6(resolve5(pluginRoot, "mcp/dist/index.js"))) return false;
3836
3905
  return true;
3837
3906
  }
3838
3907
  function findMissingPlugins(enabledPlugins) {
@@ -3840,10 +3909,10 @@ function findMissingPlugins(enabledPlugins) {
3840
3909
  return enabledPlugins.filter(isMissingPluginDir);
3841
3910
  }
3842
3911
  function readBundleSubPlugins(bundlePath) {
3843
- if (!existsSync5(bundlePath)) return [];
3912
+ if (!existsSync6(bundlePath)) return [];
3844
3913
  let raw2;
3845
3914
  try {
3846
- raw2 = readFileSync5(bundlePath, "utf-8");
3915
+ raw2 = readFileSync6(bundlePath, "utf-8");
3847
3916
  } catch {
3848
3917
  return [];
3849
3918
  }
@@ -3885,8 +3954,8 @@ function walkPremiumBundles() {
3885
3954
  return kept;
3886
3955
  }
3887
3956
  function walkPremiumBundlesOnDisk() {
3888
- const stagingRoot = resolve4(PLATFORM_ROOT2, "../premium-plugins");
3889
- if (!existsSync5(stagingRoot)) return [];
3957
+ const stagingRoot = resolve5(PLATFORM_ROOT2, "../premium-plugins");
3958
+ if (!existsSync6(stagingRoot)) return [];
3890
3959
  let entries;
3891
3960
  try {
3892
3961
  entries = readdirSync2(stagingRoot);
@@ -3896,7 +3965,7 @@ function walkPremiumBundlesOnDisk() {
3896
3965
  const result = [];
3897
3966
  for (const bundle of entries) {
3898
3967
  if (bundle.startsWith(".")) continue;
3899
- const bundleDir = resolve4(stagingRoot, bundle);
3968
+ const bundleDir = resolve5(stagingRoot, bundle);
3900
3969
  try {
3901
3970
  if (!statSync2(bundleDir).isDirectory()) continue;
3902
3971
  } catch {
@@ -3910,14 +3979,14 @@ function walkPremiumBundlesOnDisk() {
3910
3979
  function reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir) {
3911
3980
  const TAG = "[premium-auto-deliver]";
3912
3981
  for (const { bundle, subs } of bundles) {
3913
- const isBundle = existsSync5(join3(stagingRoot, bundle, "BUNDLE.md"));
3982
+ const isBundle = existsSync6(join3(stagingRoot, bundle, "BUNDLE.md"));
3914
3983
  for (const sub of subs) {
3915
- const premiumManifest = isBundle ? resolve4(stagingRoot, bundle, "plugins", sub, "PLUGIN.md") : resolve4(stagingRoot, bundle, "PLUGIN.md");
3916
- const flatDir = resolve4(pluginsDir, sub);
3917
- const flatManifest = resolve4(flatDir, "PLUGIN.md");
3918
- if (!existsSync5(premiumManifest) || !existsSync5(flatManifest)) continue;
3919
- const premiumSha = createHash2("sha256").update(readFileSync5(premiumManifest)).digest("hex");
3920
- const flatSha = createHash2("sha256").update(readFileSync5(flatManifest)).digest("hex");
3984
+ const premiumManifest = isBundle ? resolve5(stagingRoot, bundle, "plugins", sub, "PLUGIN.md") : resolve5(stagingRoot, bundle, "PLUGIN.md");
3985
+ const flatDir = resolve5(pluginsDir, sub);
3986
+ const flatManifest = resolve5(flatDir, "PLUGIN.md");
3987
+ if (!existsSync6(premiumManifest) || !existsSync6(flatManifest)) continue;
3988
+ const premiumSha = createHash2("sha256").update(readFileSync6(premiumManifest)).digest("hex");
3989
+ const flatSha = createHash2("sha256").update(readFileSync6(flatManifest)).digest("hex");
3921
3990
  if (isBundle) {
3922
3991
  if (premiumSha === flatSha) {
3923
3992
  try {
@@ -3943,24 +4012,24 @@ function reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir) {
3943
4012
  function autoDeliverPremiumPlugins() {
3944
4013
  const bundles = walkPremiumBundles();
3945
4014
  if (bundles.length === 0) return;
3946
- const stagingRoot = resolve4(PLATFORM_ROOT2, "../premium-plugins");
3947
- const pluginsDir = resolve4(PLATFORM_ROOT2, "plugins");
4015
+ const stagingRoot = resolve5(PLATFORM_ROOT2, "../premium-plugins");
4016
+ const pluginsDir = resolve5(PLATFORM_ROOT2, "plugins");
3948
4017
  reapDuplicateFlatPremiumSubs(bundles, stagingRoot, pluginsDir);
3949
4018
  }
3950
4019
  function reconcileEnabledPlugins(accountDir, config, accountId) {
3951
4020
  const TAG = "[premium-auto-deliver]";
3952
4021
  if (!accountDir || !config) return;
3953
4022
  const bundles = walkPremiumBundles();
3954
- const stagingRoot = resolve4(PLATFORM_ROOT2, "../premium-plugins");
4023
+ const stagingRoot = resolve5(PLATFORM_ROOT2, "../premium-plugins");
3955
4024
  const bundleNames = [];
3956
4025
  const allSubs = [];
3957
4026
  for (const { bundle, subs } of bundles) {
3958
4027
  bundleNames.push(bundle);
3959
4028
  const bundlePath = join3(stagingRoot, bundle, "BUNDLE.md");
3960
- const isBundle = existsSync5(bundlePath);
4029
+ const isBundle = existsSync6(bundlePath);
3961
4030
  for (const sub of subs) {
3962
- const subManifest = isBundle ? resolve4(stagingRoot, bundle, "plugins", sub, "PLUGIN.md") : resolve4(stagingRoot, bundle, "PLUGIN.md");
3963
- if (!existsSync5(subManifest)) continue;
4031
+ const subManifest = isBundle ? resolve5(stagingRoot, bundle, "plugins", sub, "PLUGIN.md") : resolve5(stagingRoot, bundle, "PLUGIN.md");
4032
+ if (!existsSync6(subManifest)) continue;
3964
4033
  allSubs.push(sub);
3965
4034
  }
3966
4035
  }
@@ -3977,12 +4046,12 @@ function reconcileEnabledPlugins(accountDir, config, accountId) {
3977
4046
  );
3978
4047
  if (added.length === 0) return;
3979
4048
  const merged = [...currentSet];
3980
- const configPath = resolve4(accountDir, "account.json");
4049
+ const configPath = resolve5(accountDir, "account.json");
3981
4050
  try {
3982
- const raw2 = readFileSync5(configPath, "utf-8");
4051
+ const raw2 = readFileSync6(configPath, "utf-8");
3983
4052
  const parsed = JSON.parse(raw2);
3984
4053
  parsed.enabledPlugins = merged;
3985
- writeFileSync2(configPath, JSON.stringify(parsed, null, 2) + "\n");
4054
+ writeFileSync3(configPath, JSON.stringify(parsed, null, 2) + "\n");
3986
4055
  config.enabledPlugins = merged;
3987
4056
  } catch (err) {
3988
4057
  console.error(`${TAG} enabled-stamp write failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -4008,12 +4077,12 @@ function cleanupLeakedPremiumSubs(accountDir, config, accountId) {
4008
4077
  else kept.push(name);
4009
4078
  }
4010
4079
  if (removed.length === 0) return;
4011
- const configPath = resolve4(accountDir, "account.json");
4080
+ const configPath = resolve5(accountDir, "account.json");
4012
4081
  try {
4013
- const raw2 = readFileSync5(configPath, "utf-8");
4082
+ const raw2 = readFileSync6(configPath, "utf-8");
4014
4083
  const parsed = JSON.parse(raw2);
4015
4084
  parsed.enabledPlugins = kept;
4016
- writeFileSync2(configPath, JSON.stringify(parsed, null, 2) + "\n");
4085
+ writeFileSync3(configPath, JSON.stringify(parsed, null, 2) + "\n");
4017
4086
  config.enabledPlugins = kept;
4018
4087
  console.log(`${TAG} cleanup accountId=${accountId ?? "unknown"} removed=[${removed.join(",")}]`);
4019
4088
  } catch (err) {
@@ -4061,15 +4130,15 @@ function requirePortEnv(envName, options = {}) {
4061
4130
  // app/lib/neo4j-store.ts
4062
4131
  import neo4j from "neo4j-driver";
4063
4132
  import { randomUUID } from "crypto";
4064
- import { readFileSync as readFileSync6, readdirSync as readdirSync3, existsSync as existsSync6, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4065
- import { resolve as resolve5 } from "path";
4066
- var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve5(process.cwd(), "..");
4133
+ import { readFileSync as readFileSync7, readdirSync as readdirSync3, existsSync as existsSync7, openSync, readSync, closeSync, statSync as statSync3 } from "fs";
4134
+ import { resolve as resolve6 } from "path";
4135
+ var PLATFORM_ROOT3 = process.env.MAXY_PLATFORM_ROOT ?? resolve6(process.cwd(), "..");
4067
4136
  var driver = null;
4068
4137
  function readPassword() {
4069
4138
  if (process.env.NEO4J_PASSWORD) return process.env.NEO4J_PASSWORD;
4070
- const passwordFile = resolve5(PLATFORM_ROOT3, "config/.neo4j-password");
4139
+ const passwordFile = resolve6(PLATFORM_ROOT3, "config/.neo4j-password");
4071
4140
  try {
4072
- return readFileSync6(passwordFile, "utf-8").trim();
4141
+ return readFileSync7(passwordFile, "utf-8").trim();
4073
4142
  } catch {
4074
4143
  throw new Error(
4075
4144
  `Neo4j password not found. Expected at ${passwordFile} or in NEO4J_PASSWORD env var.`
@@ -4387,8 +4456,8 @@ async function persistMessage(sessionId, role, content, accountId, tokens, creat
4387
4456
  const prev = persistMessageLocks.get(sessionId);
4388
4457
  const waited = prev !== void 0;
4389
4458
  let release;
4390
- const mine = new Promise((resolve6) => {
4391
- release = resolve6;
4459
+ const mine = new Promise((resolve7) => {
4460
+ release = resolve7;
4392
4461
  });
4393
4462
  const chained = (prev ?? Promise.resolve()).then(() => mine);
4394
4463
  persistMessageLocks.set(sessionId, chained);
@@ -5088,11 +5157,11 @@ function parsePluginProfileKeys(manifest) {
5088
5157
  return out;
5089
5158
  }
5090
5159
  function loadEnabledPluginProfileKeys(accountId) {
5091
- const accountFile = resolve5(PLATFORM_ROOT3, "..", "data/accounts", accountId, "account.json");
5092
- if (!existsSync6(accountFile)) return {};
5160
+ const accountFile = resolve6(PLATFORM_ROOT3, "..", "data/accounts", accountId, "account.json");
5161
+ if (!existsSync7(accountFile)) return {};
5093
5162
  let enabled;
5094
5163
  try {
5095
- const raw2 = readFileSync6(accountFile, "utf-8");
5164
+ const raw2 = readFileSync7(accountFile, "utf-8");
5096
5165
  const parsed = JSON.parse(raw2);
5097
5166
  enabled = Array.isArray(parsed.enabledPlugins) ? parsed.enabledPlugins.filter((p) => typeof p === "string") : [];
5098
5167
  } catch (err) {
@@ -5103,11 +5172,11 @@ function loadEnabledPluginProfileKeys(accountId) {
5103
5172
  }
5104
5173
  const merged = {};
5105
5174
  for (const pluginName of enabled) {
5106
- const manifestPath = resolve5(PLATFORM_ROOT3, "plugins", pluginName, "PLUGIN.md");
5107
- if (!existsSync6(manifestPath)) continue;
5175
+ const manifestPath = resolve6(PLATFORM_ROOT3, "plugins", pluginName, "PLUGIN.md");
5176
+ if (!existsSync7(manifestPath)) continue;
5108
5177
  let manifest;
5109
5178
  try {
5110
- manifest = readFileSync6(manifestPath, "utf-8");
5179
+ manifest = readFileSync7(manifestPath, "utf-8");
5111
5180
  } catch {
5112
5181
  continue;
5113
5182
  }
@@ -5352,22 +5421,22 @@ async function projectAgent(accountId, accountDir, slug) {
5352
5421
  );
5353
5422
  return;
5354
5423
  }
5355
- const agentDir = resolve5(accountDir, "agents", slug);
5356
- const configPath = resolve5(agentDir, "config.json");
5424
+ const agentDir = resolve6(accountDir, "agents", slug);
5425
+ const configPath = resolve6(agentDir, "config.json");
5357
5426
  let config;
5358
5427
  let presentRoles = [];
5359
5428
  try {
5360
- if (!existsSync6(configPath)) {
5429
+ if (!existsSync7(configPath)) {
5361
5430
  console.error(
5362
5431
  `[agent-graph] project FAILED slug=${slug} account=${account8} error="config.json missing at ${configPath}"`
5363
5432
  );
5364
5433
  return;
5365
5434
  }
5366
- config = JSON.parse(readFileSync6(configPath, "utf-8"));
5435
+ config = JSON.parse(readFileSync7(configPath, "utf-8"));
5367
5436
  for (const { filename, role } of AGENT_FILE_ROLES) {
5368
- const filePath = resolve5(agentDir, filename);
5369
- if (!existsSync6(filePath)) continue;
5370
- const body = readFileSync6(filePath, "utf-8");
5437
+ const filePath = resolve6(agentDir, filename);
5438
+ if (!existsSync7(filePath)) continue;
5439
+ const body = readFileSync7(filePath, "utf-8");
5371
5440
  presentRoles.push({ role, body, edge: ROLE_TO_EDGE[role] });
5372
5441
  }
5373
5442
  } catch (err) {
@@ -5650,7 +5719,14 @@ export {
5650
5719
  renderLoginPage,
5651
5720
  canAccessAdmin,
5652
5721
  parseCookieValue,
5722
+ AGENT_SLUG_PATTERN,
5653
5723
  SYSTEM_PATH_SLUGS,
5724
+ PUBLIC_ALLOWED_PREFIXES,
5725
+ PUBLIC_ALLOWED_EXACT,
5726
+ isPublicPathAllowed,
5727
+ isOperatorHost,
5728
+ classifyHost,
5729
+ getOperatorDomains,
5654
5730
  PLATFORM_ROOT2 as PLATFORM_ROOT,
5655
5731
  ACCOUNTS_DIR,
5656
5732
  listValidAccounts,
@@ -6,7 +6,9 @@ import {
6
6
  canAccessAdmin,
7
7
  clientIpMiddleware,
8
8
  describeRemoteSession,
9
+ getOperatorDomains,
9
10
  getRequestListener,
11
+ isOperatorHost,
10
12
  newCorrId,
11
13
  parseCookieValue,
12
14
  requireAdminCookie,
@@ -14,7 +16,7 @@ import {
14
16
  sanitizeClientCorrId,
15
17
  vncLog,
16
18
  websockifyLog
17
- } from "./chunk-7H4KMTMC.js";
19
+ } from "./chunk-JHSF5VPE.js";
18
20
  import "./chunk-PFF6I7KP.js";
19
21
 
20
22
  // server/edge.ts
@@ -46,6 +48,7 @@ function attachVncWsProxy(server2, opts) {
46
48
  try {
47
49
  handleUpgrade(req, clientSocket, head, {
48
50
  isPublicHost: opts.isPublicHost,
51
+ isOperatorHost: opts.isOperatorHost ?? (() => false),
49
52
  upstreamHost,
50
53
  upstreamPort,
51
54
  brand
@@ -143,6 +146,19 @@ function handleUpgrade(req, clientSocket, head, opts) {
143
146
  writeStatusAndDestroy(clientSocket, 403, "Forbidden");
144
147
  return;
145
148
  }
149
+ if (opts.isOperatorHost(originHost)) {
150
+ vncLog("ws-upgrade", {
151
+ corrId,
152
+ clientCorrId: clientCorrId ?? null,
153
+ decision: "rejected",
154
+ reason: "origin-operator-host",
155
+ origin_host: originHost,
156
+ host: hostHeader,
157
+ ip: remote
158
+ });
159
+ writeStatusAndDestroy(clientSocket, 403, "Forbidden");
160
+ return;
161
+ }
146
162
  vncLog("ws-upgrade", {
147
163
  corrId,
148
164
  clientCorrId: clientCorrId ?? null,
@@ -795,6 +811,8 @@ server.keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT ?? "61000", 10
795
811
  server.headersTimeout = server.keepAliveTimeout + 1e3;
796
812
  attachVncWsProxy(server, {
797
813
  isPublicHost,
814
+ // Task 829 — deny VNC on operator hosts (operator shell has no /browser).
815
+ isOperatorHost: (h) => isOperatorHost(h, getOperatorDomains()),
798
816
  upstreamHost: WEBSOCKIFY_HOST,
799
817
  upstreamPort: WEBSOCKIFY_PORT2,
800
818
  brand: BRAND.productName