@rubytech/create-maxy-code 0.1.316 → 0.1.318

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 (268) hide show
  1. package/package.json +2 -2
  2. package/payload/platform/lib/mcp-eager/dist/index.d.ts +0 -20
  3. package/payload/platform/lib/mcp-eager/dist/index.d.ts.map +1 -1
  4. package/payload/platform/lib/mcp-eager/dist/index.js +2 -1
  5. package/payload/platform/lib/mcp-eager/dist/index.js.map +1 -1
  6. package/payload/platform/lib/mcp-eager/src/index.ts +3 -1
  7. package/payload/platform/lib/mcp-lifeline/dist/index.d.ts +8 -0
  8. package/payload/platform/lib/mcp-lifeline/dist/index.d.ts.map +1 -0
  9. package/payload/platform/lib/mcp-lifeline/dist/index.js +71 -0
  10. package/payload/platform/lib/mcp-lifeline/dist/index.js.map +1 -0
  11. package/payload/platform/lib/mcp-lifeline/package.json +7 -0
  12. package/payload/platform/lib/mcp-lifeline/src/__tests__/lifeline.test.ts +146 -0
  13. package/payload/platform/lib/mcp-lifeline/src/index.ts +78 -0
  14. package/payload/platform/lib/mcp-lifeline/tsconfig.json +9 -0
  15. package/payload/platform/lib/mcp-lifeline/vitest.config.ts +9 -0
  16. package/payload/platform/lib/models/dist/index.d.ts +8 -0
  17. package/payload/platform/lib/models/dist/index.d.ts.map +1 -1
  18. package/payload/platform/lib/models/dist/index.js +20 -1
  19. package/payload/platform/lib/models/dist/index.js.map +1 -1
  20. package/payload/platform/lib/models/src/index.ts +22 -0
  21. package/payload/platform/package.json +5 -2
  22. package/payload/platform/plugins/admin/mcp/dist/index.js +11 -10
  23. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  24. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +19 -10
  25. package/payload/platform/plugins/docs/references/admin-ui.md +4 -2
  26. package/payload/platform/plugins/docs/references/internals.md +14 -7
  27. package/payload/platform/plugins/memory/mcp/dist/index.js +32 -31
  28. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  29. package/payload/platform/plugins/outlook/mcp/dist/index.js +8 -7
  30. package/payload/platform/plugins/outlook/mcp/dist/index.js.map +1 -1
  31. package/payload/platform/plugins/quickbooks/mcp/dist/index.js +12 -11
  32. package/payload/platform/plugins/quickbooks/mcp/dist/index.js.map +1 -1
  33. package/payload/platform/plugins/replicate/mcp/dist/index.js +4 -3
  34. package/payload/platform/plugins/replicate/mcp/dist/index.js.map +1 -1
  35. package/payload/platform/plugins/whatsapp/mcp/dist/index.js +11 -10
  36. package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
  37. package/payload/platform/scripts/__tests__/check-no-raw-mcp-registrations.test.sh +57 -0
  38. package/payload/platform/scripts/check-no-raw-mcp-registrations.mjs +70 -0
  39. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/http-server.js +57 -9
  41. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  42. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +5 -0
  43. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  44. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +7 -0
  45. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  46. package/payload/platform/services/claude-session-manager/dist/rc-daemon.d.ts.map +1 -1
  47. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +3 -12
  48. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  49. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts +8 -0
  50. package/payload/platform/services/claude-session-manager/dist/session-sidecar.d.ts.map +1 -1
  51. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js +9 -0
  52. package/payload/platform/services/claude-session-manager/dist/session-sidecar.js.map +1 -1
  53. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +5 -0
  54. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  55. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +15 -0
  56. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  57. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts +8 -0
  58. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.d.ts.map +1 -0
  59. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js +71 -0
  60. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/dist/index.js.map +1 -0
  61. package/payload/premium-plugins/writer-craft/lib/mcp-lifeline/package.json +7 -0
  62. package/payload/premium-plugins/writer-craft/mcp/dist/index.d.ts.map +1 -1
  63. package/payload/premium-plugins/writer-craft/mcp/dist/index.js +6 -5
  64. package/payload/premium-plugins/writer-craft/mcp/dist/index.js.map +1 -1
  65. package/payload/premium-plugins/writer-craft/mcp/src/index.ts +6 -5
  66. package/payload/server/{chunk-Q7EWROVN.js → chunk-NCRJQEZ3.js} +0 -101
  67. package/payload/server/maxy-edge.js +1 -1
  68. package/payload/server/public/assets/AdminLoginScreens-CrdmA3KA.js +1 -0
  69. package/payload/server/public/assets/AdminShell-0meAFBva.js +1 -0
  70. package/payload/server/public/assets/Checkbox-DXisJRUK.js +1 -0
  71. package/payload/server/public/assets/OperatorConversations-DBy2G8q3.js +9 -0
  72. package/payload/server/public/assets/OperatorConversations-DvRXfq3q.css +1 -0
  73. package/payload/server/public/assets/admin-DX5lZxWt.js +1 -0
  74. package/payload/server/public/assets/{arc-J2g2u5Xv.js → arc-CxLB9WCE.js} +1 -1
  75. package/payload/server/public/assets/architecture-YZFGNWBL-DN-MYxff.js +1 -0
  76. package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-CN0BXxpE.js → architectureDiagram-Q4EWVU46-D-EdJPSY.js} +1 -1
  77. package/payload/server/public/assets/{blockDiagram-DXYQGD6D-HX-8wF2p.js → blockDiagram-DXYQGD6D-CXx9RgCm.js} +1 -1
  78. package/payload/server/public/assets/browser-Bxx8w8BA.js +1 -0
  79. package/payload/server/public/assets/{c4Diagram-AHTNJAMY-wIuarKF5.js → c4Diagram-AHTNJAMY-RFBXEe0B.js} +1 -1
  80. package/payload/server/public/assets/channel-y27xl53N.js +1 -0
  81. package/payload/server/public/assets/chat-CT9YrNtI.js +1 -0
  82. package/payload/server/public/assets/{chunk-2KRD3SAO-Buz7egJZ.js → chunk-2KRD3SAO-DBqAFwK9.js} +1 -1
  83. package/payload/server/public/assets/{chunk-336JU56O-_JcFXJqc.js → chunk-336JU56O-DdnFEz6R.js} +2 -2
  84. package/payload/server/public/assets/chunk-426QAEUC-D8Iwaegm.js +1 -0
  85. package/payload/server/public/assets/{chunk-4BX2VUAB-DUR5Dg3M.js → chunk-4BX2VUAB-cnw-3Gbs.js} +1 -1
  86. package/payload/server/public/assets/{chunk-4TB4RGXK-BRIqQ9st.js → chunk-4TB4RGXK-BnqJ0bDc.js} +1 -1
  87. package/payload/server/public/assets/{chunk-55IACEB6-CezTHWXL.js → chunk-55IACEB6-BwyHvvzo.js} +1 -1
  88. package/payload/server/public/assets/{chunk-5FUZZQ4R-DHYUPzF1.js → chunk-5FUZZQ4R-DXA9U02I.js} +1 -1
  89. package/payload/server/public/assets/{chunk-5PVQY5BW-BVn4_fI5.js → chunk-5PVQY5BW-D78bZ_8D.js} +1 -1
  90. package/payload/server/public/assets/{chunk-67CJDMHE-BBLA8Mbi.js → chunk-67CJDMHE-CtE_Mgv7.js} +1 -1
  91. package/payload/server/public/assets/{chunk-7N4EOEYR-CdWfEI5c.js → chunk-7N4EOEYR-CUZDaySl.js} +1 -1
  92. package/payload/server/public/assets/{chunk-AA7GKIK3-tS11knCR.js → chunk-AA7GKIK3-CYQ3jO4X.js} +1 -1
  93. package/payload/server/public/assets/{chunk-BSJP7CBP-GEu1OOZ6.js → chunk-BSJP7CBP-BbA_HyTR.js} +1 -1
  94. package/payload/server/public/assets/{chunk-CIAEETIT-DKrNbbp_.js → chunk-CIAEETIT-D7_YqRhG.js} +1 -1
  95. package/payload/server/public/assets/{chunk-EDXVE4YY-B0InXNyr.js → chunk-EDXVE4YY-B23LrtSw.js} +1 -1
  96. package/payload/server/public/assets/{chunk-ENJZ2VHE-CO7lkHdm.js → chunk-ENJZ2VHE-D3fTHYKN.js} +1 -1
  97. package/payload/server/public/assets/{chunk-FMBD7UC4-CMj74lWo.js → chunk-FMBD7UC4-DFAA2tyh.js} +1 -1
  98. package/payload/server/public/assets/{chunk-FOC6F5B3-CLnKQoXw.js → chunk-FOC6F5B3-BF4IHvlI.js} +1 -1
  99. package/payload/server/public/assets/{chunk-ICPOFSXX-CdiEKIaz.js → chunk-ICPOFSXX-DBUGemHy.js} +2 -2
  100. package/payload/server/public/assets/{chunk-K5T4RW27-B6LA3fiv.js → chunk-K5T4RW27-rMMs08Eh.js} +1 -1
  101. package/payload/server/public/assets/{chunk-KGLVRYIC-DrhRrb8Q.js → chunk-KGLVRYIC-BD2r8R2G.js} +1 -1
  102. package/payload/server/public/assets/{chunk-LIHQZDEY-DVQukevB.js → chunk-LIHQZDEY-D4sYTTwM.js} +1 -1
  103. package/payload/server/public/assets/{chunk-ORNJ4GCN-ZMLkoDhP.js → chunk-ORNJ4GCN-CAs_uFzb.js} +1 -1
  104. package/payload/server/public/assets/{chunk-OYMX7WX6-C0dJkynG.js → chunk-OYMX7WX6-Fkp-2ORc.js} +1 -1
  105. package/payload/server/public/assets/chunk-QZHKN3VN-qHqDpwz3.js +1 -0
  106. package/payload/server/public/assets/{chunk-U2HBQHQK-BQ9BPIFZ.js → chunk-U2HBQHQK-D_pxZh25.js} +1 -1
  107. package/payload/server/public/assets/{chunk-X2U36JSP-CAonGMOd.js → chunk-X2U36JSP-CeVmvvRf.js} +1 -1
  108. package/payload/server/public/assets/{chunk-XPW4576I-D5C_WNlk.js → chunk-XPW4576I-iWP54fKp.js} +1 -1
  109. package/payload/server/public/assets/{chunk-YZCP3GAM-Ecdvzekb.js → chunk-YZCP3GAM-CNtbWJNN.js} +1 -1
  110. package/payload/server/public/assets/{chunk-ZZ45TVLE-BsFZd1cN.js → chunk-ZZ45TVLE-BmlFjU_9.js} +1 -1
  111. package/payload/server/public/assets/classDiagram-6PBFFD2Q-DgVoYWhO.js +1 -0
  112. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-C0WNP3uN.js +1 -0
  113. package/payload/server/public/assets/clone-D50F_pvg.js +1 -0
  114. package/payload/server/public/assets/{cose-bilkent-S5V4N54A-DBWHaIwm.js → cose-bilkent-S5V4N54A-C7YmF1Pg.js} +1 -1
  115. package/payload/server/public/assets/{dagre-Dr7ZJYeS.js → dagre-BAmiDDtR.js} +1 -1
  116. package/payload/server/public/assets/{dagre-KV5264BT-oIJddk7m.js → dagre-KV5264BT-Ca3ESJhc.js} +1 -1
  117. package/payload/server/public/assets/data-B9NtsXgF.js +1 -0
  118. package/payload/server/public/assets/{diagram-5BDNPKRD-CEVxqOZ4.js → diagram-5BDNPKRD-BgT1ORf2.js} +1 -1
  119. package/payload/server/public/assets/{diagram-G4DWMVQ6-BovF7Rjx.js → diagram-G4DWMVQ6-BTaUIiem.js} +1 -1
  120. package/payload/server/public/assets/{diagram-MMDJMWI5-BhrF8zoF.js → diagram-MMDJMWI5-Bdb2g6Uo.js} +1 -1
  121. package/payload/server/public/assets/{diagram-TYMM5635-DCUYwxtR.js → diagram-TYMM5635-CkLGC0zZ.js} +1 -1
  122. package/payload/server/public/assets/{dist-DSsFp0Qd.js → dist-Bkbhs3jw.js} +1 -1
  123. package/payload/server/public/assets/{erDiagram-SMLLAGMA-BS2-HdCg.js → erDiagram-SMLLAGMA-D_sj4DMg.js} +1 -1
  124. package/payload/server/public/assets/{flatten-BZMXCpLh.js → flatten-E2Sr0FeD.js} +1 -1
  125. package/payload/server/public/assets/{flowDiagram-DWJPFMVM-BzSFLoea.js → flowDiagram-DWJPFMVM-iLERoZTe.js} +1 -1
  126. package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-1-3QU7mT.js → ganttDiagram-T4ZO3ILL-D60hjMBy.js} +1 -1
  127. package/payload/server/public/assets/gitGraph-7Q5UKJZL-D-L2yzYf.js +1 -0
  128. package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-fTrJ35Wk.js → gitGraphDiagram-UUTBAWPF-Di0XM6fi.js} +1 -1
  129. package/payload/server/public/assets/{graph-BZNc3EXa.js → graph-B59N222f.js} +3 -3
  130. package/payload/server/public/assets/graph-labels-70w-1ov0.js +1 -0
  131. package/payload/server/public/assets/{graphlib-rlEzI2qD.js → graphlib-C8fUP7uV.js} +1 -1
  132. package/payload/server/public/assets/info-OMHHGYJF-BQn6jndO.js +1 -0
  133. package/payload/server/public/assets/infoDiagram-42DDH7IO-BwMdbiXg.js +2 -0
  134. package/payload/server/public/assets/{isEmpty-DaYIrHay.js → isEmpty-CLz-UprQ.js} +1 -1
  135. package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-0eU_UtlT.js → ishikawaDiagram-UXIWVN3A-CwgI4B5Z.js} +1 -1
  136. package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-BKLeZohp.js → journeyDiagram-VCZTEJTY-CxBu-tze.js} +1 -1
  137. package/payload/server/public/assets/{kanban-definition-6JOO6SKY-Dq72xyaN.js → kanban-definition-6JOO6SKY-D2qlheA5.js} +1 -1
  138. package/payload/server/public/assets/{line-LQhmDT8k.js → line-Bdod7uzQ.js} +1 -1
  139. package/payload/server/public/assets/{linear-BGotDbGs.js → linear-BiVe6QzC.js} +1 -1
  140. package/payload/server/public/assets/{mermaid-parser.core-DoLdho1V.js → mermaid-parser.core-xZN7hC6M.js} +2 -2
  141. package/payload/server/public/assets/{mermaid.core-C1RRyHGm.js → mermaid.core-D0IylAac.js} +3 -3
  142. package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-vUVVVyV1.js → mindmap-definition-QFDTVHPH-J_Szhwf1.js} +1 -1
  143. package/payload/server/public/assets/operator-DpRAhwQN.js +1 -0
  144. package/payload/server/public/assets/{ordinal-BqEhkPyh.js → ordinal-5RtyPJVt.js} +1 -1
  145. package/payload/server/public/assets/packet-4T2RLAQJ-DmkQBx4h.js +1 -0
  146. package/payload/server/public/assets/page-Ehjc9b9V.js +30 -0
  147. package/payload/server/public/assets/pie-ZZUOXDRM-DDnxYUBm.js +1 -0
  148. package/payload/server/public/assets/{pieDiagram-DEJITSTG-B9Pl6Qhc.js → pieDiagram-DEJITSTG-CV5DxUVx.js} +1 -1
  149. package/payload/server/public/assets/public-BcqXGSaE.js +1 -0
  150. package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-Drn9T81A.js → quadrantDiagram-34T5L4WZ-BsFMVizF.js} +1 -1
  151. package/payload/server/public/assets/radar-PYXPWWZC-7H4k0ChM.js +1 -0
  152. package/payload/server/public/assets/{reduce-T2IuntYP.js → reduce-B3Mw_0s1.js} +1 -1
  153. package/payload/server/public/assets/{requirementDiagram-MS252O5E-C0PAItJm.js → requirementDiagram-MS252O5E-C5eRRvGc.js} +1 -1
  154. package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-BR42Mtwd.js → sankeyDiagram-XADWPNL6-CJYv5gpw.js} +1 -1
  155. package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-c2lR9UOS.js → sequenceDiagram-FGHM5R23-B25563_2.js} +1 -1
  156. package/payload/server/public/assets/{src-DXUM2BJo.js → src-BKOAoFQc.js} +1 -1
  157. package/payload/server/public/assets/{stateDiagram-FHFEXIEX-BcHhtqsZ.js → stateDiagram-FHFEXIEX-BLyNJYOA.js} +1 -1
  158. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BSVuxZxz.js +1 -0
  159. package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-Ax32c10H.js → timeline-definition-GMOUNBTQ-D-HgOM6Q.js} +1 -1
  160. package/payload/server/public/assets/treeView-SZITEDCU-BLXWTQtW.js +1 -0
  161. package/payload/server/public/assets/treemap-W4RFUUIX-DiePDF5d.js +1 -0
  162. package/payload/server/public/assets/{vennDiagram-DHZGUBPP-BxePewPq.js → vennDiagram-DHZGUBPP-Cw1JElYp.js} +1 -1
  163. package/payload/server/public/assets/wardley-RL74JXVD-OSUWK5LN.js +1 -0
  164. package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-DmJwZ2f5.js → wardleyDiagram-NUSXRM2D-BqMWzEko.js} +1 -1
  165. package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-YjHomudv.js → xychartDiagram-5P7HB3ND-DBp71TLT.js} +1 -1
  166. package/payload/server/public/browser.html +5 -8
  167. package/payload/server/public/chat.html +8 -12
  168. package/payload/server/public/data.html +5 -7
  169. package/payload/server/public/graph.html +7 -10
  170. package/payload/server/public/index.html +8 -11
  171. package/payload/server/public/operator.html +10 -14
  172. package/payload/server/public/public.html +8 -10
  173. package/payload/server/server.js +276 -219
  174. package/payload/server/public/assets/AccessGate-bu988Xo-.js +0 -1
  175. package/payload/server/public/assets/AdminLoginScreens-BCYaOOuk.js +0 -1
  176. package/payload/server/public/assets/AdminShell-DSjJ4Biu.js +0 -1
  177. package/payload/server/public/assets/Checkbox-B4Dbvjls.js +0 -1
  178. package/payload/server/public/assets/OperatorConversations-XsXP7-P-.js +0 -1
  179. package/payload/server/public/assets/OperatorConversations-qc_xy7Az.css +0 -1
  180. package/payload/server/public/assets/admin-m0797WGA.js +0 -1
  181. package/payload/server/public/assets/architecture-YZFGNWBL-C6nkAxzW.js +0 -1
  182. package/payload/server/public/assets/audio-attachment-mime-Jm4KJ4YC.js +0 -30
  183. package/payload/server/public/assets/brand-D8LClgr_.js +0 -9
  184. package/payload/server/public/assets/brand-DvttVeGB.css +0 -1
  185. package/payload/server/public/assets/browser-CBjNMPsz.js +0 -1
  186. package/payload/server/public/assets/channel-Q39xIXyT.js +0 -1
  187. package/payload/server/public/assets/chat-Sg-RGuV6.js +0 -1
  188. package/payload/server/public/assets/chunk-426QAEUC-CCYjp9C2.js +0 -1
  189. package/payload/server/public/assets/chunk-QZHKN3VN-BNBxnHZh.js +0 -1
  190. package/payload/server/public/assets/classDiagram-6PBFFD2Q-BShusfby.js +0 -1
  191. package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-D4ivPLFF.js +0 -1
  192. package/payload/server/public/assets/clone-CjEM8LwB.js +0 -1
  193. package/payload/server/public/assets/data-CEqE4BDw.js +0 -1
  194. package/payload/server/public/assets/gitGraph-7Q5UKJZL-Btp3PwZh.js +0 -1
  195. package/payload/server/public/assets/graph-labels-Bj5yM9bI.js +0 -1
  196. package/payload/server/public/assets/info-OMHHGYJF-CPt2y6_L.js +0 -1
  197. package/payload/server/public/assets/infoDiagram-42DDH7IO-CpXNTMgd.js +0 -2
  198. package/payload/server/public/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
  199. package/payload/server/public/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
  200. package/payload/server/public/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
  201. package/payload/server/public/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
  202. package/payload/server/public/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
  203. package/payload/server/public/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
  204. package/payload/server/public/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
  205. package/payload/server/public/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
  206. package/payload/server/public/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
  207. package/payload/server/public/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
  208. package/payload/server/public/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
  209. package/payload/server/public/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
  210. package/payload/server/public/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
  211. package/payload/server/public/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
  212. package/payload/server/public/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
  213. package/payload/server/public/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
  214. package/payload/server/public/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  215. package/payload/server/public/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
  216. package/payload/server/public/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
  217. package/payload/server/public/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  218. package/payload/server/public/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
  219. package/payload/server/public/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
  220. package/payload/server/public/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
  221. package/payload/server/public/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
  222. package/payload/server/public/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
  223. package/payload/server/public/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
  224. package/payload/server/public/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
  225. package/payload/server/public/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
  226. package/payload/server/public/assets/newsreader-latin-300-normal-AOSWdb_s.woff +0 -0
  227. package/payload/server/public/assets/newsreader-latin-300-normal-FGBQ0wlI.woff2 +0 -0
  228. package/payload/server/public/assets/newsreader-latin-400-normal-BFBkh4jY.woff2 +0 -0
  229. package/payload/server/public/assets/newsreader-latin-400-normal-gRTjlS2D.woff +0 -0
  230. package/payload/server/public/assets/newsreader-latin-500-normal-B66TYsaK.woff2 +0 -0
  231. package/payload/server/public/assets/newsreader-latin-500-normal-DFwuUcdu.woff +0 -0
  232. package/payload/server/public/assets/newsreader-latin-ext-300-normal-CFtw49Zd.woff +0 -0
  233. package/payload/server/public/assets/newsreader-latin-ext-300-normal-DRMzurxT.woff2 +0 -0
  234. package/payload/server/public/assets/newsreader-latin-ext-400-normal-DYA1XoQK.woff +0 -0
  235. package/payload/server/public/assets/newsreader-latin-ext-400-normal-svq1FPys.woff2 +0 -0
  236. package/payload/server/public/assets/newsreader-latin-ext-500-normal-BNHmvKvI.woff2 +0 -0
  237. package/payload/server/public/assets/newsreader-latin-ext-500-normal-CZruMFou.woff +0 -0
  238. package/payload/server/public/assets/newsreader-vietnamese-300-normal-CsrIkm-V.woff +0 -0
  239. package/payload/server/public/assets/newsreader-vietnamese-300-normal-D3VHEe81.woff2 +0 -0
  240. package/payload/server/public/assets/newsreader-vietnamese-400-normal-BekUZro8.woff +0 -0
  241. package/payload/server/public/assets/newsreader-vietnamese-400-normal-DdKr49mV.woff2 +0 -0
  242. package/payload/server/public/assets/newsreader-vietnamese-500-normal-BEAbKU8A.woff +0 -0
  243. package/payload/server/public/assets/newsreader-vietnamese-500-normal-CL6a8tp2.woff2 +0 -0
  244. package/payload/server/public/assets/operator-Bph7mx87.js +0 -1
  245. package/payload/server/public/assets/packet-4T2RLAQJ-Cwc-j_AI.js +0 -1
  246. package/payload/server/public/assets/page-CtWCeXdg.js +0 -1
  247. package/payload/server/public/assets/pie-ZZUOXDRM-BZ9fjD1_.js +0 -1
  248. package/payload/server/public/assets/public-gxHCJCs3.js +0 -6
  249. package/payload/server/public/assets/public-next-C3clISGQ.js +0 -1
  250. package/payload/server/public/assets/public-vnj7OhQj.css +0 -1
  251. package/payload/server/public/assets/radar-PYXPWWZC-BNz5Rt9V.js +0 -1
  252. package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BUQ_F4eP.js +0 -1
  253. package/payload/server/public/assets/treeView-SZITEDCU-DcVCQgp1.js +0 -1
  254. package/payload/server/public/assets/treemap-W4RFUUIX-Bm12mwGd.js +0 -1
  255. package/payload/server/public/assets/useSelectionMode-BMn70cch.js +0 -5
  256. package/payload/server/public/assets/wardley-RL74JXVD-47Z3ymtK.js +0 -1
  257. package/payload/server/public/public-next.html +0 -25
  258. /package/payload/server/public/assets/{_baseFor-Y5mTRiRv.js → _baseFor-DVaNaTfF.js} +0 -0
  259. /package/payload/server/public/assets/{admin-types-D2qTXuCg.js → admin-types-CJrGd46U.js} +0 -0
  260. /package/payload/server/public/assets/{array-BwJyW1Dp.js → array-8_H1156C.js} +0 -0
  261. /package/payload/server/public/assets/{chunk-CAM3fms7.js → chunk-Pqm5yXtL.js} +0 -0
  262. /package/payload/server/public/assets/{cytoscape.esm-D95TtHqz.js → cytoscape.esm-h10p_6j-.js} +0 -0
  263. /package/payload/server/public/assets/{defaultLocale-kiwRz9Au.js → defaultLocale-pD7tFa1r.js} +0 -0
  264. /package/payload/server/public/assets/{init-CKZirZ49.js → init-CwJ4b81e.js} +0 -0
  265. /package/payload/server/public/assets/{katex-8mXVa4k3.js → katex-DJPjIBAI.js} +0 -0
  266. /package/payload/server/public/assets/{path-B0d9ncVi.js → path-CK8wrAxY.js} +0 -0
  267. /package/payload/server/public/assets/{preload-helper-C5gCWwwF.js → preload-helper-Bf_JiD2A.js} +0 -0
  268. /package/payload/server/public/assets/{rough.esm-BWqoIFNR.js → rough.esm-Dwml_la6.js} +0 -0
