@rubytech/create-maxy-code 0.1.246 → 0.1.248

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 (168) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +3 -3
  3. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  4. package/payload/platform/plugins/admin/PLUGIN.md +4 -1
  5. package/payload/platform/plugins/admin/hooks/__tests__/pin-identity-gate.test.sh +96 -0
  6. package/payload/platform/plugins/admin/hooks/pin-identity-gate.sh +136 -0
  7. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts +2 -0
  8. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.d.ts.map +1 -0
  9. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js +34 -0
  10. package/payload/platform/plugins/admin/mcp/dist/__tests__/admin-identity-authenticate.test.js.map +1 -0
  11. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts +2 -0
  12. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.d.ts.map +1 -0
  13. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js +50 -0
  14. package/payload/platform/plugins/admin/mcp/dist/__tests__/skill-no-prescribed-role.test.js.map +1 -0
  15. package/payload/platform/plugins/admin/mcp/dist/index.js +8 -0
  16. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  17. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts +6 -0
  18. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.d.ts.map +1 -0
  19. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js +32 -0
  20. package/payload/platform/plugins/admin/mcp/dist/tools/admin-identity-authenticate.js.map +1 -0
  21. package/payload/platform/plugins/admin/skills/investigate/SKILL.md +34 -17
  22. package/payload/platform/plugins/admin/skills/public-agent-manager/SKILL.md +15 -8
  23. package/payload/platform/plugins/admin/skills/publish-site/SKILL.md +5 -0
  24. package/payload/platform/plugins/admin/skills/unzip-attachment/SKILL.md +5 -0
  25. package/payload/platform/plugins/admin/skills/update-knowledge/SKILL.md +5 -0
  26. package/payload/platform/plugins/docs/references/admin-identity-gate.md +81 -0
  27. package/payload/platform/plugins/memory/skills/conversation-archive-enrich/SKILL.md +1 -0
  28. package/payload/platform/plugins/memory/skills/conversational-memory/SKILL.md +5 -0
  29. package/payload/platform/plugins/workflows/skills/workflow-manager/SKILL.md +5 -0
  30. package/payload/platform/scripts/check-skill-frontmatter.mjs +139 -0
  31. package/payload/platform/scripts/setup-account.sh +5 -16
  32. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts +39 -0
  33. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.d.ts.map +1 -0
  34. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js +133 -0
  35. package/payload/platform/services/claude-session-manager/dist/admin-identity-audit.js.map +1 -0
  36. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  37. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +1 -0
  38. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  39. package/payload/platform/services/claude-session-manager/dist/index.js +29 -0
  40. package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
  41. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts +28 -0
  42. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -0
  43. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +99 -0
  44. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -0
  45. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  46. package/payload/server/{chunk-JMEX5NRX.js → chunk-UEIA5YUG.js} +30 -18
  47. package/payload/server/maxy-edge.js +7 -5
  48. package/payload/server/public/assets/{AdminShell-D_eg2QKE.js → AdminShell-892Jy_rs.js} +1 -1
  49. package/payload/server/public/assets/AdminShell-qc_xy7Az.css +1 -0
  50. package/payload/server/public/assets/{Checkbox-CfE7p1Tv.js → Checkbox-Bc2QzX9b.js} +1 -1
  51. package/payload/server/public/assets/{admin-DfeXRW1m.js → admin-D3K13ndi.js} +1 -1
  52. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-DvDVmNbJ.js → architectureDiagram-Q4EWVU46-c09loTER.js} +1 -1
  53. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-CVCQHVcw.js → blockDiagram-DXYQGD6D-Cjdeyoq1.js} +1 -1
  54. package/payload/server/public/assets/brand-D0gNihp7.css +1 -0
  55. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DancbaY-.js → c4Diagram-AHTNJAMY-NY6Wlzo2.js} +1 -1
  56. package/payload/server/public/assets/channel-B1IT7to2.js +1 -0
  57. package/payload/server/public/assets/chunk-336JU56O-CdKRCIeE.js +2 -0
  58. package/payload/server/public/assets/{chunk-426QAEUC-Dqt07sZz.js → chunk-426QAEUC-BybuQ3Ve.js} +1 -1
  59. package/payload/server/public/assets/{chunk-4TB4RGXK-Bdm77ygl.js → chunk-4TB4RGXK-BXpto3yW.js} +1 -1
  60. package/payload/server/public/assets/{chunk-5FUZZQ4R-nDbgOH1b.js → chunk-5FUZZQ4R-C403gCUk.js} +1 -1
  61. package/payload/server/public/assets/{chunk-5PVQY5BW-mYip6Ias.js → chunk-5PVQY5BW-CjVzXQEp.js} +1 -1
  62. package/payload/server/public/assets/{chunk-EDXVE4YY-DubyAY7F.js → chunk-EDXVE4YY-DJcJAsAg.js} +1 -1
  63. package/payload/server/public/assets/{chunk-ENJZ2VHE-DIa8CJbF.js → chunk-ENJZ2VHE-CFDNvYu1.js} +1 -1
  64. package/payload/server/public/assets/{chunk-ICPOFSXX-bKmK-tZo.js → chunk-ICPOFSXX-ecLOxGhL.js} +1 -1
  65. package/payload/server/public/assets/{chunk-OYMX7WX6-KcUQTwd8.js → chunk-OYMX7WX6-B7MW66KB.js} +1 -1
  66. package/payload/server/public/assets/{chunk-U2HBQHQK-3p-zDDFG.js → chunk-U2HBQHQK-BMawmsyk.js} +1 -1
  67. package/payload/server/public/assets/{chunk-X2U36JSP-C5F60GoO.js → chunk-X2U36JSP-CT6g7pno.js} +1 -1
  68. package/payload/server/public/assets/{chunk-YZCP3GAM-CEhP6XMC.js → chunk-YZCP3GAM-xeAluiAH.js} +1 -1
  69. package/payload/server/public/assets/{chunk-ZZ45TVLE-Bac24FOS.js → chunk-ZZ45TVLE-BRN9qUC5.js} +1 -1
  70. package/payload/server/public/assets/classDiagram-6PBFFD2Q-rjCize6i.js +1 -0
  71. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BORWOUt0.js +1 -0
  72. package/payload/server/public/assets/clone-Csqv5U6T.js +1 -0
  73. package/payload/server/public/assets/{dagre-xntZVDsO.js → dagre-DTjePoco.js} +1 -1
  74. package/payload/server/public/assets/{dagre-KV5264BT-DqGsPaYJ.js → dagre-KV5264BT-DHBkRke4.js} +1 -1
  75. package/payload/server/public/assets/{data-JoiWCmz6.js → data-Br-pdljK.js} +1 -1
  76. package/payload/server/public/assets/{diagram-5BDNPKRD-Co8NC28s.js → diagram-5BDNPKRD-BIq1-idL.js} +1 -1
  77. package/payload/server/public/assets/{diagram-G4DWMVQ6-HewQArEf.js → diagram-G4DWMVQ6-BsIUDzV6.js} +1 -1
  78. package/payload/server/public/assets/{diagram-MMDJMWI5-s6NqURmM.js → diagram-MMDJMWI5-CgHSri2i.js} +1 -1
  79. package/payload/server/public/assets/{diagram-TYMM5635-CAof9UmL.js → diagram-TYMM5635-Ce2Wh9ZX.js} +1 -1
  80. package/payload/server/public/assets/{erDiagram-SMLLAGMA-CUqIICFD.js → erDiagram-SMLLAGMA-BU0Kh6OQ.js} +1 -1
  81. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-DN1n7xgU.js → flowDiagram-DWJPFMVM-B0N06MF7.js} +1 -1
  82. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-sGoWsEWZ.js → ganttDiagram-T4ZO3ILL-BVbx4ARZ.js} +1 -1
  83. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-Dz_cZL1Q.js → gitGraphDiagram-UUTBAWPF-C-xRJ94t.js} +1 -1
  84. package/payload/server/public/assets/{graph-DmOvqjTa.js → graph-g48ZcA5M.js} +1 -1
  85. package/payload/server/public/assets/{graph-labels-iPC15OmD.js → graph-labels-BYH-IPCb.js} +1 -1
  86. package/payload/server/public/assets/{graphlib-eZzlPtt9.js → graphlib-YmNcoMjY.js} +1 -1
  87. package/payload/server/public/assets/{infoDiagram-42DDH7IO-DFMOgYMn.js → infoDiagram-42DDH7IO-Di6oPQ_-.js} +1 -1
  88. package/payload/server/public/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
  89. package/payload/server/public/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  90. package/payload/server/public/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  91. package/payload/server/public/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
  92. package/payload/server/public/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  93. package/payload/server/public/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
  94. package/payload/server/public/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  95. package/payload/server/public/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
  96. package/payload/server/public/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  97. package/payload/server/public/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
  98. package/payload/server/public/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  99. package/payload/server/public/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
  100. package/payload/server/public/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  101. package/payload/server/public/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
  102. package/payload/server/public/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
  103. package/payload/server/public/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  104. package/payload/server/public/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  105. package/payload/server/public/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  106. package/payload/server/public/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  107. package/payload/server/public/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  108. package/payload/server/public/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
  109. package/payload/server/public/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  110. package/payload/server/public/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
  111. package/payload/server/public/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  112. package/payload/server/public/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
  113. package/payload/server/public/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  114. package/payload/server/public/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  115. package/payload/server/public/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
  116. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-C9AGnqZn.js → ishikawaDiagram-UXIWVN3A-DTrq54yC.js} +1 -1
  117. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-C4-y1Faf.js → journeyDiagram-VCZTEJTY-OZZZMrFX.js} +1 -1
  118. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DIynz-Si.js → kanban-definition-6JOO6SKY--w-IP9pN.js} +1 -1
  119. package/payload/server/public/assets/{line-CzaIC22F.js → line-Ckeulv5T.js} +1 -1
  120. package/payload/server/public/assets/{mermaid-parser.core-Dcdye_D2.js → mermaid-parser.core-CVRAxYRD.js} +1 -1
  121. package/payload/server/public/assets/{mermaid.core-HWxg8X0R.js → mermaid.core-B-mE18I1.js} +3 -3
  122. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-ve0J3SsF.js → mindmap-definition-QFDTVHPH-Bm8mDicL.js} +1 -1
  123. package/payload/server/public/assets/newsreader-latin-300-normal-AOSWdb_s.woff +0 -0
  124. package/payload/server/public/assets/newsreader-latin-300-normal-FGBQ0wlI.woff2 +0 -0
  125. package/payload/server/public/assets/newsreader-latin-400-normal-BFBkh4jY.woff2 +0 -0
  126. package/payload/server/public/assets/newsreader-latin-400-normal-gRTjlS2D.woff +0 -0
  127. package/payload/server/public/assets/newsreader-latin-500-normal-B66TYsaK.woff2 +0 -0
  128. package/payload/server/public/assets/newsreader-latin-500-normal-DFwuUcdu.woff +0 -0
  129. package/payload/server/public/assets/newsreader-latin-ext-300-normal-CFtw49Zd.woff +0 -0
  130. package/payload/server/public/assets/newsreader-latin-ext-300-normal-DRMzurxT.woff2 +0 -0
  131. package/payload/server/public/assets/newsreader-latin-ext-400-normal-DYA1XoQK.woff +0 -0
  132. package/payload/server/public/assets/newsreader-latin-ext-400-normal-svq1FPys.woff2 +0 -0
  133. package/payload/server/public/assets/newsreader-latin-ext-500-normal-BNHmvKvI.woff2 +0 -0
  134. package/payload/server/public/assets/newsreader-latin-ext-500-normal-CZruMFou.woff +0 -0
  135. package/payload/server/public/assets/newsreader-vietnamese-300-normal-CsrIkm-V.woff +0 -0
  136. package/payload/server/public/assets/newsreader-vietnamese-300-normal-D3VHEe81.woff2 +0 -0
  137. package/payload/server/public/assets/newsreader-vietnamese-400-normal-BekUZro8.woff +0 -0
  138. package/payload/server/public/assets/newsreader-vietnamese-400-normal-DdKr49mV.woff2 +0 -0
  139. package/payload/server/public/assets/newsreader-vietnamese-500-normal-BEAbKU8A.woff +0 -0
  140. package/payload/server/public/assets/newsreader-vietnamese-500-normal-CL6a8tp2.woff2 +0 -0
  141. package/payload/server/public/assets/{pieDiagram-DEJITSTG-DdiZi8Iv.js → pieDiagram-DEJITSTG-BCmRLgGO.js} +1 -1
  142. package/payload/server/public/assets/{public-DbW8Up_b.js → public-DknO-g9S.js} +5 -5
  143. package/payload/server/public/assets/public-vnj7OhQj.css +1 -0
  144. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-CvNd8CMM.js → quadrantDiagram-34T5L4WZ-CniTIUTm.js} +1 -1
  145. package/payload/server/public/assets/{requirementDiagram-MS252O5E-8LsItfG7.js → requirementDiagram-MS252O5E-CoxBSj9M.js} +1 -1
  146. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-CoXsggQF.js → sankeyDiagram-XADWPNL6-BjS-4jzq.js} +1 -1
  147. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-CxtIGmey.js → sequenceDiagram-FGHM5R23-B9jVOnPR.js} +1 -1
  148. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-C2zgoy3P.js → stateDiagram-FHFEXIEX-BvOQPzP8.js} +1 -1
  149. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-v4ND10uR.js +1 -0
  150. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-DQ_J-0lx.js → timeline-definition-GMOUNBTQ-CdfgWLo1.js} +1 -1
  151. package/payload/server/public/assets/{useSelectionMode-BbLqtKTJ.js → useSelectionMode-DwsyptOw.js} +1 -1
  152. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-B7Y7Cw54.js → vennDiagram-DHZGUBPP-JCgpIbj-.js} +1 -1
  153. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-1XkR1IH-.js → wardleyDiagram-NUSXRM2D-Dei3VqHo.js} +1 -1
  154. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-CcatDElf.js → xychartDiagram-5P7HB3ND-DUtIyoIb.js} +1 -1
  155. package/payload/server/public/brand-defaults.css +3 -3
  156. package/payload/server/public/data.html +6 -5
  157. package/payload/server/public/graph.html +7 -6
  158. package/payload/server/public/index.html +7 -6
  159. package/payload/server/public/public.html +7 -6
  160. package/payload/server/server.js +290 -157
  161. package/payload/server/public/assets/brand-hVIfBy3s.css +0 -1
  162. package/payload/server/public/assets/channel-t5srld-W.js +0 -1
  163. package/payload/server/public/assets/chunk-336JU56O-DL5O4-qf.js +0 -2
  164. package/payload/server/public/assets/classDiagram-6PBFFD2Q-197c9FtA.js +0 -1
  165. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-C5RIsovf.js +0 -1
  166. package/payload/server/public/assets/clone-BJPTkE0R.js +0 -1
  167. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-C3CpI3Q7.js +0 -1
  168. /package/payload/server/public/assets/{brand-Dmpzr6Qq.js → brand-CcN3dELF.js} +0 -0
@@ -14,6 +14,7 @@ import {
14
14
  MAXY_DIR,
15
15
  PLATFORM_ROOT,
16
16
  RFB_PORT,
17
+ SYSTEM_PATH_SLUGS,
17
18
  USERS_FILE,
18
19
  VISITOR_TOKEN_SECRET_FILE,
19
20
  VNC_DISPLAY,
@@ -91,7 +92,7 @@ import {
91
92
  vncLog,
92
93
  walkPremiumBundles,
93
94
  writeAdminUserAndPerson
94
- } from "./chunk-JMEX5NRX.js";
95
+ } from "./chunk-UEIA5YUG.js";
95
96
  import {
96
97
  __commonJS,
97
98
  __toESM
@@ -600,6 +601,46 @@ var require_dist2 = __commonJS({
600
601
  }
601
602
  });
602
603
 
604
+ // ../lib/require-port-env/dist/index.js
605
+ var require_dist3 = __commonJS({
606
+ "../lib/require-port-env/dist/index.js"(exports) {
607
+ "use strict";
608
+ Object.defineProperty(exports, "__esModule", { value: true });
609
+ exports.MissingPortEnvError = void 0;
610
+ exports.requirePortEnv = requirePortEnv3;
611
+ var MissingPortEnvError = class extends Error {
612
+ envName;
613
+ tag;
614
+ failLine;
615
+ constructor(envName, tag, failLine, message) {
616
+ super(message);
617
+ this.name = "MissingPortEnvError";
618
+ this.envName = envName;
619
+ this.tag = tag;
620
+ this.failLine = failLine;
621
+ }
622
+ };
623
+ exports.MissingPortEnvError = MissingPortEnvError;
624
+ var VALID_PORT_MIN = 1;
625
+ var VALID_PORT_MAX = 65535;
626
+ function requirePortEnv3(envName, options = {}) {
627
+ const tag = options.tag ?? "port-env";
628
+ const failLine = options.failLine ?? "missing-port-env";
629
+ const raw = process.env[envName];
630
+ if (raw === void 0 || raw === "") {
631
+ const msg = `[${tag}] ${failLine} reason=missing-env env=${envName}`;
632
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
633
+ }
634
+ const parsed = Number.parseInt(raw, 10);
635
+ if (!Number.isInteger(parsed) || parsed < VALID_PORT_MIN || parsed > VALID_PORT_MAX || String(parsed) !== raw.trim()) {
636
+ const msg = `[${tag}] ${failLine} reason=invalid-port-env env=${envName} value=${JSON.stringify(raw)}`;
637
+ throw new MissingPortEnvError(envName, tag, failLine, msg);
638
+ }
639
+ return parsed;
640
+ }
641
+ }
642
+ });
643
+
603
644
  // node_modules/hono/dist/utils/mime.js