@@ -27,9 +27,7 @@ import {
27
27
  WEBSOCKIFY_PORT,
28
28
  accessPasswordCollides,
29
29
  autoDeliverPremiumPlugins,
30
- bindVisitorToGroup,
31
30
  canAccessAdmin,
32
- checkGroupMembership,
33
31
  checkRateLimit,
34
32
  classifyHost,
35
33
  cleanupLeakedPremiumSubs,
@@ -42,7 +40,6 @@ import {
42
40
  emitMissingOnResolve,
43
41
  ensureConversation,
44
42
  fetchBranding,
45
- findGroupBySlug,
46
43
  findMissingPlugins,
47
44
  findRecentConversation,
48
45
  fingerprintSessionKey,
@@ -50,7 +47,6 @@ import {
50
47
  getAgentSessionIdForConversation,
51
48
  getConversationClaudeSessionIds,
52
49
  getDefaultAccountId,
53
- getGroupParticipants,
54
50
  getOperatorDomains,
55
51
  getRecentMessages,
56
52
  getRoleForSession,
@@ -110,7 +106,7 @@ import {
110
106
  vncLog,
111
107
  walkPremiumBundles,
112
108
  writeAdminUserAndPerson
113
- } from "./chunk-Q7EWROVN.js";
109
+ } from "./chunk-NCRJQEZ3.js";
114
110
  import {
115
111
  __commonJS,
116
112
  __toESM
@@ -532,63 +528,63 @@ var require_dist2 = __commonJS({
532
528
  }
533
529
  function pickShortLabel(node) {
534
530
  const props = node.properties;
535
- const primaryLabel = node.labels[0];
536
- if (primaryLabel === "ToolCall") {
531
+ const primaryLabel2 = node.labels[0];
532
+ if (primaryLabel2 === "ToolCall") {
537
533
  const v = props.toolName;
538
534
  if (typeof v === "string" && v.length > 0) {
539
535
  return v.length > 24 ? v.slice(0, 24) + "\u2026" : v;
540
536
  }
541
- } else if (primaryLabel === "WorkflowRun") {
537
+ } else if (primaryLabel2 === "WorkflowRun") {
542
538
  const v = props.startedAt;
543
539
  if (typeof v === "string" && v.length > 0) {
544
540
  const ts = formatRunTimestamp(v);
545
541
  if (ts)
546
542
  return ts;
547
543
  }
548
- } else if (primaryLabel === "WorkflowStep") {
544
+ } else if (primaryLabel2 === "WorkflowStep") {
549
545
  const v = props.label;
550
546
  if (typeof v === "string" && v.length > 0) {
551
547
  return v.length > 24 ? v.slice(0, 24) + "\u2026" : v;
552
548
  }
553
- } else if (primaryLabel === "Person") {
549
+ } else if (primaryLabel2 === "Person") {
554
550
  const given = typeof props.givenName === "string" ? props.givenName : "";
555
551
  const family = typeof props.familyName === "string" ? props.familyName : "";
556
552
  const full = [given, family].filter((s) => s.length > 0).join(" ");
557
553
  if (full.length > 0) {
558
554
  return full.length > 24 ? full.slice(0, 24) + "\u2026" : full;
559
555
  }
560
- } else if (primaryLabel === "Agent") {
556
+ } else if (primaryLabel2 === "Agent") {
561
557
  const dn = typeof props.displayName === "string" ? props.displayName : "";
562
558
  const slug = typeof props.slug === "string" ? props.slug : "";
563
559
  const v = dn.length > 0 ? dn : slug;
564
560
  if (v.length > 0) {
565
561
  return v.length > 24 ? v.slice(0, 24) + "\u2026" : v;
566
562
  }
567
- } else if (primaryLabel === "Job") {
563
+ } else if (primaryLabel2 === "Job") {
568
564
  const client = typeof props.client === "string" ? props.client : "";
569
565
  const jobId = typeof props.jobId === "string" ? props.jobId : "";
570
566
  const composed = [client, jobId.length > 0 ? `#${jobId}` : ""].filter((s) => s.length > 0).join(" ");
571
567
  if (composed.length > 0) {
572
568
  return composed.length > 24 ? composed.slice(0, 24) + "\u2026" : composed;
573
569
  }
574
- } else if (primaryLabel === "QuoteDocument") {
570
+ } else if (primaryLabel2 === "QuoteDocument") {
575
571
  const ref = typeof props.ref === "string" ? props.ref : "";
576
572
  if (ref.length > 0) {
577
573
  return ref.length > 24 ? ref.slice(0, 24) + "\u2026" : ref;
578
574
  }
579
- } else if (primaryLabel === "InboundInvoice") {
575
+ } else if (primaryLabel2 === "InboundInvoice") {
580
576
  const supplier = typeof props.supplier === "string" ? props.supplier : "";
581
577
  const conf = typeof props.confirmationNumber === "string" ? props.confirmationNumber : "";
582
578
  const composed = [supplier, conf.length > 0 ? `#${conf}` : ""].filter((s) => s.length > 0).join(" ");
583
579
  if (composed.length > 0) {
584
580
  return composed.length > 24 ? composed.slice(0, 24) + "\u2026" : composed;
585
581
  }
586
- } else if (primaryLabel === "WhatsAppGroup") {
582
+ } else if (primaryLabel2 === "WhatsAppGroup") {
587
583
  const clientName = typeof props.clientName === "string" ? props.clientName : "";
588
584
  if (clientName.length > 0) {
589
585
  return clientName.length > 24 ? clientName.slice(0, 24) + "\u2026" : clientName;
590
586
  }
591
- } else if (primaryLabel === "Message") {
587
+ } else if (primaryLabel2 === "Message") {
592
588
  const role = typeof props.role === "string" ? props.role : "";
593
589
  const roleShort = role === "user" ? "user" : role === "assistant" ? "asst" : role === "system" ? "sys" : role === "tool" ? "tool" : null;
594
590
  const createdAt = typeof props.createdAt === "string" ? props.createdAt : "";
@@ -604,60 +600,60 @@ var require_dist2 = __commonJS({
604
600
  return v.length > 24 ? v.slice(0, 24) + "\u2026" : v;
605
601
  }
606
602
  }
607
- if (primaryLabel === "Conversation") {
603
+ if (primaryLabel2 === "Conversation") {
608
604
  const id = typeof props.sessionId === "string" ? props.sessionId : null;
609
605
  if (id)
610
606
  return `Conv ${id.slice(0, 8)}`;
611
607
  }
612
- return primaryLabel ?? "\u2026";
608
+ return primaryLabel2 ?? "\u2026";
613
609
  }
614
610
  function pickDisplayName(node) {
615
611
  const props = node.properties;
616
- const primaryLabel = node.labels[0];
617
- if (primaryLabel === "ToolCall") {
612
+ const primaryLabel2 = node.labels[0];
613
+ if (primaryLabel2 === "ToolCall") {
618
614
  const v = props.toolName;
619
615
  if (typeof v === "string" && v.length > 0)
620
616
  return v;
621
- } else if (primaryLabel === "WorkflowRun") {
617
+ } else if (primaryLabel2 === "WorkflowRun") {
622
618
  const v = props.startedAt;
623
619
  if (typeof v === "string" && v.length > 0) {
624
620
  const ts = formatRunTimestamp(v);
625
621
  if (ts)
626
622
  return ts;
627
623
  }
628
- } else if (primaryLabel === "WorkflowStep") {
624
+ } else if (primaryLabel2 === "WorkflowStep") {
629
625
  const v = props.label;
630
626
  if (typeof v === "string" && v.length > 0)
631
627
  return v;
632
- } else if (primaryLabel === "Person") {
628
+ } else if (primaryLabel2 === "Person") {
633
629
  const given = typeof props.givenName === "string" ? props.givenName : "";
634
630
  const family = typeof props.familyName === "string" ? props.familyName : "";
635
631
  const full = [given, family].filter((s) => s.length > 0).join(" ");
636
632
  if (full.length > 0)
637
633
  return full;
638
- } else if (primaryLabel === "Agent") {
634
+ } else if (primaryLabel2 === "Agent") {
639
635
  const dn = typeof props.displayName === "string" ? props.displayName : "";
640
636
  const slug = typeof props.slug === "string" ? props.slug : "";
641
637
  const v = dn.length > 0 ? dn : slug;
642
638
  if (v.length > 0)
643
639
  return v;
644
- } else if (primaryLabel === "Job") {
640
+ } else if (primaryLabel2 === "Job") {
645
641
  const client = typeof props.client === "string" ? props.client : "";
646
642
  const jobId = typeof props.jobId === "string" ? props.jobId : "";
647
643
  const composed = [client, jobId.length > 0 ? `#${jobId}` : ""].filter((s) => s.length > 0).join(" ");
648
644
  if (composed.length > 0)
649
645
  return composed;
650
- } else if (primaryLabel === "QuoteDocument") {
646
+ } else if (primaryLabel2 === "QuoteDocument") {
651
647
  const ref = typeof props.ref === "string" ? props.ref : "";
652
648
  if (ref.length > 0)
653
649
  return ref;
654
- } else if (primaryLabel === "InboundInvoice") {
650
+ } else if (primaryLabel2 === "InboundInvoice") {
655
651
  const supplier = typeof props.supplier === "string" ? props.supplier : "";
656
652
  const conf = typeof props.confirmationNumber === "string" ? props.confirmationNumber : "";
657
653
  const composed = [supplier, conf.length > 0 ? `#${conf}` : ""].filter((s) => s.length > 0).join(" ");
658
654
  if (composed.length > 0)
659
655
  return composed;
660
- } else if (primaryLabel === "WhatsAppGroup") {
656
+ } else if (primaryLabel2 === "WhatsAppGroup") {
661
657
  const clientName = typeof props.clientName === "string" ? props.clientName : "";
662
658
  if (clientName.length > 0)
663
659
  return clientName;
@@ -667,12 +663,12 @@ var require_dist2 = __commonJS({
667
663
  if (typeof v === "string" && v.length > 0)
668
664
  return v;
669
665
  }
670
- if (primaryLabel === "Conversation") {
666
+ if (primaryLabel2 === "Conversation") {
671
667
  const id = typeof props.sessionId === "string" ? props.sessionId : null;
672
668
  if (id)
673
669
  return `Conv ${id.slice(0, 8)}`;
674
670
  }
675
- return primaryLabel ?? "\u2026";
671
+ return primaryLabel2 ?? "\u2026";
676
672
  }
677
673
  }
678
674
  });
@@ -7953,18 +7949,37 @@ var UUID = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-f
7953
7949
  function canonicalOverridePath(accountDir) {
7954
7950
  return join13(accountDir, FILE);
7955
7951
  }
7956
- function readCanonicalOverrideId(accountDir) {
7952
+ function readRaw(accountDir) {
7957
7953
  try {
7958
- const raw = JSON.parse(readFileSync14(canonicalOverridePath(accountDir), "utf8"));
7959
- return typeof raw.sessionId === "string" && UUID.test(raw.sessionId) ? raw.sessionId : null;
7954
+ return JSON.parse(readFileSync14(canonicalOverridePath(accountDir), "utf8"));
7960
7955
  } catch {
7961
7956
  return null;
7962
7957
  }
7963
7958
  }
7964
- function writeCanonicalOverrideId(accountDir, sessionId) {
7959
+ function readCanonicalOverrideId(accountDir, userId, primaryUserId) {
7960
+ const raw = readRaw(accountDir);
7961
+ if (!raw) return null;
7962
+ if (raw.byAdmin && typeof raw.byAdmin === "object") {
7963
+ const v = raw.byAdmin[userId];
7964
+ return typeof v === "string" && UUID.test(v) ? v : null;
7965
+ }
7966
+ if (typeof raw.sessionId === "string" && UUID.test(raw.sessionId) && primaryUserId !== null && userId === primaryUserId) {
7967
+ return raw.sessionId;
7968
+ }
7969
+ return null;
7970
+ }
7971
+ function writeCanonicalOverrideId(accountDir, userId, sessionId) {
7972
+ const raw = readRaw(accountDir);
7973
+ const byAdmin = {};
7974
+ if (raw?.byAdmin && typeof raw.byAdmin === "object") {
7975
+ for (const [k, v] of Object.entries(raw.byAdmin)) {
7976
+ if (typeof v === "string") byAdmin[k] = v;
7977
+ }
7978
+ }
7979
+ byAdmin[userId] = sessionId;
7965
7980
  const path2 = canonicalOverridePath(accountDir);
7966
7981
  const tmp = `${path2}.${process.pid}.tmp`;
7967
- writeFileSync5(tmp, JSON.stringify({ sessionId }, null, 2), "utf8");
7982
+ writeFileSync5(tmp, JSON.stringify({ byAdmin }, null, 2), "utf8");
7968
7983
  renameSync(tmp, path2);
7969
7984
  }
7970
7985
 
@@ -7980,6 +7995,33 @@ function adminSessionIdFor(accountId, senderId, personId) {
7980
7995
  return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`;
7981
7996
  }
7982
7997
 
7998
+ // ../lib/models/src/index.ts
7999
+ var OPUS_MODEL = "claude-opus-4-8[1m]";
8000
+ var SONNET_MODEL = "claude-sonnet-4-6";
8001
+ var HAIKU_MODEL = "claude-haiku-4-5";
8002
+ var MODEL_CONTEXT_WINDOW = {
8003
+ [OPUS_MODEL]: 1e6,
8004
+ [SONNET_MODEL]: 2e5,
8005
+ [HAIKU_MODEL]: 2e5
8006
+ };
8007
+ var MODEL_DISPLAY_NAMES = {
8008
+ [OPUS_MODEL]: "Opus 4.8 (1M context)",
8009
+ [SONNET_MODEL]: "Sonnet 4.6",
8010
+ [HAIKU_MODEL]: "Haiku 4.5"
8011
+ };
8012
+ var SELECTABLE_MODELS = [OPUS_MODEL, SONNET_MODEL, HAIKU_MODEL];
8013
+ function isSelectableModel(id) {
8014
+ return SELECTABLE_MODELS.includes(id);
8015
+ }
8016
+ var PERMISSION_MODES = ["default", "acceptEdits", "plan", "auto", "bypassPermissions"];
8017
+ function isPermissionMode(value) {
8018
+ return PERMISSION_MODES.includes(value);
8019
+ }
8020
+ var EFFORT_LEVELS = ["low", "medium", "high", "xhigh"];
8021
+ function isEffortLevel(value) {
8022
+ return EFFORT_LEVELS.includes(value);
8023
+ }
8024
+
7983
8025
  // ../services/claude-session-manager/src/sidecar-store.ts
7984
8026
  import { existsSync as existsSync8, mkdirSync as mkdirSync2, readdirSync as readdirSync9, readFileSync as readFileSync15, renameSync as renameSync2, unlinkSync, writeFileSync as writeFileSync6 } from "fs";
7985
8027
  import { join as join14 } from "path";
@@ -8133,11 +8175,25 @@ function locateSidecar(sessionId) {
8133
8175
  for (const slug of slugs) {
8134
8176
  const metaPath = join15(projectsRoot, slug, `${sessionId}.meta.json`);
8135
8177
  if (existsSync9(metaPath)) {
8136
- return { channel: readSidecarMeta(metaPath).channel };
8178
+ const meta = readSidecarMeta(metaPath);
8179
+ return { channel: meta.channel, adminUserId: meta.adminUserId };
8137
8180
  }
8138
8181
  }
8139
8182
  return null;
8140
8183
  }
8184
+ function readTargetOwner(sessionId) {
8185
+ const sidecar = locateSidecar(sessionId);
8186
+ if (sidecar !== null) return { found: true, owner: sidecar.adminUserId };
8187
+ const { projectDir } = locateSession(sessionId);
8188
+ if (projectDir !== null) {
8189
+ return { found: true, owner: readSidecarMeta(join15(projectDir, `${sessionId}.meta.json`)).adminUserId };
8190
+ }
8191
+ return { found: false, owner: null };
8192
+ }
8193
+ function ownedByRequester(owner, requesterUserId, primaryUserId) {
8194
+ if (requesterUserId === null) return false;
8195
+ return owner === requesterUserId || owner === null && requesterUserId === primaryUserId;
8196
+ }
8141
8197
  function sessionSidecarExists(sessionId) {
8142
8198
  return locateSidecar(sessionId) !== null;
8143
8199
  }
@@ -8188,8 +8244,6 @@ async function fetchComposerIndicators(sessionId) {
8188
8244
  }
8189
8245
  }
8190
8246
  var MODEL_ID_PATTERN = /^claude-[a-z0-9][a-z0-9.-]*(\[1m\])?$/;
8191
- var EFFORT_LEVELS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh"]);
8192
- var PERMISSION_MODE_VALUES = /* @__PURE__ */ new Set(["default", "acceptEdits", "plan", "auto", "bypassPermissions"]);
8193
8247
  function readLevers(preResolved) {
8194
8248
  let account = preResolved;
8195
8249
  if (account === void 0) {
@@ -8205,11 +8259,20 @@ function readLevers(preResolved) {
8205
8259
  const mode = account.config.adminPermissionMode;
8206
8260
  return {
8207
8261
  leverModel: typeof model === "string" && MODEL_ID_PATTERN.test(model) ? model : null,
8208
- leverEffort: typeof effort === "string" && EFFORT_LEVELS.has(effort) ? effort : null,
8209
- leverMode: typeof mode === "string" && PERMISSION_MODE_VALUES.has(mode) ? mode : null
8262
+ leverEffort: typeof effort === "string" && isEffortLevel(effort) ? effort : null,
8263
+ leverMode: typeof mode === "string" && isPermissionMode(mode) ? mode : null
8210
8264
  };
8211
8265
  }
8212
- function latestAdminWebchatSessionId() {
8266
+ function resolvePrimaryAdminUserId() {
8267
+ try {
8268
+ const users = readUsersFile(USERS_FILE);
8269
+ return users && users.length > 0 ? users[0].userId : null;
8270
+ } catch {
8271
+ return null;
8272
+ }
8273
+ }
8274
+ function latestAdminWebchatSessionId(requesterUserId, primaryUserId) {
8275
+ if (requesterUserId === null) return null;
8213
8276
  const cfg = claudeConfigDir();
8214
8277
  if (!cfg) return null;
8215
8278
  let best = null;
@@ -8224,6 +8287,13 @@ function latestAdminWebchatSessionId() {
8224
8287
  } catch {
8225
8288
  continue;
8226
8289
  }
8290
+ const owned = meta.adminUserId === requesterUserId || meta.adminUserId === null && requesterUserId === primaryUserId;
8291
+ if (!owned) {
8292
+ if (best === null || mtimeMs > best.mtimeMs) {
8293
+ console.error(`[webchat:inbound] op=owner-skip candidate=${id.slice(0, 8)} owner=${meta.adminUserId ? meta.adminUserId.slice(0, 8) : "none"} requester=${requesterUserId.slice(0, 8)}`);
8294
+ }
8295
+ continue;
8296
+ }
8227
8297
  if (best === null || mtimeMs > best.mtimeMs) best = { id, mtimeMs };
8228
8298
  }
8229
8299
  return best === null ? null : best.id;
@@ -8233,14 +8303,17 @@ function overrideKnownNonArchived(id) {
8233
8303
  if (projectDir === null) return sessionSidecarExists(id);
8234
8304
  return basename4(projectDir) !== "archive";
8235
8305
  }
8236
- function resolveCanonical(accountId, accountDir) {
8237
- const latest = latestAdminWebchatSessionId();
8306
+ function resolveCanonical(accountId, accountDir, requesterUserId, primaryUserId) {
8307
+ if (requesterUserId === null) {
8308
+ return { sessionId: adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY), source: "canonical-empty" };
8309
+ }
8310
+ const latest = latestAdminWebchatSessionId(requesterUserId, primaryUserId);
8238
8311
  if (latest !== null) return { sessionId: latest, source: "latest" };
8239
8312
  if (accountDir) {
8240
- const override = readCanonicalOverrideId(accountDir);
8313
+ const override = readCanonicalOverrideId(accountDir, requesterUserId, primaryUserId);
8241
8314
  if (override && overrideKnownNonArchived(override)) return { sessionId: override, source: "override" };
8242
8315
  }
8243
- return { sessionId: adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY), source: "canonical-empty" };
8316
+ return { sessionId: adminSessionIdFor(accountId, WEBCHAT_ADMIN_KEY, requesterUserId), source: "canonical-empty" };
8244
8317
  }
8245
8318
  var REAPPLY_TIMEOUT_MS = 1500;
8246
8319
  async function reapplyLeversViaManager() {
@@ -8273,6 +8346,9 @@ function createWebchatRoutes(deps) {
8273
8346
  console.error(`[webchat:inbound] op=send-refused reason=account-unresolved detail=${detail}`);
8274
8347
  return c.json({ error: "account unresolved" }, 503);
8275
8348
  }
8349
+ const cacheKey = c.get("cacheKey");
8350
+ const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
8351
+ const primaryUserId = resolvePrimaryAdminUserId();
8276
8352
  let text;
8277
8353
  let target;
8278
8354
  let files = [];
@@ -8313,10 +8389,18 @@ function createWebchatRoutes(deps) {
8313
8389
  }
8314
8390
  let deliveryKey = WEBCHAT_ADMIN_KEY;
8315
8391
  let deliverySessionId;
8392
+ const explicitTarget = target !== void 0;
8316
8393
  if (target === void 0) {
8317
- const latest = latestAdminWebchatSessionId();
8394
+ const latest = latestAdminWebchatSessionId(requesterUserId, primaryUserId);
8318
8395
  if (latest !== null) target = latest;
8319
8396
  }
8397
+ if (explicitTarget && target !== void 0) {
8398
+ const t = readTargetOwner(target);
8399
+ if (t.found && !ownedByRequester(t.owner, requesterUserId, primaryUserId)) {
8400
+ console.error(`[webchat:inbound] op=send-refused key=session:${target.slice(0, 8)} reason=foreign-target requester=${requesterUserId ? requesterUserId.slice(0, 8) : "none"}`);
8401
+ return c.json({ error: "session not found" }, 404);
8402
+ }
8403
+ }
8320
8404
  if (target !== void 0) {
8321
8405
  let { projectDir, channel } = locateSession(target);
8322
8406
  if (projectDir === null) {
@@ -8392,10 +8476,11 @@ ${note}` : note;
8392
8476
  }
8393
8477
  console.log(`[webchat:inbound] op=send-accepted kind=${kind} files=${stored.length} bytes=${Buffer.byteLength(text, "utf8")}`);
8394
8478
  }
8479
+ const adminUserId = requesterUserId ?? void 0;
8395
8480
  if (deliverySessionId !== void 0) {
8396
- await deps.handleInbound({ role: "admin", accountId, key: deliveryKey, text, sessionId: deliverySessionId });
8481
+ await deps.handleInbound({ role: "admin", accountId, key: deliveryKey, text, sessionId: deliverySessionId, adminUserId });
8397
8482
  } else {
8398
- await deps.handleInbound({ role: "admin", accountId, key: deliveryKey, text });
8483
+ await deps.handleInbound({ role: "admin", accountId, key: deliveryKey, text, adminUserId });
8399
8484
  }
8400
8485
  const sendId = ++sendSeq;
8401
8486
  let turnSessionId = deliverySessionId;
@@ -8406,7 +8491,7 @@ ${note}` : note;
8406
8491
  } catch {
8407
8492
  canonAccount = null;
8408
8493
  }
8409
- turnSessionId = resolveCanonical(accountId, canonAccount?.accountDir ?? null).sessionId;
8494
+ turnSessionId = resolveCanonical(accountId, canonAccount?.accountDir ?? null, requesterUserId, primaryUserId).sessionId;
8410
8495
  }
8411
8496
  const keyDisplay2 = deliveryKey.startsWith("session:") ? deliveryKey.slice(0, "session:".length + 8) : WEBCHAT_ADMIN_KEY;
8412
8497
  const baseline = jsonlSizeBytes(locateSession(turnSessionId).projectDir, turnSessionId);
@@ -8431,7 +8516,7 @@ ${note}` : note;
8431
8516
  console.error(`[webchat:settings] op=${String(op)} outcome=refused reason=unknown-op`);
8432
8517
  return c.json({ error: "op must be model, effort, or mode" }, 400);
8433
8518
  }
8434
- if (typeof value !== "string" || op === "model" && !MODEL_ID_PATTERN.test(value) || op === "effort" && !EFFORT_LEVELS.has(value) || op === "mode" && !PERMISSION_MODE_VALUES.has(value)) {
8519
+ if (typeof value !== "string" || op === "model" && !MODEL_ID_PATTERN.test(value) || op === "effort" && !isEffortLevel(value) || op === "mode" && !isPermissionMode(value)) {
8435
8520
  console.error(`[webchat:settings] op=${op} outcome=refused value=${JSON.stringify(value)} reason=invalid-value`);
8436
8521
  return c.json({ error: `invalid ${op} value` }, 400);
8437
8522
  }
@@ -8472,11 +8557,19 @@ ${note}` : note;
8472
8557
  console.error(`[webchat:inbound] op=session-refused reason=account-unresolved detail=${detail}`);
8473
8558
  return c.json({ error: "account unresolved" }, 503);
8474
8559
  }
8560
+ const cacheKey = c.get("cacheKey");
8561
+ const requesterUserId = (cacheKey ? getUserIdForSession(cacheKey) : void 0) ?? null;
8562
+ const primaryUserId = resolvePrimaryAdminUserId();
8475
8563
  const target = c.req.query("session");
8476
8564
  if (target !== void 0) {
8477
8565
  if (!UUID_PATTERN.test(target)) {
8478
8566
  return c.json({ error: "invalid session id" }, 400);
8479
8567
  }
8568
+ const owned = readTargetOwner(target);
8569
+ if (owned.found && !ownedByRequester(owned.owner, requesterUserId, primaryUserId)) {
8570
+ console.error(`[webchat:inbound] op=session-target-foreign key=session:${target.slice(0, 8)} requester=${requesterUserId ? requesterUserId.slice(0, 8) : "none"}`);
8571
+ return c.json({ error: "session not found" }, 404);
8572
+ }
8480
8573
  const { projectDir: projectDir2, channel } = locateSession(target);
8481
8574
  let resolvedProjectDir = projectDir2;
8482
8575
  let transcriptSessionId = target;
@@ -8505,11 +8598,14 @@ ${note}` : note;
8505
8598
  } catch {
8506
8599
  account = null;
8507
8600
  }
8508
- const { sessionId, source } = resolveCanonical(accountId, account?.accountDir ?? null);
8509
- if (source === "latest" && account?.accountDir) {
8510
- writeCanonicalOverrideId(account.accountDir, sessionId);
8601
+ const { sessionId, source } = resolveCanonical(accountId, account?.accountDir ?? null, requesterUserId, primaryUserId);
8602
+ if (requesterUserId === null) {
8603
+ console.error(`[webchat:inbound] op=session-resolve-no-identity key=${sessionId.slice(0, 8)}`);
8511
8604
  }
8512
- console.log(`[webchat:inbound] op=session-resolve key=${sessionId.slice(0, 8)} source=${source}`);
8605
+ if (source === "latest" && account?.accountDir && requesterUserId !== null) {
8606
+ writeCanonicalOverrideId(account.accountDir, requesterUserId, sessionId);
8607
+ }
8608
+ console.log(`[webchat:inbound] op=session-resolve key=${sessionId.slice(0, 8)} source=${source} admin=${requesterUserId ? requesterUserId.slice(0, 8) : "none"}`);
8513
8609
  const cfg = claudeConfigDir();
8514
8610
  let projectDir = null;
8515
8611
  if (cfg) {
@@ -8520,6 +8616,12 @@ ${note}` : note;
8520
8616
  }
8521
8617
  }
8522
8618
  }
8619
+ if (source === "latest" && requesterUserId !== null) {
8620
+ const owner = readSidecarMeta(join15(projectDir ?? "", `${sessionId}.meta.json`)).adminUserId;
8621
+ if (owner !== null && owner !== requesterUserId && requesterUserId !== primaryUserId) {
8622
+ console.error(`[webchat:inbound] op=session-resolve-foreign key=${sessionId.slice(0, 8)} owner=${owner.slice(0, 8)} requester=${requesterUserId.slice(0, 8)}`);
8623
+ }
8624
+ }
8523
8625
  const indicators = await fetchComposerIndicators(sessionId);
8524
8626
  return c.json({ sessionId, projectDir, sizeBytes: jsonlSizeBytes(projectDir, sessionId), pendingPermissionPrompt: deps.pendingPromptFor?.(`session:${sessionId}`) ?? null, ...indicators, ...readLevers(account) });
8525
8627
  });
@@ -8721,7 +8823,8 @@ async function managerSpawn(opts) {
8721
8823
  personId: opts.personId,
8722
8824
  visitorId: opts.visitorId,
8723
8825
  name: opts.name,
8724
- webchatChannel: opts.webchatChannel
8826
+ webchatChannel: opts.webchatChannel,
8827
+ previousContext: opts.previousContext
8725
8828
  })
8726
8829
  }).catch((err) => ({ __throw: err instanceof Error ? err.message : String(err) }));
8727
8830
  if ("__throw" in res) {
@@ -8748,6 +8851,7 @@ async function managerRcSpawn(opts) {
8748
8851
  sliceToken: opts.sliceToken,
8749
8852
  personId: opts.personId,
8750
8853
  userId: opts.userId,
8854
+ adminUserId: opts.adminUserId,
8751
8855
  waChannel: opts.waChannel,
8752
8856
  webchatChannel: opts.webchatChannel,
8753
8857
  role: opts.role,
@@ -16102,29 +16206,6 @@ var session_rc_spawn_default = app32;
16102
16206
 
16103
16207
  // server/routes/admin/session-reseat.ts
16104
16208
  import { randomUUID as randomUUID12 } from "crypto";
16105
-
16106
- // ../lib/models/src/index.ts
16107
- var OPUS_MODEL = "claude-opus-4-8[1m]";
16108
- var SONNET_MODEL = "claude-sonnet-4-6";
16109
- var HAIKU_MODEL = "claude-haiku-4-5";
16110
- var MODEL_CONTEXT_WINDOW = {
16111
- [OPUS_MODEL]: 1e6,
16112
- [SONNET_MODEL]: 2e5,
16113
- [HAIKU_MODEL]: 2e5
16114
- };
16115
- var MODEL_DISPLAY_NAMES = {
16116
- [OPUS_MODEL]: "Opus 4.8 (1M context)",
16117
- [SONNET_MODEL]: "Sonnet 4.6",
16118
- [HAIKU_MODEL]: "Haiku 4.5"
16119
- };
16120
- var SELECTABLE_MODELS = [OPUS_MODEL, SONNET_MODEL, HAIKU_MODEL];
16121
- function isSelectableModel(id) {
16122
- return SELECTABLE_MODELS.includes(id);
16123
- }
16124
-
16125
- // server/routes/admin/session-reseat.ts
16126
- var RESEAT_PERMISSION_MODES = /* @__PURE__ */ new Set(["default", "acceptEdits", "plan", "auto", "bypassPermissions"]);
16127
- var RESEAT_EFFORT_LEVELS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh"]);
16128
16209
  function resolveReseatPlan(body, mintId = randomUUID12, adminUserId, authenticatedName) {
16129
16210
  const sessionId = mintId();
16130
16211
  const key = `session:${sessionId}`;
@@ -16157,8 +16238,8 @@ app33.post("/", requireAdminSession, async (c) => {
16157
16238
  const model = typeof body.model === "string" && isSelectableModel(body.model) ? body.model : null;
16158
16239
  if (fromSessionId === null) return c.json({ error: "fromSessionId must be a valid session id" }, 400);
16159
16240
  if (model === null) return c.json({ error: "model must be a selectable model" }, 400);
16160
- const permissionMode = typeof body.permissionMode === "string" ? RESEAT_PERMISSION_MODES.has(body.permissionMode) ? body.permissionMode : null : void 0;
16161
- const effort = typeof body.effort === "string" ? RESEAT_EFFORT_LEVELS.has(body.effort) ? body.effort : null : void 0;
16241
+ const permissionMode = typeof body.permissionMode === "string" ? isPermissionMode(body.permissionMode) ? body.permissionMode : null : void 0;
16242
+ const effort = typeof body.effort === "string" ? isEffortLevel(body.effort) ? body.effort : null : void 0;
16162
16243
  if (permissionMode === null) return c.json({ error: "permissionMode must be a composer-writable mode" }, 400);
16163
16244
  if (effort === null) return c.json({ error: "effort must be an accepted level" }, 400);
16164
16245
  if (reseatsInFlight.has(fromSessionId)) {
@@ -16168,6 +16249,13 @@ app33.post("/", requireAdminSession, async (c) => {
16168
16249
  try {
16169
16250
  const cacheKey = c.get("cacheKey");
16170
16251
  const adminUserId = cacheKey ? getUserIdForSession(cacheKey) : void 0;
16252
+ {
16253
+ const ownerInfo = readTargetOwner(fromSessionId);
16254
+ if (!(ownerInfo.found && ownedByRequester(ownerInfo.owner, adminUserId ?? null, resolvePrimaryAdminUserId()))) {
16255
+ console.error(`[chat-reseat] op=reseat-refused from=${fromSessionId.slice(0, 8)} reason=foreign-source requester=${adminUserId ? adminUserId.slice(0, 8) : "none"}`);
16256
+ return c.json({ error: "session not found" }, 404);
16257
+ }
16258
+ }
16171
16259
  const accountId = cacheKey ? getAccountIdForSession(cacheKey) : void 0;
16172
16260
  const authenticatedName = accountId ? await resolveAuthenticatedName(accountId, adminUserId) : void 0;
16173
16261
  const plan = resolveReseatPlan(
@@ -16204,12 +16292,13 @@ app33.post("/", requireAdminSession, async (c) => {
16204
16292
  }
16205
16293
  try {
16206
16294
  const account = resolveAccount();
16207
- if (account) {
16295
+ if (account && adminUserId) {
16208
16296
  const accountId2 = resolvePlatformAccountId();
16209
- const canonicalId = adminSessionIdFor(accountId2, WEBCHAT_ADMIN_KEY);
16210
- const currentOverride = readCanonicalOverrideId(account.accountDir);
16297
+ const primaryUserId = resolvePrimaryAdminUserId();
16298
+ const canonicalId = adminSessionIdFor(accountId2, WEBCHAT_ADMIN_KEY, adminUserId);
16299
+ const currentOverride = readCanonicalOverrideId(account.accountDir, adminUserId, primaryUserId);
16211
16300
  if (fromSessionId === canonicalId || fromSessionId === currentOverride) {
16212
- writeCanonicalOverrideId(account.accountDir, plan.sessionId);
16301
+ writeCanonicalOverrideId(account.accountDir, adminUserId, plan.sessionId);
16213
16302
  console.log(`[chat-reseat] op=canonical-forward reseatReqId=${reseatReqId} from=${fromSessionId} to=${plan.sessionId}`);
16214
16303
  }
16215
16304
  }
@@ -16668,9 +16757,8 @@ app37.get("/", async (c) => {
16668
16757
  });
16669
16758
  var post_turn_context_default = app37;
16670
16759
 
16671
- // server/routes/admin/public-session-context.ts
16760
+ // app/lib/slice-writes.ts
16672
16761
  import neo4j4 from "neo4j-driver";
16673
- var TAG32 = "[public-session-context]";
16674
16762
  var STRIPPED_PROPERTIES3 = /* @__PURE__ */ new Set([
16675
16763
  "embedding",
16676
16764
  "passwordHash",
@@ -16678,9 +16766,6 @@ var STRIPPED_PROPERTIES3 = /* @__PURE__ */ new Set([
16678
16766
  "otpCode",
16679
16767
  "cacheKey"
16680
16768
  ]);
16681
- function isLoopbackAddr3(addr) {
16682
- return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
16683
- }
16684
16769
  function convertValue2(value) {
16685
16770
  if (neo4j4.isDateTime(value) || neo4j4.isDate(value) || neo4j4.isLocalDateTime(value) || neo4j4.isLocalTime(value) || neo4j4.isTime(value) || neo4j4.isDuration(value)) {
16686
16771
  return value.toString();
@@ -16708,6 +16793,78 @@ function pruneProperties2(raw) {
16708
16793
  }
16709
16794
  return out;
16710
16795
  }
16796
+ async function fetchSliceWrites(session, sliceToken, accountId) {
16797
+ const cypher = `
16798
+ MATCH (n)
16799
+ WHERE n.sliceToken = $sliceToken AND n.accountId = $accountId
16800
+ RETURN elementId(n) AS elementId,
16801
+ labels(n) AS labels,
16802
+ properties(n) AS properties,
16803
+ coalesce(n.createdAt, n.observedAt, '') AS sortKey
16804
+ `;
16805
+ const res = await session.executeRead((tx) => tx.run(cypher, { sliceToken, accountId }));
16806
+ const writes = res.records.map((r) => ({
16807
+ elementId: r.get("elementId"),
16808
+ labels: r.get("labels"),
16809
+ properties: pruneProperties2(r.get("properties")),
16810
+ sortKey: String(r.get("sortKey") ?? "")
16811
+ }));
16812
+ writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
16813
+ return writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }));
16814
+ }
16815
+ var STRUCTURAL_KEYS = /* @__PURE__ */ new Set([
16816
+ "accountId",
16817
+ "scope",
16818
+ "sliceToken",
16819
+ "preferenceId",
16820
+ "ideaId",
16821
+ "createdAt",
16822
+ "updatedAt",
16823
+ "observedAt",
16824
+ "sessionId",
16825
+ "createdByAgent",
16826
+ "createdBySession",
16827
+ "confidence",
16828
+ "notApplicable"
16829
+ ]);
16830
+ function primaryLabel(labels) {
16831
+ return labels.find((l) => l.length > 0) ?? "Node";
16832
+ }
16833
+ function renderWrite(write) {
16834
+ const label = primaryLabel(write.labels);
16835
+ const props = write.properties;
16836
+ const parts = [];
16837
+ if (label === "Person") {
16838
+ const name = [props.givenName, props.familyName].filter((v) => typeof v === "string" && v.length > 0).join(" ");
16839
+ if (name) parts.push(name);
16840
+ }
16841
+ const kv = [];
16842
+ for (const [k, v] of Object.entries(props)) {
16843
+ if (STRUCTURAL_KEYS.has(k)) continue;
16844
+ if (label === "Person" && (k === "givenName" || k === "familyName")) continue;
16845
+ if (v === null || v === void 0 || v === "") continue;
16846
+ const val = String(v).slice(0, 200);
16847
+ kv.push(`${k}=${val}`);
16848
+ }
16849
+ const tail = [parts.join(" "), kv.join("; ")].filter((s) => s.length > 0).join(" \u2014 ");
16850
+ if (tail.length === 0) return null;
16851
+ return `- ${label}: ${tail}`;
16852
+ }
16853
+ function formatPreviousContext(writes) {
16854
+ if (writes.length === 0) return null;
16855
+ const lines = writes.filter((w) => w.properties.scope === "user").map(renderWrite).filter((l) => l !== null);
16856
+ if (lines.length === 0) return null;
16857
+ return [
16858
+ "What you already know about this visitor from earlier conversations:",
16859
+ ...lines
16860
+ ].join("\n");
16861
+ }
16862
+
16863
+ // server/routes/admin/public-session-context.ts
16864
+ var TAG32 = "[public-session-context]";
16865
+ function isLoopbackAddr3(addr) {
16866
+ return addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
16867
+ }
16711
16868
  var app38 = new Hono();
16712
16869
  app38.get("/", async (c) => {
16713
16870
  const remoteAddr = c.env?.incoming?.socket?.remoteAddress ?? "";
@@ -16732,31 +16889,12 @@ app38.get("/", async (c) => {
16732
16889
  const session = getSession();
16733
16890
  const started = Date.now();
16734
16891
  try {
16735
- const cypher = `
16736
- MATCH (n)
16737
- WHERE n.sliceToken = $sliceToken AND n.accountId = $accountId
16738
- RETURN elementId(n) AS elementId,
16739
- labels(n) AS labels,
16740
- properties(n) AS properties,
16741
- coalesce(n.createdAt, n.observedAt, '') AS sortKey
16742
- `;
16743
- const res = await session.executeRead(
16744
- (tx) => tx.run(cypher, { sliceToken, accountId })
16745
- );
16746
- const writes = res.records.map((r) => ({
16747
- elementId: r.get("elementId"),
16748
- labels: r.get("labels"),
16749
- properties: pruneProperties2(r.get("properties")),
16750
- sortKey: String(r.get("sortKey") ?? "")
16751
- }));
16752
- writes.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
16892
+ const writes = await fetchSliceWrites(session, sliceToken, accountId);
16753
16893
  const total = Date.now() - started;
16754
16894
  console.log(
16755
16895
  `${TAG32} sliceToken=${sliceToken.slice(0, 8)} writes=${writes.length} ms=${total}`
16756
16896
  );
16757
- return c.json({
16758
- writes: writes.map(({ elementId, labels, properties }) => ({ elementId, labels, properties }))
16759
- });
16897
+ return c.json({ writes });
16760
16898
  } catch (err) {
16761
16899
  const elapsed = Date.now() - started;
16762
16900
  const message = err instanceof Error ? err.message : String(err);
@@ -17995,19 +18133,8 @@ app51.post("/", async (c) => {
17995
18133
  const account = resolveAccount();
17996
18134
  const cookieHeader = c.req.header("cookie");
17997
18135
  const visitorId = parseVisitorCookie2(cookieHeader);
17998
- const groupSlug = body.group_slug && typeof body.group_slug === "string" ? body.group_slug : null;
17999
- let groupInfo = null;
18000
- if (groupSlug) {
18001
- groupInfo = await findGroupBySlug(groupSlug, accountId).catch(() => null);
18002
- if (!groupInfo) {
18003
- console.error(`[session] group not found: slug=${groupSlug} account=${accountId.slice(0, 8)}\u2026`);
18004
- return c.json({ error: "Group not found" }, 404);
18005
- }
18006
- }
18007
18136
  let agentSlug = null;
18008
- if (groupInfo) {
18009
- agentSlug = groupInfo.agentSlug;
18010
- } else if (body.agent) {
18137
+ if (body.agent) {
18011
18138
  if (!validateAgentSlug(body.agent)) {
18012
18139
  return c.json({ error: "Invalid agent name" }, 400);
18013
18140
  }
@@ -18040,11 +18167,6 @@ app51.post("/", async (c) => {
18040
18167
  ...agentConfig.imageShape ? { agentImageShape: agentConfig.imageShape } : {},
18041
18168
  ...agentConfig.showAgentName ? { showAgentName: agentConfig.showAgentName } : {}
18042
18169
  } : {};
18043
- const groupFields = groupInfo ? {
18044
- group: true,
18045
- groupName: groupInfo.groupName,
18046
- groupSlug
18047
- } : {};
18048
18170
  const branding = await fetchBranding(accountId).catch(() => null);
18049
18171
  if (branding) writeBrandingCache(accountId, agentSlug, branding);
18050
18172
  let accessSession = null;
@@ -18057,7 +18179,6 @@ app51.post("/", async (c) => {
18057
18179
  Response.json({
18058
18180
  auth_required: true,
18059
18181
  agent_id: agentSlug,
18060
- ...groupFields,
18061
18182
  ...branding ? { branding } : {},
18062
18183
  ...agentIdentity
18063
18184
  }),
@@ -18082,7 +18203,6 @@ app51.post("/", async (c) => {
18082
18203
  agent_id: agentSlug,
18083
18204
  resumed,
18084
18205
  ...resumed ? { messages: uiMessages } : {},
18085
- ...groupFields,
18086
18206
  ...branding ? { branding } : {},
18087
18207
  ...agentIdentity
18088
18208
  });
@@ -18093,56 +18213,10 @@ app51.post("/", async (c) => {
18093
18213
  session_key: body.session_key,
18094
18214
  agent_id: agentSlug,
18095
18215
  resumed: false,
18096
- ...groupFields,
18097
18216
  ...branding ? { branding } : {},
18098
18217
  ...agentIdentity
18099
18218
  });
18100
18219
  }
18101
- if (groupInfo && visitorId) {
18102
- let memberName = await checkGroupMembership(groupInfo.sessionId, visitorId).catch(() => null);
18103
- if (!memberName && accessSession) {
18104
- const contactValue = accessSession.contactValue;
18105
- const isEmail = contactValue?.includes("@");
18106
- const bindResult = await bindVisitorToGroup(
18107
- groupInfo.sessionId,
18108
- visitorId,
18109
- isEmail ? contactValue : void 0,
18110
- !isEmail ? contactValue : void 0
18111
- ).catch(() => null);
18112
- memberName = bindResult?.displayName ?? null;
18113
- }
18114
- if (memberName) {
18115
- const neo4jMessages = await getRecentMessages(groupInfo.sessionId).catch(() => []);
18116
- const uiMessages = neo4jMessages.filter((m) => m.content !== GREETING_DIRECTIVE).map((m) => ({
18117
- role: m.role === "user" ? "visitor" : "maxy",
18118
- content: m.content,
18119
- timestamp: new Date(m.createdAt).getTime() || Date.now()
18120
- }));
18121
- const participants = await getGroupParticipants(groupInfo.sessionId).catch(() => []);
18122
- const cacheKey2 = crypto.randomUUID();
18123
- const resumed = uiMessages.length > 0;
18124
- console.log(`[session] cold-resume group=${groupSlug} visitor=${visitorId.slice(0, 8)}\u2026 messages=${uiMessages.length}`);
18125
- return withVisitorCookie(
18126
- Response.json({
18127
- session_key: cacheKey2,
18128
- agent_id: agentSlug,
18129
- resumed,
18130
- ...resumed ? { messages: uiMessages } : {},
18131
- ...groupFields,
18132
- participants: participants.map((p) => ({ displayName: p.displayName, joinedAt: p.joinedAt })),
18133
- ...branding ? { branding } : {},
18134
- ...agentIdentity
18135
- }),
18136
- visitorId
18137
- );
18138
- }
18139
- console.log(`[session] group cold-resume denied: visitor=${visitorId.slice(0, 8)}\u2026 not a member of group=${groupSlug}`);
18140
- return c.json({ error: "Not a member of this group" }, 403);
18141
- }
18142
- if (groupInfo) {
18143
- console.error(`[session] group=${groupSlug} requires visitor cookie`);
18144
- return c.json({ error: "Groups require member authentication" }, 400);
18145
- }
18146
18220
  if (visitorId) {
18147
18221
  const recent = await findRecentConversation(visitorId, accountId, agentSlug).catch(() => null);
18148
18222
  if (recent) {
@@ -18544,7 +18618,7 @@ var defaultResolveName = async (accountId, userId) => {
18544
18618
  const res = await loadAdminUserName(accountId, userId);
18545
18619
  return res.source === "neo4j" && res.joined.length > 0 ? res.joined : null;
18546
18620
  };
18547
- async function readRaw(path2) {
18621
+ async function readRaw2(path2) {
18548
18622
  let raw;
18549
18623
  try {
18550
18624
  raw = await readFile7(path2, "utf8");
@@ -18652,7 +18726,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
18652
18726
  };
18653
18727
  const sidecars = await collectLiveSidecars(projectsRoot);
18654
18728
  for (const path2 of sidecars) {
18655
- const raw = await readRaw(path2);
18729
+ const raw = await readRaw2(path2);
18656
18730
  if (!raw) continue;
18657
18731
  if (raw.role !== ADMIN_ROLE2 || raw.channel !== WEBCHAT_CHANNEL2) continue;
18658
18732
  result.scanned++;
@@ -18670,7 +18744,7 @@ async function migrateAdminWebchatSidecars(opts = {}) {
18670
18744
  await writeRaw(path2, raw);
18671
18745
  result.backfilled++;
18672
18746
  await resolveAdminName();
18673
- const back = await readRaw(path2);
18747
+ const back = await readRaw2(path2);
18674
18748
  const wrote = back && back.adminUserId === soleAdminUserId;
18675
18749
  if (wrote && resolvedNameForAdmin) {
18676
18750
  result.resolvedName++;
@@ -19614,6 +19688,9 @@ var WebchatGateway = class _WebchatGateway {
19614
19688
  // Task 800 — only present on a session-targeted launch, so the
19615
19689
  // default-path call shape stays byte-identical.
19616
19690
  ...input.sessionId !== void 0 ? { sessionId: input.sessionId } : {},
19691
+ // The authenticated admin's userId on an admin bootstrap inbound; the
19692
+ // default-path call shape stays byte-identical when absent.
19693
+ ...input.adminUserId !== void 0 ? { adminUserId: input.adminUserId } : {},
19617
19694
  // Task 756 — public spawn params on a role:'public' inbound.
19618
19695
  ...input.public !== void 0 ? { public: input.public } : {}
19619
19696
  });
@@ -19648,6 +19725,7 @@ function buildPublicWebchatSpawnRequest(input) {
19648
19725
  ...sliceToken ? { sliceToken } : {},
19649
19726
  ...personId ? { personId } : {},
19650
19727
  ...visitorId ? { visitorId } : {},
19728
+ ...input.previousContext ? { previousContext: input.previousContext } : {},
19651
19729
  name,
19652
19730
  webchatChannel: { key: input.key, gatewayUrl: input.gatewayUrl, serverPath: input.serverPath }
19653
19731
  };
@@ -20120,14 +20198,27 @@ waGateway.startSweeper();
20120
20198
  var webchatGateway = new WebchatGateway({
20121
20199
  gatewayUrl: webchatGatewayUrl(),
20122
20200
  serverPath: webchatServerPath(),
20123
- ensureChannelSession: async ({ accountId, key, role, gatewayUrl, serverPath, sessionId, public: pub }) => {
20201
+ ensureChannelSession: async ({ accountId, key, role, adminUserId, gatewayUrl, serverPath, sessionId, public: pub }) => {
20124
20202
  if (role === "public") {
20125
20203
  if (!pub) {
20126
20204
  console.error(`[webchat:inbound] op=spawn-refused key=${key} role=public reason=missing-public-params`);
20127
20205
  return;
20128
20206
  }
20207
+ let previousContext;
20208
+ if (pub.sliceToken) {
20209
+ const session = getSession();
20210
+ try {
20211
+ const writes = await fetchSliceWrites(session, pub.sliceToken, accountId);
20212
+ previousContext = formatPreviousContext(writes) ?? void 0;
20213
+ console.log(`[webchat:inbound] op=slice-readback key=${key} writes=${writes.length} injected=${previousContext ? "yes" : "no"}`);
20214
+ } catch (err) {
20215
+ console.error(`[webchat:inbound] op=slice-readback-failed key=${key} err=${err instanceof Error ? err.message : String(err)}`);
20216
+ } finally {
20217
+ await session.close();
20218
+ }
20219
+ }
20129
20220
  const result2 = await managerSpawn(
20130
- buildPublicWebchatSpawnRequest({ accountId, key, gatewayUrl, serverPath, public: pub })
20221
+ buildPublicWebchatSpawnRequest({ accountId, key, gatewayUrl, serverPath, previousContext, public: pub })
20131
20222
  );
20132
20223
  if ("error" in result2) {
20133
20224
  console.error(`[webchat:inbound] op=spawn-failed key=${key} role=public error=${result2.error} status=${result2.status}`);
@@ -20136,10 +20227,11 @@ var webchatGateway = new WebchatGateway({
20136
20227
  return { sessionId: result2.sessionId };
20137
20228
  }
20138
20229
  const result = await managerRcSpawn({
20139
- sessionId: sessionId ?? adminSessionIdFor(accountId, key),
20230
+ sessionId: sessionId ?? adminSessionIdFor(accountId, key, adminUserId),
20140
20231
  role: "admin",
20141
20232
  channel: "webchat",
20142
20233
  senderId: key,
20234
+ adminUserId,
20143
20235
  webchatChannel: { key, gatewayUrl, serverPath },
20144
20236
  logContext: `channel=webchat key=${key} role=${role}`
20145
20237
  });
@@ -20658,7 +20750,6 @@ ${clientErrorReporterScript}
20658
20750
  }
20659
20751
  return html;
20660
20752
  }
20661
- var brandedHtmlCache = /* @__PURE__ */ new Map();
20662
20753
  function loadBrandingCache(agentSlug) {
20663
20754
  const configDir2 = join28(homedir3(), BRAND.configDir);
20664
20755
  try {
@@ -20676,36 +20767,6 @@ function resolveDefaultSlug() {
20676
20767
  if (!account) return null;
20677
20768
  return resolveDefaultAgentSlug(account.accountDir);
20678
20769
  }
20679
- function wantsNextSurface(c) {
20680
- return c.req.query("surface") === "next";
20681
- }
20682
- function brandedPublicHtml(agentSlug) {
20683
- const baseHtml = cachedHtml("public.html");
20684
- if (!agentSlug) return baseHtml;
20685
- const cached3 = brandedHtmlCache.get(agentSlug);
20686
- const branding = loadBrandingCache(agentSlug);
20687
- if (!branding) return baseHtml;
20688
- const brandHash = JSON.stringify(branding).length;
20689
- if (cached3 && cached3.mtime === brandHash) return cached3.html;
20690
- const title = escapeHtml(branding.name);
20691
- const description = branding.tagline ? escapeHtml(branding.tagline) : "";
20692
- const themeColor = branding.primaryColor || "";
20693
- const ogImage = branding.logoUrl || "";
20694
- const favicon = branding.faviconUrl || "";
20695
- const metaTags = [
20696
- ` <title>${title}</title>`,
20697
- favicon ? ` <link rel="icon" href="${escapeHtml(favicon)}">` : ` <link rel="icon" href="${escapeHtml(brandFaviconPath)}">`,
20698
- themeColor ? ` <meta name="theme-color" content="${escapeHtml(themeColor)}">` : "",
20699
- ` <meta property="og:title" content="${title}">`,
20700
- description ? ` <meta property="og:description" content="${description}">` : "",
20701
- ogImage ? ` <meta property="og:image" content="${escapeHtml(ogImage)}">` : "",
20702
- ' <meta property="og:type" content="website">'
20703
- ].filter(Boolean).join("\n");
20704
- const html = baseHtml.replace(` <title>${escapeHtml(BRAND.productName)}</title>
20705
- <link rel="icon" href="${escapeHtml(brandFaviconPath)}">`, metaTags);
20706
- brandedHtmlCache.set(agentSlug, { html, mtime: brandHash });
20707
- return html;
20708
- }
20709
20770
  function escapeHtml(s) {
20710
20771
  return s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
20711
20772
  }
@@ -20729,8 +20790,7 @@ app52.get("/", (c) => {
20729
20790
  );
20730
20791
  }
20731
20792
  console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
20732
- if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
20733
- return c.html(brandedPublicHtml(defaultSlug));
20793
+ return c.html(cachedHtml("public.html"));
20734
20794
  }
20735
20795
  console.log(`[host-class] host=${host} class=admin served=index.html`);
20736
20796
  return c.html(cachedHtml("index.html"));
@@ -20738,13 +20798,11 @@ app52.get("/", (c) => {
20738
20798
  app52.get("/public", (c) => {
20739
20799
  const host = (c.req.header("host") ?? "").split(":")[0];
20740
20800
  if (isPublicHost(host)) return c.text("Not found", 404);
20741
- if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
20742
20801
  return c.html(cachedHtml("public.html"));
20743
20802
  });
20744
20803
  app52.get("/public-chat", (c) => {
20745
20804
  const host = (c.req.header("host") ?? "").split(":")[0];
20746
20805
  if (isPublicHost(host)) return c.text("Not found", 404);
20747
- if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
20748
20806
  return c.html(cachedHtml("public.html"));
20749
20807
  });
20750
20808
  async function logViewerFetch(c, next) {
@@ -20798,7 +20856,7 @@ app52.post("/api/vnc/client-event", async (c) => {
20798
20856
  return c.json({ ok: true });
20799
20857
  });
20800
20858
  app52.get("/g/:slug", (c) => {
20801
- return c.html(brandedPublicHtml());
20859
+ return c.html(cachedHtml("public.html"));
20802
20860
  });
20803
20861
  for (const pwa of PWA_SURFACES) {
20804
20862
  app52.get(pwa.manifestPath, (c) => {
@@ -20854,8 +20912,7 @@ app52.get("/:slug", async (c, next) => {
20854
20912
  }
20855
20913
  const branding = loadBrandingCache(slug);
20856
20914
  console.error(`[public-catchall] served path=/${slug} slug=${slug} branding=${branding ? "hit" : "miss"}`);
20857
- if (wantsNextSurface(c)) return c.html(cachedHtml("public-next.html"));
20858
- return c.html(brandedPublicHtml(slug));
20915
+ return c.html(cachedHtml("public.html"));
20859
20916
  }
20860
20917
  await next();
20861
20918
  });