604
645
  var getMimeType = (filename, mimes = baseMimes) => {
605
646
  const regexp = /\.([a-zA-Z0-9]+?)$/;
@@ -4777,6 +4818,7 @@ app2.post("/", async (c) => {
4777
4818
  let isGreeting = false;
4778
4819
  let requestFormat;
4779
4820
  let attachmentCount = 0;
4821
+ let requestedSlug;
4780
4822
  if (contentType.startsWith("multipart/form-data")) {
4781
4823
  requestFormat = "multipart";
4782
4824
  let formData;
@@ -4787,6 +4829,7 @@ app2.post("/", async (c) => {
4787
4829
  }
4788
4830
  message = formData.get("message") ?? "";
4789
4831
  session_key = formData.get("session_key") ?? "";
4832
+ requestedSlug = formData.get("agent") || void 0;
4790
4833
  userTimestamp = formData.get("timestamp") || void 0;
4791
4834
  if (!session_key) {
4792
4835
  return c.json({ error: "session_key required" }, 400);
@@ -4844,6 +4887,7 @@ app2.post("/", async (c) => {
4844
4887
  return c.json({ error: "Invalid request" }, 400);
4845
4888
  }
4846
4889
  session_key = body.session_key;
4890
+ requestedSlug = typeof body.agent === "string" ? body.agent : void 0;
4847
4891
  userTimestamp = typeof body.timestamp === "string" ? body.timestamp : void 0;
4848
4892
  if (body.topicChangeAction !== void 0 || body.heldMessage !== void 0) {
4849
4893
  hasStaleTopicFields = true;
@@ -4874,9 +4918,19 @@ app2.post("/", async (c) => {
4874
4918
  if (!account) {
4875
4919
  return c.json({ error: "No account configured" }, 500);
4876
4920
  }
4877
- const agentSlug = resolveDefaultAgentSlug(account.accountDir);
4921
+ let agentSlug;
4922
+ let resolveSource;
4923
+ if (requestedSlug) {
4924
+ const active = validateAgentSlug(requestedSlug) && resolveAgentConfig(account.accountDir, requestedSlug).status === "active";
4925
+ agentSlug = active ? requestedSlug : null;
4926
+ resolveSource = active ? "slug" : "none";
4927
+ } else {
4928
+ agentSlug = resolveDefaultAgentSlug(account.accountDir);
4929
+ resolveSource = agentSlug ? "default-fallback" : "none";
4930
+ }
4931
+ console.log(`[webchat] op=resolve slug=${requestedSlug ?? "none"} source=${resolveSource} agent=${agentSlug ?? "none"}`);
4878
4932
  if (!agentSlug) {
4879
- return c.json({ error: "No default agent configured" }, 500);
4933
+ return c.json({ error: "no-agent-for-address" }, 404);
4880
4934
  }
4881
4935
  let accessMode = "open";
4882
4936
  try {
@@ -6662,32 +6716,46 @@ app5.post("/", async (c) => {
6662
6716
  var client_error_default = app5;
6663
6717
 
6664
6718
  // server/routes/admin/session.ts
6665
- import { readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4, existsSync as existsSync8 } from "fs";
6666
- import { join as join8 } from "path";
6667
- import { createHash as createHash2 } from "crypto";
6668
6719
  import { randomUUID as randomUUID7 } from "crypto";
6720
+
6721
+ // app/lib/admin-identity/pin-validator.ts
6722
+ import { createHash as createHash2 } from "crypto";
6723
+ import { existsSync as existsSync8, readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync4 } from "fs";
6724
+ import { join as join8 } from "path";
6669
6725
  function hashPin2(pin) {
6670
6726
  return createHash2("sha256").update(pin).digest("hex");
6671
6727
  }
6672
- function readUsersFile2() {
6673
- if (!existsSync8(USERS_FILE)) return null;
6674
- const raw = readFileSync9(USERS_FILE, "utf-8").trim();
6728
+ function readUsersFile2(usersFilePath) {
6729
+ if (!existsSync8(usersFilePath)) return null;
6730
+ const raw = readFileSync9(usersFilePath, "utf-8").trim();
6675
6731
  if (!raw) return [];
6676
6732
  return JSON.parse(raw);
6677
6733
  }
6678
- function scanForOrphanedAccountAdmins(users) {
6679
- const usersUserIds = new Set(users.map((u) => u.userId));
6734
+ function validatePin(pin, usersFilePath) {
6735
+ let users;
6736
+ try {
6737
+ users = readUsersFile2(usersFilePath);
6738
+ } catch (err) {
6739
+ return { kind: "corrupt", message: err instanceof Error ? err.message : String(err) };
6740
+ }
6741
+ if (users === null || users.length === 0) return { kind: "unavailable" };
6742
+ const inputHash = hashPin2(pin);
6743
+ const matched = users.find((u) => u.pin === inputHash);
6744
+ return matched ? { kind: "match", userId: matched.userId } : { kind: "miss" };
6745
+ }
6746
+ function scanForOrphanedAccountAdmins(users, accountsDir) {
6747
+ const known = new Set(users.map((u) => u.userId));
6680
6748
  const orphans = [];
6681
- if (!existsSync8(ACCOUNTS_DIR)) return orphans;
6749
+ if (!existsSync8(accountsDir)) return orphans;
6682
6750
  let entries;
6683
6751
  try {
6684
- entries = readdirSync4(ACCOUNTS_DIR);
6752
+ entries = readdirSync4(accountsDir);
6685
6753
  } catch {
6686
6754
  return orphans;
6687
6755
  }
6688
6756
  for (const entry of entries) {
6689
6757
  if (entry.startsWith(".")) continue;
6690
- const accountDir = join8(ACCOUNTS_DIR, entry);
6758
+ const accountDir = join8(accountsDir, entry);
6691
6759
  try {
6692
6760
  if (!statSync4(accountDir).isDirectory()) continue;
6693
6761
  } catch {
@@ -6699,9 +6767,7 @@ function scanForOrphanedAccountAdmins(users) {
6699
6767
  const config = JSON.parse(readFileSync9(accountJsonPath, "utf-8"));
6700
6768
  const admins = config.admins ?? [];
6701
6769
  for (const a of admins) {
6702
- if (typeof a.userId === "string" && !usersUserIds.has(a.userId)) {
6703
- orphans.push(a.userId);
6704
- }
6770
+ if (typeof a.userId === "string" && !known.has(a.userId)) orphans.push(a.userId);
6705
6771
  }
6706
6772
  } catch {
6707
6773
  continue;
@@ -6709,6 +6775,8 @@ function scanForOrphanedAccountAdmins(users) {
6709
6775
  }
6710
6776
  return orphans;
6711
6777
  }
6778
+
6779
+ // server/routes/admin/session.ts
6712
6780
  async function resolveUserIdentity(accountId, userId) {
6713
6781
  const result = await loadAdminUserName(accountId, userId);
6714
6782
  if (result.source === "neo4j") {
@@ -6818,20 +6886,21 @@ app6.post("/", async (c) => {
6818
6886
  return c.json({ error: "Invalid request" }, 400);
6819
6887
  }
6820
6888
  if (!body.pin) return c.json({ error: "Invalid request" }, 400);
6821
- const inputHash = hashPin2(body.pin);
6822
- let users = null;
6823
- try {
6824
- users = readUsersFile2();
6825
- } catch (err) {
6826
- console.error(`[session] users.json corrupt: ${err instanceof Error ? err.message : String(err)}`);
6889
+ const verdict = validatePin(body.pin, USERS_FILE);
6890
+ if (verdict.kind === "corrupt") {
6891
+ console.error(`[session] users.json corrupt: ${verdict.message}`);
6827
6892
  return c.json({ error: "User configuration is corrupt. Re-run the seed script." }, 503);
6828
6893
  }
6829
- if (users === null || users.length === 0) {
6894
+ if (verdict.kind === "unavailable") {
6830
6895
  return c.json({ error: "PIN not configured. Complete onboarding first." }, 503);
6831
6896
  }
6832
- const matchedUser = users.find((u) => u.pin === inputHash);
6833
- if (!matchedUser) {
6834
- const orphanUserIds = scanForOrphanedAccountAdmins(users);
6897
+ if (verdict.kind === "miss") {
6898
+ let users = [];
6899
+ try {
6900
+ users = readUsersFile2(USERS_FILE) ?? [];
6901
+ } catch {
6902
+ }
6903
+ const orphanUserIds = scanForOrphanedAccountAdmins(users, ACCOUNTS_DIR);
6835
6904
  if (orphanUserIds.length > 0) {
6836
6905
  const prefix = orphanUserIds[0].slice(0, 8);
6837
6906
  console.log(
@@ -6842,7 +6911,7 @@ app6.post("/", async (c) => {
6842
6911
  }
6843
6912
  return c.json({ error: "Invalid PIN" }, 401);
6844
6913
  }
6845
- const { userId } = matchedUser;
6914
+ const { userId } = verdict;
6846
6915
  const accounts = resolveUserAccounts(userId);
6847
6916
  if (accounts.length === 0) {
6848
6917
  console.log(`[session] user has no accounts: userId=${userId}`);
@@ -7551,11 +7620,11 @@ app11.delete("/:id", requireAdminSession, async (c) => {
7551
7620
  const owned = await verifyConversationOwnership(sessionId, accountId);
7552
7621
  if (!owned) return c.json({ error: "Conversation not found" }, 404);
7553
7622
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-conversation-delete" });
7554
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
7623
+ const managerBase6 = `http://127.0.0.1:${managerPort}`;
7555
7624
  const outcome = await cascadeAdminConversationDelete({
7556
7625
  sessionId,
7557
7626
  accountId,
7558
- managerBase: managerBase5
7627
+ managerBase: managerBase6
7559
7628
  });
7560
7629
  if (outcome.ok) return c.json({ ok: true, claudeSessionIds: outcome.claudeSessionIds });
7561
7630
  if (outcome.reason === "pty-still-alive") {
@@ -8437,18 +8506,18 @@ var ALLOWED_EVENTS = /* @__PURE__ */ new Set([
8437
8506
  ]);
8438
8507
  var app14 = new Hono();
8439
8508
  app14.post("/", async (c) => {
8440
- const TAG28 = "[admin:events]";
8509
+ const TAG29 = "[admin:events]";
8441
8510
  let body;
8442
8511
  try {
8443
8512
  body = await c.req.json();
8444
8513
  } catch (err) {
8445
8514
  const detail = err instanceof Error ? err.message : String(err);
8446
- console.error(`${TAG28} reject reason=body-not-json detail=${detail}`);
8515
+ console.error(`${TAG29} reject reason=body-not-json detail=${detail}`);
8447
8516
  return c.json({ ok: false, detail: "Request body was not valid JSON" }, 400);
8448
8517
  }
8449
8518
  const event = typeof body.event === "string" ? body.event : "";
8450
8519
  if (!ALLOWED_EVENTS.has(event)) {
8451
- console.error(`${TAG28} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
8520
+ console.error(`${TAG29} reject reason=event-not-allowed event=${JSON.stringify(event)}`);
8452
8521
  return c.json({ ok: false, detail: `Event "${event}" is not allowed` }, 400);
8453
8522
  }
8454
8523
  const rawFields = body.fields && typeof body.fields === "object" ? body.fields : {};
@@ -11259,7 +11328,7 @@ app18.post("/", requireAdminSession, async (c) => {
11259
11328
  return c.json({ error: "AdminConversation node is missing sessionId" }, 500);
11260
11329
  }
11261
11330
  const managerPort = requirePortEnv("CLAUDE_SESSION_MANAGER_PORT", { tag: "graph-page-cascade" });
11262
- const managerBase5 = `http://127.0.0.1:${managerPort}`;
11331
+ const managerBase6 = `http://127.0.0.1:${managerPort}`;
11263
11332
  try {
11264
11333
  await session.close();
11265
11334
  } catch {
@@ -11267,7 +11336,7 @@ app18.post("/", requireAdminSession, async (c) => {
11267
11336
  const outcome = await cascadeAdminConversationDelete({
11268
11337
  sessionId,
11269
11338
  accountId,
11270
- managerBase: managerBase5
11339
+ managerBase: managerBase6
11271
11340
  });
11272
11341
  const elapsed2 = Date.now() - started;
11273
11342
  const labelSummary2 = preflightLabels.join(",");
@@ -12899,36 +12968,89 @@ app32.post("/", async (c) => {
12899
12968
  });
12900
12969
  var access_session_evict_default = app32;
12901
12970
 
12902
- // server/routes/admin/index.ts
12971
+ // server/routes/admin/identity.ts
12972
+ var import_dist4 = __toESM(require_dist3(), 1);
12903
12973
  var app33 = new Hono();
12904
- app33.route("/session", session_default);
12905
- app33.route("/logs", logs_default);
12906
- app33.route("/claude-info", claude_info_default);
12907
- app33.route("/attachment", attachment_default);
12908
- app33.route("/agents", agents_default);
12909
- app33.route("/sessions", sessions_default);
12910
- app33.route("/claude-sessions", claude_sessions_default);
12911
- app33.route("/log-ingest", log_ingest_default);
12912
- app33.route("/events", events_default);
12913
- app33.route("/files", files_default);
12914
- app33.route("/graph-search", graph_search_default);
12915
- app33.route("/graph-subgraph", graph_subgraph_default);
12916
- app33.route("/graph-delete", graph_delete_default);
12917
- app33.route("/graph-restore", graph_restore_default);
12918
- app33.route("/graph-labels-in-graph", graph_labels_in_graph_default);
12919
- app33.route("/graph-default-view", graph_default_view_default);
12920
- app33.route("/sidebar-artefacts", sidebar_artefacts_default);
12921
- app33.route("/sidebar-sessions", sidebar_sessions_default);
12922
- app33.route("/session-delete", session_delete_default);
12923
- app33.route("/session-rc-spawn", session_rc_spawn_default);
12924
- app33.route("/system-stats", system_stats_default);
12925
- app33.route("/health-brand", health_default2);
12926
- app33.route("/linkedin-ingest", linkedin_ingest_default);
12927
- app33.route("/post-turn-context", post_turn_context_default);
12928
- app33.route("/public-session-context", public_session_context_default);
12929
- app33.route("/public-session-exit", public_session_exit_default);
12930
- app33.route("/access-session-evict", access_session_evict_default);
12931
- var admin_default = app33;
12974
+ var TAG25 = "[admin-identity]";
12975
+ function managerBase5() {
12976
+ const port2 = (0, import_dist4.requirePortEnv)("CLAUDE_SESSION_MANAGER_PORT", { tag: "admin-identity" });
12977
+ return `http://127.0.0.1:${port2}`;
12978
+ }
12979
+ app33.post("/validate", async (c) => {
12980
+ const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
12981
+ const isLoopback = remoteAddr === "127.0.0.1" || remoteAddr === "::1" || remoteAddr === "::ffff:127.0.0.1";
12982
+ if (!isLoopback || c.req.header("x-forwarded-for")) {
12983
+ return c.json({ error: "forbidden" }, 403);
12984
+ }
12985
+ let body;
12986
+ try {
12987
+ body = await c.req.json();
12988
+ } catch {
12989
+ return c.json({ error: "bad-request" }, 400);
12990
+ }
12991
+ const pin = typeof body.pin === "string" ? body.pin : "";
12992
+ const sessionId = typeof body.sessionId === "string" ? body.sessionId : void 0;
12993
+ if (!pin) return c.json({ error: "bad-request" }, 400);
12994
+ const fireStop = () => {
12995
+ if (sessionId) {
12996
+ void fetch(`${managerBase5()}/${encodeURIComponent(sessionId)}/stop`, { method: "POST" }).catch(
12997
+ () => {
12998
+ }
12999
+ );
13000
+ }
13001
+ };
13002
+ const verdict = validatePin(pin, USERS_FILE);
13003
+ if (verdict.kind !== "match") {
13004
+ if (verdict.kind === "miss") fireStop();
13005
+ console.log(`${TAG25} op=endpoint-validate result=${verdict.kind}${sessionId ? ` sessionId=${sessionId.slice(0, 8)}` : ""}`);
13006
+ return c.json({ kind: verdict.kind });
13007
+ }
13008
+ const { userId } = verdict;
13009
+ const accounts = resolveUserAccounts(userId);
13010
+ if (accounts.length === 0) {
13011
+ fireStop();
13012
+ console.log(`${TAG25} op=endpoint-validate result=no-account userId=${userId.slice(0, 8)}`);
13013
+ return c.json({ kind: "miss" });
13014
+ }
13015
+ const accountId = accounts[0].accountId;
13016
+ const { userName } = await resolveUserIdentity(accountId, userId);
13017
+ const aboutOwner = await resolveOwnerProfileBlock(accountId, userId);
13018
+ console.log(`${TAG25} op=endpoint-validate result=match userId=${userId.slice(0, 8)} aboutOwner=${aboutOwner.ok ? "ok" : `unresolved:${aboutOwner.reason}`}`);
13019
+ return c.json({ kind: "match", userId, userName, aboutOwner });
13020
+ });
13021
+ var identity_default = app33;
13022
+
13023
+ // server/routes/admin/index.ts
13024
+ var app34 = new Hono();
13025
+ app34.route("/session", session_default);
13026
+ app34.route("/identity", identity_default);
13027
+ app34.route("/logs", logs_default);
13028
+ app34.route("/claude-info", claude_info_default);
13029
+ app34.route("/attachment", attachment_default);
13030
+ app34.route("/agents", agents_default);
13031
+ app34.route("/sessions", sessions_default);
13032
+ app34.route("/claude-sessions", claude_sessions_default);
13033
+ app34.route("/log-ingest", log_ingest_default);
13034
+ app34.route("/events", events_default);
13035
+ app34.route("/files", files_default);
13036
+ app34.route("/graph-search", graph_search_default);
13037
+ app34.route("/graph-subgraph", graph_subgraph_default);
13038
+ app34.route("/graph-delete", graph_delete_default);
13039
+ app34.route("/graph-restore", graph_restore_default);
13040
+ app34.route("/graph-labels-in-graph", graph_labels_in_graph_default);
13041
+ app34.route("/graph-default-view", graph_default_view_default);
13042
+ app34.route("/sidebar-artefacts", sidebar_artefacts_default);
13043
+ app34.route("/sidebar-sessions", sidebar_sessions_default);
13044
+ app34.route("/session-delete", session_delete_default);
13045
+ app34.route("/session-rc-spawn", session_rc_spawn_default);
13046
+ app34.route("/system-stats", system_stats_default);
13047
+ app34.route("/health-brand", health_default2);
13048
+ app34.route("/linkedin-ingest", linkedin_ingest_default);
13049
+ app34.route("/post-turn-context", post_turn_context_default);
13050
+ app34.route("/public-session-context", public_session_context_default);
13051
+ app34.route("/public-session-exit", public_session_exit_default);
13052
+ app34.route("/access-session-evict", access_session_evict_default);
13053
+ var admin_default = app34;
12932
13054
 
12933
13055
  // app/lib/access-gate.ts
12934
13056
  import neo4j4 from "neo4j-driver";
@@ -13139,11 +13261,11 @@ async function generateNewMagicToken(grantId) {
13139
13261
  }
13140
13262
 
13141
13263
  // server/routes/access/verify-token.ts
13142
- var TAG25 = "[access-verify]";
13264
+ var TAG26 = "[access-verify]";
13143
13265
  var MINT_TAG = "[access-session-mint]";
13144
13266
  var COOKIE_NAME = "__access_session";
13145
- var app34 = new Hono();
13146
- app34.post("/", async (c) => {
13267
+ var app35 = new Hono();
13268
+ app35.post("/", async (c) => {
13147
13269
  const ip = c.var.clientIp || "unknown";
13148
13270
  let body;
13149
13271
  try {
@@ -13158,39 +13280,39 @@ app34.post("/", async (c) => {
13158
13280
  }
13159
13281
  const rateMsg = checkAccessRateLimit(ip, agentSlug);
13160
13282
  if (rateMsg) {
13161
- console.error(`${TAG25} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
13283
+ console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=rate-limited ip=${ip}`);
13162
13284
  return c.json({ error: rateMsg }, 429);
13163
13285
  }
13164
13286
  const grant = await findGrantByMagicToken(token);
13165
13287
  if (!grant) {
13166
13288
  recordAccessFailedAttempt(ip, agentSlug);
13167
- console.error(`${TAG25} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
13289
+ console.error(`${TAG26} grantId=- agentSlug=${agentSlug} result=notfound ip=${ip}`);
13168
13290
  return c.json({ error: "invalid-or-expired-link" }, 401);
13169
13291
  }
13170
13292
  if (grant.agentSlug !== agentSlug) {
13171
13293
  recordAccessFailedAttempt(ip, agentSlug);
13172
13294
  console.error(
13173
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
13295
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=agent-mismatch grantAgent=${grant.agentSlug} ip=${ip}`
13174
13296
  );
13175
13297
  return c.json({ error: "invalid-or-expired-link" }, 401);
13176
13298
  }
13177
13299
  if (grant.status === "expired" || grant.status === "revoked") {
13178
13300
  recordAccessFailedAttempt(ip, agentSlug);
13179
13301
  console.error(
13180
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
13302
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired status=${grant.status} ip=${ip}`
13181
13303
  );
13182
13304
  return c.json({ error: "access-no-longer-valid" }, 401);
13183
13305
  }
13184
13306
  if (grant.expiresAt !== null && grant.expiresAt < Date.now()) {
13185
13307
  recordAccessFailedAttempt(ip, agentSlug);
13186
13308
  console.error(
13187
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
13309
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=expired reason=expiresAt-past ip=${ip}`
13188
13310
  );
13189
13311
  return c.json({ error: "access-no-longer-valid" }, 401);
13190
13312
  }
13191
13313
  if (!grant.sliceToken) {
13192
13314
  console.error(
13193
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
13315
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=no-slice-token reason=schema-violation`
13194
13316
  );
13195
13317
  return c.json({ error: "grant-misconfigured" }, 500);
13196
13318
  }
@@ -13206,12 +13328,12 @@ app34.post("/", async (c) => {
13206
13328
  await consumeMagicTokenAndActivate(grant.grantId);
13207
13329
  } catch (err) {
13208
13330
  console.error(
13209
- `${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
13331
+ `${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=consume-failed err="${err instanceof Error ? err.message : String(err)}"`
13210
13332
  );
13211
13333
  return c.json({ error: "verification-failed" }, 500);
13212
13334
  }
13213
13335
  clearAccessRateLimit(ip, agentSlug);
13214
- console.log(`${TAG25} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
13336
+ console.log(`${TAG26} grantId=${grant.grantId} agentSlug=${agentSlug} result=ok ip=${ip}`);
13215
13337
  console.log(
13216
13338
  `${MINT_TAG} grantId=${grant.grantId} sliceToken=${grant.sliceToken.slice(0, 8)} agentSlug=${agentSlug} personId=${grant.personId ?? "none"}`
13217
13339
  );
@@ -13225,7 +13347,7 @@ app34.post("/", async (c) => {
13225
13347
  displayName: grant.displayName
13226
13348
  });
13227
13349
  });
13228
- var verify_token_default = app34;
13350
+ var verify_token_default = app35;
13229
13351
 
13230
13352
  // app/lib/access-email.ts
13231
13353
  import { spawn as spawn2 } from "child_process";
@@ -13287,10 +13409,10 @@ async function sendMagicLinkEmail(payload) {
13287
13409
  }
13288
13410
 
13289
13411
  // server/routes/access/request-magic-link.ts
13290
- var TAG26 = "[access-request-link]";
13291
- var app35 = new Hono();
13412
+ var TAG27 = "[access-request-link]";
13413
+ var app36 = new Hono();
13292
13414
  var VISITOR_MESSAGE = "If that email is on the invite list, a fresh link is on the way.";
13293
- app35.post("/", async (c) => {
13415
+ app36.post("/", async (c) => {
13294
13416
  let body;
13295
13417
  try {
13296
13418
  body = await c.req.json();
@@ -13304,18 +13426,18 @@ app35.post("/", async (c) => {
13304
13426
  }
13305
13427
  const rateMsg = checkRequestLinkRateLimit(contactValue);
13306
13428
  if (rateMsg) {
13307
- console.error(`${TAG26} contactValue=${maskContact(contactValue)} result=rate-limited`);
13429
+ console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=rate-limited`);
13308
13430
  return c.json({ error: rateMsg }, 429);
13309
13431
  }
13310
13432
  recordRequestLinkAttempt(contactValue);
13311
13433
  const accountId = process.env.ACCOUNT_ID ?? "";
13312
13434
  if (!accountId) {
13313
- console.error(`${TAG26} contactValue=${maskContact(contactValue)} result=no-account-id`);
13435
+ console.error(`${TAG27} contactValue=${maskContact(contactValue)} result=no-account-id`);
13314
13436
  return c.json({ message: VISITOR_MESSAGE }, 200);
13315
13437
  }
13316
13438
  const grant = await findActiveGrantByContact(contactValue, agentSlug, accountId);
13317
13439
  if (!grant) {
13318
- console.log(`${TAG26} contactValue=${maskContact(contactValue)} result=notfound`);
13440
+ console.log(`${TAG27} contactValue=${maskContact(contactValue)} result=notfound`);
13319
13441
  return c.json({ message: VISITOR_MESSAGE }, 200);
13320
13442
  }
13321
13443
  let token;
@@ -13323,7 +13445,7 @@ app35.post("/", async (c) => {
13323
13445
  token = await generateNewMagicToken(grant.grantId);
13324
13446
  } catch (err) {
13325
13447
  console.error(
13326
- `${TAG26} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
13448
+ `${TAG27} contactValue=${maskContact(contactValue)} result=mint-failed err="${err instanceof Error ? err.message : String(err)}"`
13327
13449
  );
13328
13450
  return c.json({ message: VISITOR_MESSAGE }, 200);
13329
13451
  }
@@ -13355,22 +13477,22 @@ app35.post("/", async (c) => {
13355
13477
  });
13356
13478
  if (!sendResult.ok) {
13357
13479
  console.error(
13358
- `${TAG26} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
13480
+ `${TAG27} contactValue=${maskContact(contactValue)} result=send-failed err="${sendResult.error}"`
13359
13481
  );
13360
13482
  return c.json({ message: VISITOR_MESSAGE }, 200);
13361
13483
  }
13362
13484
  console.log(
13363
- `${TAG26} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
13485
+ `${TAG27} contactValue=${maskContact(contactValue)} result=ok messageId=${sendResult.messageId}`
13364
13486
  );
13365
13487
  return c.json({ message: VISITOR_MESSAGE }, 200);
13366
13488
  });
13367
- var request_magic_link_default = app35;
13489
+ var request_magic_link_default = app36;
13368
13490
 
13369
13491
  // server/routes/access/index.ts
13370
- var app36 = new Hono();
13371
- app36.route("/verify-token", verify_token_default);
13372
- app36.route("/request-magic-link", request_magic_link_default);
13373
- var access_default = app36;
13492
+ var app37 = new Hono();
13493
+ app37.route("/verify-token", verify_token_default);
13494
+ app37.route("/request-magic-link", request_magic_link_default);
13495
+ var access_default = app37;
13374
13496
 
13375
13497
  // server/routes/sites.ts
13376
13498
  import { existsSync as existsSync19, readFileSync as readFileSync18, realpathSync as realpathSync5, statSync as statSync8 } from "fs";
@@ -13405,8 +13527,8 @@ function getExt(p) {
13405
13527
  if (idx < p.lastIndexOf("/")) return "";
13406
13528
  return p.slice(idx).toLowerCase();
13407
13529
  }
13408
- var app37 = new Hono();
13409
- app37.get("/:rel{.*}", (c) => {
13530
+ var app38 = new Hono();
13531
+ app38.get("/:rel{.*}", (c) => {
13410
13532
  const reqPath = c.req.path;
13411
13533
  const rawRel = c.req.param("rel") ?? "";
13412
13534
  const trimmed = rawRel.replace(/^\/+/, "").replace(/\/+$/, "");
@@ -13509,7 +13631,7 @@ app37.get("/:rel{.*}", (c) => {
13509
13631
  "X-Content-Type-Options": "nosniff"
13510
13632
  });
13511
13633
  });
13512
- var sites_default = app37;
13634
+ var sites_default = app38;
13513
13635
 
13514
13636
  // app/lib/visitor-token.ts
13515
13637
  import { createHmac, randomBytes, timingSafeEqual } from "crypto";
@@ -13609,7 +13731,7 @@ function readBrandConfig() {
13609
13731
  }
13610
13732
 
13611
13733
  // server/routes/visitor-consent.ts
13612
- var app38 = new Hono();
13734
+ var app39 = new Hono();
13613
13735
  var CONSENT_COOKIE_NAME = "mxy_consent";
13614
13736
  var CONSENT_COOKIE_MAX_AGE_SECONDS = 60 * 60 * 24 * 365;
13615
13737
  var DEFAULT_CONSENT_COPY = {
@@ -13654,17 +13776,17 @@ function siteSlugFromReferer(referer) {
13654
13776
  return "";
13655
13777
  }
13656
13778
  }
13657
- app38.options("/consent", (c) => {
13779
+ app39.options("/consent", (c) => {
13658
13780
  const origin = getOrigin(c);
13659
13781
  setCorsHeaders(c, origin);
13660
13782
  return c.body(null, 204);
13661
13783
  });
13662
- app38.options("/brand-config", (c) => {
13784
+ app39.options("/brand-config", (c) => {
13663
13785
  const origin = getOrigin(c);
13664
13786
  setCorsHeaders(c, origin);
13665
13787
  return c.body(null, 204);
13666
13788
  });
13667
- app38.post("/consent", async (c) => {
13789
+ app39.post("/consent", async (c) => {
13668
13790
  const origin = getOrigin(c);
13669
13791
  setCorsHeaders(c, origin);
13670
13792
  let raw;
@@ -13704,7 +13826,7 @@ app38.post("/consent", async (c) => {
13704
13826
  console.log(`[consent] ${parsed.decision} site=${site} brand=${brandName} tokenBound=${tokenBound}`);
13705
13827
  return c.body(null, 204);
13706
13828
  });
13707
- app38.get("/brand-config", (c) => {
13829
+ app39.get("/brand-config", (c) => {
13708
13830
  const origin = getOrigin(c);
13709
13831
  setCorsHeaders(c, origin);
13710
13832
  const brand = readBrandConfig();
@@ -13714,7 +13836,7 @@ app38.get("/brand-config", (c) => {
13714
13836
  c.header("Cache-Control", "public, max-age=300");
13715
13837
  return c.json({ consent: { copy, palette } });
13716
13838
  });
13717
- var visitor_consent_default = app38;
13839
+ var visitor_consent_default = app39;
13718
13840
 
13719
13841
  // server/routes/listings.ts
13720
13842
  function getCookie(headerValue, name) {
@@ -13741,8 +13863,8 @@ function appendConsentParams(pageUrl, token) {
13741
13863
  }
13742
13864
  var SAFE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,118}[a-z0-9])?$/;
13743
13865
  var CHAT_SESSION_KEY_RE = /^[A-Za-z0-9][A-Za-z0-9_-]{7,127}$/;
13744
- var app39 = new Hono();
13745
- app39.get("/:slug/click", async (c) => {
13866
+ var app40 = new Hono();
13867
+ app40.get("/:slug/click", async (c) => {
13746
13868
  const slug = c.req.param("slug") ?? "";
13747
13869
  const rawSession = c.req.query("session") ?? "";
13748
13870
  const sessionKey = CHAT_SESSION_KEY_RE.test(rawSession) ? rawSession : "invalid";
@@ -13806,10 +13928,10 @@ app39.get("/:slug/click", async (c) => {
13806
13928
  console.log(`[property-card-click] sessionKey=${sessionKey} listingSlug=${slug} consent=${consentCookie ?? "absent"} ts=${(/* @__PURE__ */ new Date()).toISOString()}`);
13807
13929
  return c.redirect(redirectUrl, 302);
13808
13930
  });
13809
- var listings_default = app39;
13931
+ var listings_default = app40;
13810
13932
 
13811
13933
  // server/routes/visitor-event.ts
13812
- var app40 = new Hono();
13934
+ var app41 = new Hono();
13813
13935
  var BOT_UA_RE = /\b(bot|crawl|spider|slurp|headlesschrome|phantomjs|googlebot|bingbot|yandex|baiduspider|ahrefsbot|semrushbot|mj12bot|dotbot|petalbot)\b/i;
13814
13936
  var buckets = /* @__PURE__ */ new Map();
13815
13937
  var RATE_LIMIT = 60;
@@ -13876,12 +13998,12 @@ function originAllowed(origin, allowlist) {
13876
13998
  return false;
13877
13999
  }
13878
14000
  }
13879
- app40.options("/event", (c) => {
14001
+ app41.options("/event", (c) => {
13880
14002
  const origin = getOrigin2(c);
13881
14003
  setCorsHeaders2(c, origin);
13882
14004
  return c.body(null, 204);
13883
14005
  });
13884
- app40.post("/event", async (c) => {
14006
+ app41.post("/event", async (c) => {
13885
14007
  const origin = getOrigin2(c);
13886
14008
  setCorsHeaders2(c, origin);
13887
14009
  const ua = c.req.header("user-agent") ?? "";
@@ -14086,7 +14208,7 @@ async function writeEvent(opts) {
14086
14208
  );
14087
14209
  }
14088
14210
  }
14089
- var visitor_event_default = app40;
14211
+ var visitor_event_default = app41;
14090
14212
 
14091
14213
  // server/routes/session.ts
14092
14214
  import { resolve as resolve22 } from "path";
@@ -14123,8 +14245,8 @@ function withVisitorCookie(response, visitorId) {
14123
14245
  headers
14124
14246
  });
14125
14247
  }
14126
- var app41 = new Hono();
14127
- app41.post("/", async (c) => {
14248
+ var app42 = new Hono();
14249
+ app42.post("/", async (c) => {
14128
14250
  let body;
14129
14251
  try {
14130
14252
  body = await c.req.json();
@@ -14324,7 +14446,7 @@ app41.post("/", async (c) => {
14324
14446
  newVisitorId
14325
14447
  );
14326
14448
  });
14327
- var session_default2 = app41;
14449
+ var session_default2 = app42;
14328
14450
 
14329
14451
  // app/lib/graph-health.ts
14330
14452
  var HOUR_MS = 60 * 60 * 1e3;
@@ -14511,7 +14633,7 @@ async function startFileWatcher(opts = {}) {
14511
14633
  }
14512
14634
 
14513
14635
  // app/lib/whatsapp/inbound/claude-bridge.ts
14514
- var TAG27 = "[whatsapp-adaptor]";
14636
+ var TAG28 = "[whatsapp-adaptor]";
14515
14637
  function whatsappTurnTimeoutMs() {
14516
14638
  return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
14517
14639
  }
@@ -14533,7 +14655,7 @@ async function dispatchToClaude(input) {
14533
14655
  await input.reply(result.turnText);
14534
14656
  } catch (err) {
14535
14657
  const m = err instanceof Error ? err.message : String(err);
14536
- console.error(`${TAG27} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
14658
+ console.error(`${TAG28} reject reason=reply-failed senderId=${input.senderId} message=${m}`);
14537
14659
  }
14538
14660
  }
14539
14661
  function startReaper2() {
@@ -14863,9 +14985,9 @@ watchFile(ALIAS_DOMAINS_PATH, { interval: 2e3 }, () => {
14863
14985
  function isPublicHost(host) {
14864
14986
  return host.startsWith("public.") || aliasDomains.has(host);
14865
14987
  }
14866
- var app42 = new Hono();
14867
- app42.use("*", clientIpMiddleware);
14868
- app42.use("*", async (c, next) => {
14988
+ var app43 = new Hono();
14989
+ app43.use("*", clientIpMiddleware);
14990
+ app43.use("*", async (c, next) => {
14869
14991
  await next();
14870
14992
  c.header("X-Content-Type-Options", "nosniff");
14871
14993
  c.header("Referrer-Policy", "strict-origin-when-cross-origin");
@@ -14875,7 +14997,7 @@ app42.use("*", async (c, next) => {
14875
14997
  );
14876
14998
  });
14877
14999
  var HTTP_LOG_PATHS = /* @__PURE__ */ new Set(["/vnc-viewer.html", "/vnc-popout.html"]);
14878
- app42.use("*", async (c, next) => {
15000
+ app43.use("*", async (c, next) => {
14879
15001
  if (!HTTP_LOG_PATHS.has(c.req.path)) {
14880
15002
  await next();
14881
15003
  return;
@@ -14893,7 +15015,7 @@ app42.use("*", async (c, next) => {
14893
15015
  });
14894
15016
  }
14895
15017
  });
14896
- app42.use("*", async (c, next) => {
15018
+ app43.use("*", async (c, next) => {
14897
15019
  const host = (c.req.header("host") ?? "").split(":")[0];
14898
15020
  if (!isPublicHost(host)) {
14899
15021
  await next();
@@ -14924,7 +15046,7 @@ function resolveRemoteAuthOpts() {
14924
15046
  return brandLoginOpts;
14925
15047
  }
14926
15048
  var MAX_LOGIN_BODY = 8 * 1024;
14927
- app42.post("/__remote-auth/login", async (c) => {
15049
+ app43.post("/__remote-auth/login", async (c) => {
14928
15050
  const client = clientFrom(c);
14929
15051
  const clientIp = client.ip || "unknown";
14930
15052
  if (!requestIsTlsTerminated(c)) {
@@ -14969,7 +15091,7 @@ app42.post("/__remote-auth/login", async (c) => {
14969
15091
  }
14970
15092
  });
14971
15093
  });
14972
- app42.get("/__remote-auth/logout", (c) => {
15094
+ app43.get("/__remote-auth/logout", (c) => {
14973
15095
  const client = clientFrom(c);
14974
15096
  const clientIp = client.ip || "unknown";
14975
15097
  console.error(`[remote-auth] logout ip=${clientIp}`);
@@ -14982,7 +15104,7 @@ app42.get("/__remote-auth/logout", (c) => {
14982
15104
  }
14983
15105
  });
14984
15106
  });
14985
- app42.post("/__remote-auth/change-password", async (c) => {
15107
+ app43.post("/__remote-auth/change-password", async (c) => {
14986
15108
  const client = clientFrom(c);
14987
15109
  const clientIp = client.ip || "unknown";
14988
15110
  const rateLimited = checkRateLimit(client);
@@ -15033,13 +15155,13 @@ app42.post("/__remote-auth/change-password", async (c) => {
15033
15155
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Failed to save password", redirect }), 200);
15034
15156
  }
15035
15157
  });
15036
- app42.get("/__remote-auth/setup", (c) => {
15158
+ app43.get("/__remote-auth/setup", (c) => {
15037
15159
  if (isRemoteAuthConfigured()) {
15038
15160
  return c.redirect("/");
15039
15161
  }
15040
15162
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup" }), 200);
15041
15163
  });
15042
- app42.post("/__remote-auth/set-initial-password", async (c) => {
15164
+ app43.post("/__remote-auth/set-initial-password", async (c) => {
15043
15165
  if (isRemoteAuthConfigured()) {
15044
15166
  return c.redirect("/");
15045
15167
  }
@@ -15077,10 +15199,10 @@ app42.post("/__remote-auth/set-initial-password", async (c) => {
15077
15199
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "setup", setupError: "Failed to save password. Please try again." }), 200);
15078
15200
  }
15079
15201
  });
15080
- app42.get("/api/remote-auth/status", (c) => {
15202
+ app43.get("/api/remote-auth/status", (c) => {
15081
15203
  return c.json({ configured: isRemoteAuthConfigured() });
15082
15204
  });
15083
- app42.post("/api/remote-auth/set-password", async (c) => {
15205
+ app43.post("/api/remote-auth/set-password", async (c) => {
15084
15206
  let body;
15085
15207
  try {
15086
15208
  body = await c.req.json();
@@ -15111,9 +15233,9 @@ app42.post("/api/remote-auth/set-password", async (c) => {
15111
15233
  return c.json({ error: "Failed to save password" }, 500);
15112
15234
  }
15113
15235
  });
15114
- app42.route("/api/_client-error", client_error_default);
15236
+ app43.route("/api/_client-error", client_error_default);
15115
15237
  console.log("[client-error-route] mounted");
15116
- app42.use("*", async (c, next) => {
15238
+ app43.use("*", async (c, next) => {
15117
15239
  const host = (c.req.header("host") ?? "").split(":")[0];
15118
15240
  const path2 = c.req.path;
15119
15241
  if (path2 === "/favicon.ico" || path2.startsWith("/assets/") || path2.startsWith("/brand/")) {
@@ -15146,13 +15268,13 @@ app42.use("*", async (c, next) => {
15146
15268
  console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
15147
15269
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
15148
15270
  });
15149
- app42.route("/api/health", health_default);
15150
- app42.route("/api/chat", chat_default);
15151
- app42.route("/api/whatsapp", whatsapp_default);
15152
- app42.route("/api/onboarding", onboarding_default);
15153
- app42.route("/api/admin", admin_default);
15154
- app42.route("/api/access", access_default);
15155
- app42.route("/api/session", session_default2);
15271
+ app43.route("/api/health", health_default);
15272
+ app43.route("/api/chat", chat_default);
15273
+ app43.route("/api/whatsapp", whatsapp_default);
15274
+ app43.route("/api/onboarding", onboarding_default);
15275
+ app43.route("/api/admin", admin_default);
15276
+ app43.route("/api/access", access_default);
15277
+ app43.route("/api/session", session_default2);
15156
15278
  var SAFE_SLUG_RE2 = /^[a-z][a-z0-9-]{2,49}$/;
15157
15279
  var SAFE_FILENAME_RE = /^[a-z0-9_][a-z0-9_.-]{0,99}$/i;
15158
15280
  var IMAGE_MIME = {
@@ -15164,7 +15286,7 @@ var IMAGE_MIME = {
15164
15286
  ".svg": "image/svg+xml",
15165
15287
  ".ico": "image/x-icon"
15166
15288
  };
15167
- app42.get("/agent-assets/:slug/:filename", (c) => {
15289
+ app43.get("/agent-assets/:slug/:filename", (c) => {
15168
15290
  const slug = c.req.param("slug");
15169
15291
  const filename = c.req.param("filename");
15170
15292
  if (!SAFE_SLUG_RE2.test(slug)) {
@@ -15199,7 +15321,7 @@ app42.get("/agent-assets/:slug/:filename", (c) => {
15199
15321
  "Cache-Control": "public, max-age=3600"
15200
15322
  });
15201
15323
  });
15202
- app42.get("/generated/:filename", (c) => {
15324
+ app43.get("/generated/:filename", (c) => {
15203
15325
  const filename = c.req.param("filename");
15204
15326
  if (!SAFE_FILENAME_RE.test(filename) || filename.includes("..")) {
15205
15327
  console.error(`[generated] serve file=${filename} status=403`);
@@ -15229,10 +15351,10 @@ app42.get("/generated/:filename", (c) => {
15229
15351
  "Cache-Control": "public, max-age=86400"
15230
15352
  });
15231
15353
  });
15232
- app42.route("/sites", sites_default);
15233
- app42.route("/listings", listings_default);
15234
- app42.route("/v", visitor_event_default);
15235
- app42.route("/v", visitor_consent_default);
15354
+ app43.route("/sites", sites_default);
15355
+ app43.route("/listings", listings_default);
15356
+ app43.route("/v", visitor_event_default);
15357
+ app43.route("/v", visitor_consent_default);
15236
15358
  var htmlCache = /* @__PURE__ */ new Map();
15237
15359
  var brandLogoPath = "/brand/maxy-monochrome.png";
15238
15360
  var brandIconPath = "/brand/maxy-monochrome.png";
@@ -15369,20 +15491,27 @@ function brandedPublicHtml(agentSlug) {
15369
15491
  function escapeHtml(s) {
15370
15492
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
15371
15493
  }
15372
- app42.get("/", (c) => {
15494
+ app43.get("/", (c) => {
15373
15495
  const host = (c.req.header("host") ?? "").split(":")[0];
15374
15496
  if (isPublicHost(host)) {
15375
15497
  const defaultSlug = resolveDefaultSlug();
15376
- return c.html(brandedPublicHtml(defaultSlug ?? void 0));
15498
+ if (!defaultSlug) {
15499
+ console.error("[public-root] op=no-default");
15500
+ return c.html(
15501
+ `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${escapeHtml(BRAND.productName)}</title></head><body style="font-family:system-ui,sans-serif;max-width:32rem;margin:4rem auto;padding:0 1.5rem;color:#222"><h1 style="font-size:1.25rem">No agent configured</h1><p>This site has no default public agent set yet. The operator can set one from the admin console.</p></body></html>`,
15502
+ 503
15503
+ );
15504
+ }
15505
+ return c.html(brandedPublicHtml(defaultSlug));
15377
15506
  }
15378
15507
  return c.html(cachedHtml("index.html"));
15379
15508
  });
15380
- app42.get("/public", (c) => {
15509
+ app43.get("/public", (c) => {
15381
15510
  const host = (c.req.header("host") ?? "").split(":")[0];
15382
15511
  if (isPublicHost(host)) return c.text("Not found", 404);
15383
15512
  return c.html(cachedHtml("public.html"));
15384
15513
  });
15385
- app42.get("/chat", (c) => {
15514
+ app43.get("/chat", (c) => {
15386
15515
  const host = (c.req.header("host") ?? "").split(":")[0];
15387
15516
  if (isPublicHost(host)) return c.text("Not found", 404);
15388
15517
  return c.html(cachedHtml("public.html"));
@@ -15401,9 +15530,9 @@ async function logViewerFetch(c, next) {
15401
15530
  duration_ms: Date.now() - start
15402
15531
  });
15403
15532
  }
15404
- app42.use("/vnc-viewer.html", logViewerFetch);
15405
- app42.use("/vnc-popout.html", logViewerFetch);
15406
- app42.get("/vnc-popout.html", (c) => {
15533
+ app43.use("/vnc-viewer.html", logViewerFetch);
15534
+ app43.use("/vnc-popout.html", logViewerFetch);
15535
+ app43.get("/vnc-popout.html", (c) => {
15407
15536
  let html = htmlCache.get("vnc-popout.html");
15408
15537
  if (!html) {
15409
15538
  html = readFileSync22(resolve25(process.cwd(), "public", "vnc-popout.html"), "utf-8");
@@ -15416,7 +15545,7 @@ app42.get("/vnc-popout.html", (c) => {
15416
15545
  }
15417
15546
  return c.html(html);
15418
15547
  });
15419
- app42.post("/api/vnc/client-event", async (c) => {
15548
+ app43.post("/api/vnc/client-event", async (c) => {
15420
15549
  let body;
15421
15550
  try {
15422
15551
  body = await c.req.json();
@@ -15437,25 +15566,25 @@ app42.post("/api/vnc/client-event", async (c) => {
15437
15566
  });
15438
15567
  return c.json({ ok: true });
15439
15568
  });
15440
- app42.get("/g/:slug", (c) => {
15569
+ app43.get("/g/:slug", (c) => {
15441
15570
  return c.html(brandedPublicHtml());
15442
15571
  });
15443
- app42.get("/graph", (c) => {
15572
+ app43.get("/graph", (c) => {
15444
15573
  const host = (c.req.header("host") ?? "").split(":")[0];
15445
15574
  if (isPublicHost(host)) return c.text("Not found", 404);
15446
15575
  return c.html(cachedHtml("graph.html"));
15447
15576
  });
15448
- app42.get("/sessions", (c) => {
15577
+ app43.get("/sessions", (c) => {
15449
15578
  const host = (c.req.header("host") ?? "").split(":")[0];
15450
15579
  if (isPublicHost(host)) return c.text("Not found", 404);
15451
15580
  return c.html(cachedHtml("sessions.html"));
15452
15581
  });
15453
- app42.get("/data", (c) => {
15582
+ app43.get("/data", (c) => {
15454
15583
  const host = (c.req.header("host") ?? "").split(":")[0];
15455
15584
  if (isPublicHost(host)) return c.text("Not found", 404);
15456
15585
  return c.html(cachedHtml("data.html"));
15457
15586
  });
15458
- app42.get("/:slug", async (c, next) => {
15587
+ app43.get("/:slug", async (c, next) => {
15459
15588
  const slug = c.req.param("slug");
15460
15589
  if (AGENT_SLUG_PATTERN.test(`/${slug}`)) {
15461
15590
  const branding = loadBrandingCache(slug);
@@ -15465,13 +15594,13 @@ app42.get("/:slug", async (c, next) => {
15465
15594
  await next();
15466
15595
  });
15467
15596
  if (brandFaviconPath !== "/favicon.ico") {
15468
- app42.get("/favicon.ico", (c) => {
15597
+ app43.get("/favicon.ico", (c) => {
15469
15598
  c.header("Cache-Control", "public, max-age=300");
15470
15599
  return c.redirect(brandFaviconPath, 302);
15471
15600
  });
15472
15601
  }
15473
- app42.use("/*", serveStatic({ root: "./public" }));
15474
- app42.all("*", (c) => {
15602
+ app43.use("/*", serveStatic({ root: "./public" }));
15603
+ app43.all("*", (c) => {
15475
15604
  const host = (c.req.header("host") ?? "").split(":")[0];
15476
15605
  const path2 = c.req.path;
15477
15606
  if (isPublicHost(host)) {
@@ -15485,7 +15614,7 @@ app42.all("*", (c) => {
15485
15614
  });
15486
15615
  var port = requirePortEnv("MAXY_UI_INTERNAL_PORT", { tag: "ui-server" });
15487
15616
  var hostname = process.env.HOSTNAME ?? "127.0.0.1";
15488
- var httpServer = serve({ fetch: app42.fetch, port, hostname });
15617
+ var httpServer = serve({ fetch: app43.fetch, port, hostname });
15489
15618
  console.log(`${BRAND.productName} listening on http://${hostname}:${port}`);
15490
15619
  startAuthHealthHeartbeat();
15491
15620
  {
@@ -15503,7 +15632,6 @@ startAuthHealthHeartbeat();
15503
15632
  }, WINDOW_MS2);
15504
15633
  lagTimer.unref();
15505
15634
  }
15506
- console.log("[boot] auth-mode summary: oauth=8 api-key=1 (api-key consumer: invokePublicAgent only)");
15507
15635
  var SUBAPP_MANIFEST = [
15508
15636
  { prefix: "/api/health", file: "server/routes/health.ts", subapp: health_default },
15509
15637
  { prefix: "/api/chat", file: "server/routes/chat.ts", subapp: chat_default },
@@ -15523,7 +15651,7 @@ for (const m of SUBAPP_MANIFEST) {
15523
15651
  }
15524
15652
  try {
15525
15653
  const registered = [];
15526
- for (const r of app42.routes ?? []) {
15654
+ for (const r of app43.routes ?? []) {
15527
15655
  if (typeof r.path !== "string" || r.path.includes(":") || r.path.includes("*")) continue;
15528
15656
  if (AGENT_SLUG_PATTERN.test(r.path)) {
15529
15657
  registered.push({ method: (r.method ?? "ALL").toUpperCase(), path: r.path });
@@ -15531,6 +15659,11 @@ try {
15531
15659
  }
15532
15660
  const summary = registered.map((r) => `${r.method} ${r.path}`).join(", ") || "(none)";
15533
15661
  console.log(`[route-shadow] static-paths-matching-slug-pattern count=${registered.length} routes=${summary}`);
15662
+ const actualSlugs = [...new Set(registered.map((r) => r.path.replace(/^\//, "")))].sort();
15663
+ const expectedSlugs = [...SYSTEM_PATH_SLUGS].sort();
15664
+ if (actualSlugs.join(",") !== expectedSlugs.join(",")) {
15665
+ console.error(`[route-shadow] drift expected=${expectedSlugs.join(",")} actual=${actualSlugs.join(",")} \u2014 update SYSTEM_PATH_SLUGS in app/lib/system-path-slugs.ts`);
15666
+ }
15534
15667
  } catch (err) {
15535
15668
  console.error(`[route-shadow] introspection unavailable: ${err instanceof Error ? err.message : String(err)}`);
15536
15669
  }