@axiom-lattice/gateway 4.1.6 → 4.2.0

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 (1129) hide show
  1. package/dist/{a2a-standard-G3J5ZHQ7.mjs → a2a-standard-WC2BSOFV.mjs} +2 -2
  2. package/dist/a2a-standard-WC2BSOFV.mjs.map +1 -0
  3. package/dist/chunk-K32XEQLH.mjs +28 -0
  4. package/dist/chunk-K32XEQLH.mjs.map +1 -0
  5. package/dist/{chunk-K4XELOSO.mjs → chunk-QKPZWWHH.mjs} +3 -2
  6. package/dist/{chunk-K4XELOSO.mjs.map → chunk-QKPZWWHH.mjs.map} +1 -1
  7. package/dist/embed/agent-chat-loader.js +1 -0
  8. package/dist/embed/embed-page-1c-75E4QIWF.js +1 -0
  9. package/dist/embed/embed-page-AgentDetailSideApp-6CVXM3P3.js +1 -0
  10. package/dist/embed/embed-page-AgentDetailSideApp-DRGKJ6C5.css +1 -0
  11. package/dist/embed/embed-page-AgentGovernanceWorkbench-4B3NJPCY.js +5 -0
  12. package/dist/embed/embed-page-AgentGovernanceWorkbench-SDS3GBCC.css +1 -0
  13. package/dist/embed/embed-page-ReactChart-OG5Z43H7.js +1 -0
  14. package/dist/embed/embed-page-ReactChart-VBM467ER.css +1 -0
  15. package/dist/embed/embed-page-ReactInfographic-IABAC7DO.js +574 -0
  16. package/dist/embed/embed-page-SkillFlow-GS4OUCJJ.js +1 -0
  17. package/dist/embed/embed-page-SkillFlow-VDPP5DFL.css +1 -0
  18. package/dist/embed/embed-page-TasksSideApp-F4XUHPTG.css +1 -0
  19. package/dist/embed/embed-page-TasksSideApp-I6Z7BOT2.js +241 -0
  20. package/dist/embed/embed-page-TeamWorkspace-DXKGNQ3C.css +1 -0
  21. package/dist/embed/embed-page-TeamWorkspace-LSCUIJDA.js +748 -0
  22. package/dist/embed/embed-page-TopologyRuntimeView-2NQ3OOYI.css +1 -0
  23. package/dist/embed/embed-page-TopologyRuntimeView-RY7NOUB7.js +6 -0
  24. package/dist/embed/embed-page-WorkflowAutomationView-MAYS27YJ.css +1 -0
  25. package/dist/embed/embed-page-WorkflowAutomationView-RNKIKDUX.js +3 -0
  26. package/dist/embed/embed-page-abap-QKV7XZRP.js +1 -0
  27. package/dist/embed/embed-page-abnf-534KGIL5.js +1 -0
  28. package/dist/embed/embed-page-abnf-NNWX7KPS.js +1 -0
  29. package/dist/embed/embed-page-accesslog-K5DAETBI.js +1 -0
  30. package/dist/embed/embed-page-actionscript-MLTGVDIY.js +1 -0
  31. package/dist/embed/embed-page-actionscript-YXZSI3FP.js +1 -0
  32. package/dist/embed/embed-page-ada-SMIJQ6T7.js +1 -0
  33. package/dist/embed/embed-page-ada-Z5BYNU6B.js +1 -0
  34. package/dist/embed/embed-page-agda-WCRTGDJB.js +1 -0
  35. package/dist/embed/embed-page-al-2LSX2G2U.js +1 -0
  36. package/dist/embed/embed-page-all-RTJLYZHS.js +1 -0
  37. package/dist/embed/embed-page-angelscript-4S3XC2EJ.js +1 -0
  38. package/dist/embed/embed-page-antlr4-OLOPZLHD.js +1 -0
  39. package/dist/embed/embed-page-apache-RGO2UM6T.js +1 -0
  40. package/dist/embed/embed-page-apacheconf-EKQ6F4ZQ.js +1 -0
  41. package/dist/embed/embed-page-apex-ZJTOIW4M.js +1 -0
  42. package/dist/embed/embed-page-apl-W7YETB5L.js +1 -0
  43. package/dist/embed/embed-page-applescript-I4PV6U4X.js +1 -0
  44. package/dist/embed/embed-page-applescript-M2D2KKDY.js +1 -0
  45. package/dist/embed/embed-page-aql-V6TCDQAH.js +1 -0
  46. package/dist/embed/embed-page-arcade-TSPLEDM5.js +1 -0
  47. package/dist/embed/embed-page-architecture-U656AL7Q-55BYHO3H.js +1 -0
  48. package/dist/embed/embed-page-architectureDiagram-VXUJARFQ-GDHKRBZH.js +36 -0
  49. package/dist/embed/embed-page-arduino-7N264XVW.js +1 -0
  50. package/dist/embed/embed-page-arduino-XUEUIP7S.js +1 -0
  51. package/dist/embed/embed-page-arff-M7PKJV7Y.js +1 -0
  52. package/dist/embed/embed-page-armasm-OAQGLAMS.js +1 -0
  53. package/dist/embed/embed-page-armasm-PTMJUNBD.js +1 -0
  54. package/dist/embed/embed-page-arturo-VYVR5YRA.js +1 -0
  55. package/dist/embed/embed-page-asciidoc-6GDV5NP4.js +1 -0
  56. package/dist/embed/embed-page-asciidoc-PDLRDQNM.js +1 -0
  57. package/dist/embed/embed-page-asm6502-LVC7KLV5.js +1 -0
  58. package/dist/embed/embed-page-asmatmel-B4D7TBZY.js +1 -0
  59. package/dist/embed/embed-page-aspectj-QZFNA4MK.js +1 -0
  60. package/dist/embed/embed-page-aspnet-4JJQ3PPT.js +1 -0
  61. package/dist/embed/embed-page-autohotkey-4QUCSDML.js +1 -0
  62. package/dist/embed/embed-page-autohotkey-SVPZNOL7.js +1 -0
  63. package/dist/embed/embed-page-autoit-IXYC6T6A.js +1 -0
  64. package/dist/embed/embed-page-autoit-PFZZYGX5.js +1 -0
  65. package/dist/embed/embed-page-avisynth-MVQJIFSP.js +1 -0
  66. package/dist/embed/embed-page-avrasm-XYNKWFKC.js +1 -0
  67. package/dist/embed/embed-page-avro-idl-4AA2QRRU.js +1 -0
  68. package/dist/embed/embed-page-awk-JNS3RERS.js +1 -0
  69. package/dist/embed/embed-page-awk-RMGF56MA.js +1 -0
  70. package/dist/embed/embed-page-axapta-6U5QN2JT.js +1 -0
  71. package/dist/embed/embed-page-bash-UJJ4GKW6.js +1 -0
  72. package/dist/embed/embed-page-bash-VYDNQBY7.js +1 -0
  73. package/dist/embed/embed-page-basic-6KLN4O27.js +1 -0
  74. package/dist/embed/embed-page-basic-EJRJ7W4E.js +1 -0
  75. package/dist/embed/embed-page-batch-AJOBLMJ2.js +1 -0
  76. package/dist/embed/embed-page-bbcode-CIP6MR7G.js +1 -0
  77. package/dist/embed/embed-page-bbj-OPFURIS3.js +1 -0
  78. package/dist/embed/embed-page-bicep-7BI3OTK4.js +1 -0
  79. package/dist/embed/embed-page-birb-LWSJQUWN.js +1 -0
  80. package/dist/embed/embed-page-bison-HDVOA2OF.js +1 -0
  81. package/dist/embed/embed-page-blockDiagram-VD42YOAC-6GQBPG3N.js +122 -0
  82. package/dist/embed/embed-page-bnf-7O24GKM6.js +1 -0
  83. package/dist/embed/embed-page-bnf-TCLPD45L.js +1 -0
  84. package/dist/embed/embed-page-bqn-LADFOREK.js +1 -0
  85. package/dist/embed/embed-page-brainfuck-B2QDW5Y5.js +1 -0
  86. package/dist/embed/embed-page-brainfuck-HUZY5LJA.js +1 -0
  87. package/dist/embed/embed-page-brightscript-4E54PL3L.js +1 -0
  88. package/dist/embed/embed-page-bro-DEBMJONL.js +1 -0
  89. package/dist/embed/embed-page-bsl-5HTEKAYP.js +1 -0
  90. package/dist/embed/embed-page-c-LFRMHVS4.js +1 -0
  91. package/dist/embed/embed-page-c-X5PJHL4T.js +1 -0
  92. package/dist/embed/embed-page-c-like-UPVRYRH5.js +1 -0
  93. package/dist/embed/embed-page-c4Diagram-YG6GDRKO-UBUOGTT3.js +10 -0
  94. package/dist/embed/embed-page-cal-MS5NKCDW.js +1 -0
  95. package/dist/embed/embed-page-capnproto-VVJPMDQX.js +1 -0
  96. package/dist/embed/embed-page-ceylon-TOPAPEAZ.js +1 -0
  97. package/dist/embed/embed-page-cfscript-P3X63VSB.js +1 -0
  98. package/dist/embed/embed-page-chaiscript-QZLDHGV3.js +1 -0
  99. package/dist/embed/embed-page-chunk-2AUFZBHG.js +1 -0
  100. package/dist/embed/embed-page-chunk-2AX46B4A.js +1 -0
  101. package/dist/embed/embed-page-chunk-2BEHY2KL.js +1 -0
  102. package/dist/embed/embed-page-chunk-2CM5KQAO.js +1 -0
  103. package/dist/embed/embed-page-chunk-2DKYYWQC.js +1 -0
  104. package/dist/embed/embed-page-chunk-2GFIRW6Z.js +1 -0
  105. package/dist/embed/embed-page-chunk-2GGHQJ6Z.js +1 -0
  106. package/dist/embed/embed-page-chunk-2IURSVR2.js +7 -0
  107. package/dist/embed/embed-page-chunk-2NLG2PBF.js +1 -0
  108. package/dist/embed/embed-page-chunk-2REOJOLY.js +1 -0
  109. package/dist/embed/embed-page-chunk-2SKSDKSN.js +1 -0
  110. package/dist/embed/embed-page-chunk-2V6IHON2.js +1 -0
  111. package/dist/embed/embed-page-chunk-2VJ7T35I.js +1 -0
  112. package/dist/embed/embed-page-chunk-2WL6TSEG.js +1 -0
  113. package/dist/embed/embed-page-chunk-2XLPEIWW.js +1 -0
  114. package/dist/embed/embed-page-chunk-2YRVPZIU.js +1 -0
  115. package/dist/embed/embed-page-chunk-33GTW5LX.js +1 -0
  116. package/dist/embed/embed-page-chunk-33LYY5FY.js +1 -0
  117. package/dist/embed/embed-page-chunk-342GWWY6.js +1 -0
  118. package/dist/embed/embed-page-chunk-34RH2U7Z.js +1 -0
  119. package/dist/embed/embed-page-chunk-37BFU4NL.js +1 -0
  120. package/dist/embed/embed-page-chunk-3C32LJTO.js +1 -0
  121. package/dist/embed/embed-page-chunk-3D3RUB6Q.js +1 -0
  122. package/dist/embed/embed-page-chunk-3DDNDQND.js +1 -0
  123. package/dist/embed/embed-page-chunk-3FQ3EELN.js +1 -0
  124. package/dist/embed/embed-page-chunk-3GRDXHWH.js +1 -0
  125. package/dist/embed/embed-page-chunk-3GTSDITA.js +1 -0
  126. package/dist/embed/embed-page-chunk-3IP6ESHH.js +1 -0
  127. package/dist/embed/embed-page-chunk-3J7LPOGR.js +1 -0
  128. package/dist/embed/embed-page-chunk-3KBA5YLX.js +1 -0
  129. package/dist/embed/embed-page-chunk-3MESXVLG.js +1 -0
  130. package/dist/embed/embed-page-chunk-3QOIYWK3.js +1 -0
  131. package/dist/embed/embed-page-chunk-3WBHNFJP.js +1 -0
  132. package/dist/embed/embed-page-chunk-3YID7Y73.js +1 -0
  133. package/dist/embed/embed-page-chunk-43APLD2U.js +1 -0
  134. package/dist/embed/embed-page-chunk-447KJWVF.js +1 -0
  135. package/dist/embed/embed-page-chunk-47OYOFAD.js +1 -0
  136. package/dist/embed/embed-page-chunk-4APB7U5B.js +1 -0
  137. package/dist/embed/embed-page-chunk-4BIOW547.js +3 -0
  138. package/dist/embed/embed-page-chunk-4BKXE5ON.js +14 -0
  139. package/dist/embed/embed-page-chunk-4BRWUEYH.js +1 -0
  140. package/dist/embed/embed-page-chunk-4C2ZTZLC.js +1 -0
  141. package/dist/embed/embed-page-chunk-4DT3DP4G.js +3 -0
  142. package/dist/embed/embed-page-chunk-4FS42IYM.js +1 -0
  143. package/dist/embed/embed-page-chunk-4JZFQLML.js +1 -0
  144. package/dist/embed/embed-page-chunk-4LC4UT4R.js +1 -0
  145. package/dist/embed/embed-page-chunk-4MNX7JDW.js +2 -0
  146. package/dist/embed/embed-page-chunk-4NIWV5BC.js +1 -0
  147. package/dist/embed/embed-page-chunk-4O7YNJLI.js +1 -0
  148. package/dist/embed/embed-page-chunk-4OTU4CRR.js +1 -0
  149. package/dist/embed/embed-page-chunk-4PR66FMJ.js +1 -0
  150. package/dist/embed/embed-page-chunk-4R5F5OQK.js +1 -0
  151. package/dist/embed/embed-page-chunk-4SGVKO3D.js +1 -0
  152. package/dist/embed/embed-page-chunk-4TEJCUD5.js +1 -0
  153. package/dist/embed/embed-page-chunk-4WOTSHAW.js +1 -0
  154. package/dist/embed/embed-page-chunk-4X5XHAMX.js +5 -0
  155. package/dist/embed/embed-page-chunk-4XVBSVFM.js +1 -0
  156. package/dist/embed/embed-page-chunk-4ZIJQUGM.js +1 -0
  157. package/dist/embed/embed-page-chunk-53PYTL4U.js +1 -0
  158. package/dist/embed/embed-page-chunk-53QS4RRO.js +1 -0
  159. package/dist/embed/embed-page-chunk-54DGJLXZ.js +1 -0
  160. package/dist/embed/embed-page-chunk-57BJJSAV.js +1 -0
  161. package/dist/embed/embed-page-chunk-5DAOHO64.js +1 -0
  162. package/dist/embed/embed-page-chunk-5HA2MCVW.js +1 -0
  163. package/dist/embed/embed-page-chunk-5HNRARTT.js +1 -0
  164. package/dist/embed/embed-page-chunk-5IG7MZQF.js +1 -0
  165. package/dist/embed/embed-page-chunk-5JDQ456X.js +7 -0
  166. package/dist/embed/embed-page-chunk-5LKQWBUZ.js +339 -0
  167. package/dist/embed/embed-page-chunk-5LZHM64O.js +1 -0
  168. package/dist/embed/embed-page-chunk-5OTSEOBG.js +1 -0
  169. package/dist/embed/embed-page-chunk-5WMGNRUZ.js +79 -0
  170. package/dist/embed/embed-page-chunk-5YNTYDFR.js +1 -0
  171. package/dist/embed/embed-page-chunk-62XZFSLM.js +1 -0
  172. package/dist/embed/embed-page-chunk-6433URSF.js +1 -0
  173. package/dist/embed/embed-page-chunk-6633JIZI.js +1 -0
  174. package/dist/embed/embed-page-chunk-664ZGB66.js +1 -0
  175. package/dist/embed/embed-page-chunk-66JWK64A.js +1 -0
  176. package/dist/embed/embed-page-chunk-66PSFC5S.js +1 -0
  177. package/dist/embed/embed-page-chunk-67RFPBNS.js +1 -0
  178. package/dist/embed/embed-page-chunk-6A6HYD7S.js +1 -0
  179. package/dist/embed/embed-page-chunk-6AF3OC6E.js +1 -0
  180. package/dist/embed/embed-page-chunk-6BL2XYV2.js +1 -0
  181. package/dist/embed/embed-page-chunk-6BUDTOPG.js +54 -0
  182. package/dist/embed/embed-page-chunk-6D23MLVG.js +1 -0
  183. package/dist/embed/embed-page-chunk-6DD7CBYV.js +1 -0
  184. package/dist/embed/embed-page-chunk-6DYN2PCR.js +1 -0
  185. package/dist/embed/embed-page-chunk-6E33CLHM.js +1 -0
  186. package/dist/embed/embed-page-chunk-6FFWZNBJ.js +1 -0
  187. package/dist/embed/embed-page-chunk-6G24DMH3.js +1 -0
  188. package/dist/embed/embed-page-chunk-6JFHQ7NQ.js +1 -0
  189. package/dist/embed/embed-page-chunk-6NWENUQ7.js +1 -0
  190. package/dist/embed/embed-page-chunk-6OKUWTCF.js +1 -0
  191. package/dist/embed/embed-page-chunk-6QTEF2NW.js +1 -0
  192. package/dist/embed/embed-page-chunk-6SFPT5PF.js +1 -0
  193. package/dist/embed/embed-page-chunk-6VRE3UPC.js +1 -0
  194. package/dist/embed/embed-page-chunk-6XNKALVC.js +1 -0
  195. package/dist/embed/embed-page-chunk-6XZZ6A3N.js +1 -0
  196. package/dist/embed/embed-page-chunk-6Y3UYJ6Z.js +1 -0
  197. package/dist/embed/embed-page-chunk-6ZXRL3VU.js +1 -0
  198. package/dist/embed/embed-page-chunk-72JNWX43.js +1 -0
  199. package/dist/embed/embed-page-chunk-734LUAPQ.js +1 -0
  200. package/dist/embed/embed-page-chunk-74YMVV5T.js +1 -0
  201. package/dist/embed/embed-page-chunk-75BP54HX.js +1 -0
  202. package/dist/embed/embed-page-chunk-76S2KVCN.js +1 -0
  203. package/dist/embed/embed-page-chunk-77SKWVKH.js +1 -0
  204. package/dist/embed/embed-page-chunk-7AKQRM6L.js +1 -0
  205. package/dist/embed/embed-page-chunk-7ASML425.js +1 -0
  206. package/dist/embed/embed-page-chunk-7BEP247X.js +1 -0
  207. package/dist/embed/embed-page-chunk-7CFGO35V.js +153 -0
  208. package/dist/embed/embed-page-chunk-7CW4T6JX.js +1 -0
  209. package/dist/embed/embed-page-chunk-7GLQRV3J.js +1 -0
  210. package/dist/embed/embed-page-chunk-7I5CUKLE.js +1 -0
  211. package/dist/embed/embed-page-chunk-7IYYKQJE.js +1 -0
  212. package/dist/embed/embed-page-chunk-7JBDPIC6.js +1 -0
  213. package/dist/embed/embed-page-chunk-7KSOII2E.js +1 -0
  214. package/dist/embed/embed-page-chunk-7MYHMZR7.js +1 -0
  215. package/dist/embed/embed-page-chunk-7OYMAA4V.js +1 -0
  216. package/dist/embed/embed-page-chunk-7Q3EEWYO.js +1 -0
  217. package/dist/embed/embed-page-chunk-7RPAJAU7.js +1 -0
  218. package/dist/embed/embed-page-chunk-7TH7FFVA.js +1 -0
  219. package/dist/embed/embed-page-chunk-7TMVQS3E.js +1 -0
  220. package/dist/embed/embed-page-chunk-7TY2R7O2.js +1 -0
  221. package/dist/embed/embed-page-chunk-7XMMIQFH.js +1 -0
  222. package/dist/embed/embed-page-chunk-A2LQIHX4.js +261 -0
  223. package/dist/embed/embed-page-chunk-A2QFCP3F.js +1 -0
  224. package/dist/embed/embed-page-chunk-A2XJ36CA.js +1 -0
  225. package/dist/embed/embed-page-chunk-A3QFY3IA.js +1 -0
  226. package/dist/embed/embed-page-chunk-A5CPK26D.js +1 -0
  227. package/dist/embed/embed-page-chunk-AAU4RSSU.js +1 -0
  228. package/dist/embed/embed-page-chunk-AB3Q2HOO.js +1 -0
  229. package/dist/embed/embed-page-chunk-ABFWMLOR.js +1 -0
  230. package/dist/embed/embed-page-chunk-ABIN3BPL.js +1 -0
  231. package/dist/embed/embed-page-chunk-ACIRZYZQ.js +1 -0
  232. package/dist/embed/embed-page-chunk-AEGLPY52.js +1 -0
  233. package/dist/embed/embed-page-chunk-AJPIJ5Q6.js +1 -0
  234. package/dist/embed/embed-page-chunk-AKPA6XS3.js +2 -0
  235. package/dist/embed/embed-page-chunk-ANZXYPYQ.js +1 -0
  236. package/dist/embed/embed-page-chunk-AO6KUNOD.js +1 -0
  237. package/dist/embed/embed-page-chunk-APIN6IE2.js +1 -0
  238. package/dist/embed/embed-page-chunk-AQ7P7MPQ.js +1 -0
  239. package/dist/embed/embed-page-chunk-AQLFD3FB.js +1 -0
  240. package/dist/embed/embed-page-chunk-AQTLXHTW.js +1 -0
  241. package/dist/embed/embed-page-chunk-ARHDAWDT.js +1 -0
  242. package/dist/embed/embed-page-chunk-ARM7QQNJ.js +1 -0
  243. package/dist/embed/embed-page-chunk-ARRA262W.js +1 -0
  244. package/dist/embed/embed-page-chunk-AWTS5ZYY.js +1 -0
  245. package/dist/embed/embed-page-chunk-AYOVLRHX.js +2167 -0
  246. package/dist/embed/embed-page-chunk-B43OSKKN.js +1 -0
  247. package/dist/embed/embed-page-chunk-B537QK4H.js +1 -0
  248. package/dist/embed/embed-page-chunk-B6767LVL.js +1 -0
  249. package/dist/embed/embed-page-chunk-BBSIPZIJ.js +2 -0
  250. package/dist/embed/embed-page-chunk-BDE6VTZO.js +1 -0
  251. package/dist/embed/embed-page-chunk-BDR2AV4C.js +1 -0
  252. package/dist/embed/embed-page-chunk-BEZUVEQG.js +1 -0
  253. package/dist/embed/embed-page-chunk-BHFBNKCC.js +1 -0
  254. package/dist/embed/embed-page-chunk-BIXWOREM.js +1 -0
  255. package/dist/embed/embed-page-chunk-BO56ESC4.js +1 -0
  256. package/dist/embed/embed-page-chunk-BOBSU3BS.js +1 -0
  257. package/dist/embed/embed-page-chunk-BOEM7RR2.js +1 -0
  258. package/dist/embed/embed-page-chunk-BOGY5UJK.js +1 -0
  259. package/dist/embed/embed-page-chunk-BOQ4YJRC.js +1 -0
  260. package/dist/embed/embed-page-chunk-BR7RHIPR.js +1 -0
  261. package/dist/embed/embed-page-chunk-BRF3QA4U.js +1 -0
  262. package/dist/embed/embed-page-chunk-BSHGJSTY.js +1 -0
  263. package/dist/embed/embed-page-chunk-BTZ6QKA5.js +1 -0
  264. package/dist/embed/embed-page-chunk-BXUFKFRH.js +1 -0
  265. package/dist/embed/embed-page-chunk-BYGKM25Z.js +1 -0
  266. package/dist/embed/embed-page-chunk-BZI3YCE7.js +1 -0
  267. package/dist/embed/embed-page-chunk-CADGB443.js +1 -0
  268. package/dist/embed/embed-page-chunk-CCNLQNKX.js +1 -0
  269. package/dist/embed/embed-page-chunk-CDFDSWNI.js +1 -0
  270. package/dist/embed/embed-page-chunk-CGMYXHWK.js +1 -0
  271. package/dist/embed/embed-page-chunk-CIVBRTV6.js +1 -0
  272. package/dist/embed/embed-page-chunk-CN3CMET4.js +1 -0
  273. package/dist/embed/embed-page-chunk-CT5EIC3O.js +1 -0
  274. package/dist/embed/embed-page-chunk-CTA4NVOR.js +1 -0
  275. package/dist/embed/embed-page-chunk-CTC4RKCL.js +1 -0
  276. package/dist/embed/embed-page-chunk-CUEEKFI2.js +1 -0
  277. package/dist/embed/embed-page-chunk-CUHPLIQJ.js +1 -0
  278. package/dist/embed/embed-page-chunk-CV7IET55.js +1 -0
  279. package/dist/embed/embed-page-chunk-CYZTUSN2.js +1 -0
  280. package/dist/embed/embed-page-chunk-CZBGTBTK.js +1 -0
  281. package/dist/embed/embed-page-chunk-CZXPKAAI.js +1 -0
  282. package/dist/embed/embed-page-chunk-D2R2NSRR.js +1 -0
  283. package/dist/embed/embed-page-chunk-D5AJQJD5.js +2 -0
  284. package/dist/embed/embed-page-chunk-D63UWHSO.js +1 -0
  285. package/dist/embed/embed-page-chunk-D6DA3A6A.js +1 -0
  286. package/dist/embed/embed-page-chunk-D73UXOFT.js +1 -0
  287. package/dist/embed/embed-page-chunk-DCS7FNFS.js +1 -0
  288. package/dist/embed/embed-page-chunk-DDTPPBJY.js +1 -0
  289. package/dist/embed/embed-page-chunk-DE7BGENS.js +1 -0
  290. package/dist/embed/embed-page-chunk-DEHJLLKN.js +1 -0
  291. package/dist/embed/embed-page-chunk-DHGHAGLL.js +1 -0
  292. package/dist/embed/embed-page-chunk-DIE6AVGX.js +1 -0
  293. package/dist/embed/embed-page-chunk-DM5ESF6C.js +1 -0
  294. package/dist/embed/embed-page-chunk-DQ4UEELI.js +1 -0
  295. package/dist/embed/embed-page-chunk-DVHOG6AY.js +31 -0
  296. package/dist/embed/embed-page-chunk-DWJV4T7Q.js +1 -0
  297. package/dist/embed/embed-page-chunk-DXVMFTPC.js +1 -0
  298. package/dist/embed/embed-page-chunk-DYBQVRXS.js +1 -0
  299. package/dist/embed/embed-page-chunk-DYPHXOEP.js +1 -0
  300. package/dist/embed/embed-page-chunk-DZRJEWQO.js +1 -0
  301. package/dist/embed/embed-page-chunk-E4OFRMJJ.js +1 -0
  302. package/dist/embed/embed-page-chunk-E7ECPW5G.js +1 -0
  303. package/dist/embed/embed-page-chunk-E7MYEYS3.js +1 -0
  304. package/dist/embed/embed-page-chunk-EAFE4NIS.js +1 -0
  305. package/dist/embed/embed-page-chunk-EAUQPBSN.js +1 -0
  306. package/dist/embed/embed-page-chunk-EBXTVXZF.js +1 -0
  307. package/dist/embed/embed-page-chunk-EG5CLCWE.js +1 -0
  308. package/dist/embed/embed-page-chunk-EGTJFOFF.js +1 -0
  309. package/dist/embed/embed-page-chunk-EKYNYNIX.js +1 -0
  310. package/dist/embed/embed-page-chunk-EPEKIAZP.js +37 -0
  311. package/dist/embed/embed-page-chunk-ER4O2WLO.js +1 -0
  312. package/dist/embed/embed-page-chunk-ESAZNCCX.js +1 -0
  313. package/dist/embed/embed-page-chunk-ESCA5JCS.js +1 -0
  314. package/dist/embed/embed-page-chunk-ESJEHJ5L.js +140 -0
  315. package/dist/embed/embed-page-chunk-ESLOGPBN.js +60 -0
  316. package/dist/embed/embed-page-chunk-ETP6AXEM.js +1 -0
  317. package/dist/embed/embed-page-chunk-ETY7U4DI.js +1 -0
  318. package/dist/embed/embed-page-chunk-EUOOO2LS.js +1 -0
  319. package/dist/embed/embed-page-chunk-EWKLGZMO.js +1 -0
  320. package/dist/embed/embed-page-chunk-EY64QEHF.js +1 -0
  321. package/dist/embed/embed-page-chunk-EY7WOIDX.js +1 -0
  322. package/dist/embed/embed-page-chunk-EYRF75EG.js +1 -0
  323. package/dist/embed/embed-page-chunk-EYZS7M3F.js +1 -0
  324. package/dist/embed/embed-page-chunk-F45LQ3RS.js +1 -0
  325. package/dist/embed/embed-page-chunk-F7IBVBXT.js +1 -0
  326. package/dist/embed/embed-page-chunk-FBXKGHOH.js +1 -0
  327. package/dist/embed/embed-page-chunk-FEEJAFK4.js +1 -0
  328. package/dist/embed/embed-page-chunk-FEOK4OPE.js +1 -0
  329. package/dist/embed/embed-page-chunk-FJ3EESJB.js +1 -0
  330. package/dist/embed/embed-page-chunk-FM5K6PQS.js +1 -0
  331. package/dist/embed/embed-page-chunk-FMMAQPSK.js +1 -0
  332. package/dist/embed/embed-page-chunk-FSDLV5QO.js +1 -0
  333. package/dist/embed/embed-page-chunk-FTXNVWT5.js +1 -0
  334. package/dist/embed/embed-page-chunk-FUIKRW55.js +1 -0
  335. package/dist/embed/embed-page-chunk-FVK265KY.js +1 -0
  336. package/dist/embed/embed-page-chunk-FWTICTEC.js +1 -0
  337. package/dist/embed/embed-page-chunk-FWXSX2W4.js +1 -0
  338. package/dist/embed/embed-page-chunk-FYBEULVS.js +1 -0
  339. package/dist/embed/embed-page-chunk-G5HXFDFC.js +1 -0
  340. package/dist/embed/embed-page-chunk-G5KW2SOV.js +1 -0
  341. package/dist/embed/embed-page-chunk-GAF3UVZE.js +1 -0
  342. package/dist/embed/embed-page-chunk-GFOWXZE5.js +1 -0
  343. package/dist/embed/embed-page-chunk-GH22I3LG.js +1 -0
  344. package/dist/embed/embed-page-chunk-GJCMO4YN.js +1 -0
  345. package/dist/embed/embed-page-chunk-GKA7H24K.js +1 -0
  346. package/dist/embed/embed-page-chunk-GL7A7IDD.js +1 -0
  347. package/dist/embed/embed-page-chunk-GNEIDEFX.js +1 -0
  348. package/dist/embed/embed-page-chunk-GPISFLXW.js +1 -0
  349. package/dist/embed/embed-page-chunk-GSWEZJ66.js +1 -0
  350. package/dist/embed/embed-page-chunk-GU7JLLYO.js +1 -0
  351. package/dist/embed/embed-page-chunk-GVZMVAXF.js +70 -0
  352. package/dist/embed/embed-page-chunk-GZBFDD4Y.js +1 -0
  353. package/dist/embed/embed-page-chunk-H3HFE6RK.js +1 -0
  354. package/dist/embed/embed-page-chunk-H3NYTZT4.js +3 -0
  355. package/dist/embed/embed-page-chunk-H7CZ6EXN.js +1 -0
  356. package/dist/embed/embed-page-chunk-H7HZ35QN.js +1 -0
  357. package/dist/embed/embed-page-chunk-H7XTOBKB.js +1 -0
  358. package/dist/embed/embed-page-chunk-HD5CA5Q2.js +1 -0
  359. package/dist/embed/embed-page-chunk-HDAHRUIT.js +1 -0
  360. package/dist/embed/embed-page-chunk-HGSQ4AUI.js +1 -0
  361. package/dist/embed/embed-page-chunk-HJJHFV6J.js +1 -0
  362. package/dist/embed/embed-page-chunk-HK4QMNL5.js +1 -0
  363. package/dist/embed/embed-page-chunk-HNWETJWB.js +1 -0
  364. package/dist/embed/embed-page-chunk-HQCMCYUS.js +1 -0
  365. package/dist/embed/embed-page-chunk-HQUXJKTG.js +1 -0
  366. package/dist/embed/embed-page-chunk-HTEALTO4.js +1 -0
  367. package/dist/embed/embed-page-chunk-HUKTQVZB.js +1 -0
  368. package/dist/embed/embed-page-chunk-HVN56UNP.js +1 -0
  369. package/dist/embed/embed-page-chunk-HVTV25TI.js +1 -0
  370. package/dist/embed/embed-page-chunk-HWNFA7PS.js +1 -0
  371. package/dist/embed/embed-page-chunk-I2JNPKJK.js +1 -0
  372. package/dist/embed/embed-page-chunk-I4BCBOUA.js +1 -0
  373. package/dist/embed/embed-page-chunk-I55FBKLU.js +3 -0
  374. package/dist/embed/embed-page-chunk-I5KTSZJX.js +1 -0
  375. package/dist/embed/embed-page-chunk-I7YQ2TGZ.js +1 -0
  376. package/dist/embed/embed-page-chunk-ICJOJGQ6.js +1 -0
  377. package/dist/embed/embed-page-chunk-IDJWNYLR.js +1 -0
  378. package/dist/embed/embed-page-chunk-IE6O7ZMQ.js +15 -0
  379. package/dist/embed/embed-page-chunk-IFCJLAOB.js +1 -0
  380. package/dist/embed/embed-page-chunk-IFEQPNI2.js +1 -0
  381. package/dist/embed/embed-page-chunk-IGBRMGDS.js +1 -0
  382. package/dist/embed/embed-page-chunk-IGIFLYCQ.js +1 -0
  383. package/dist/embed/embed-page-chunk-IGOT476M.js +1 -0
  384. package/dist/embed/embed-page-chunk-IHNNPY3P.js +1 -0
  385. package/dist/embed/embed-page-chunk-II6ODJLE.js +1 -0
  386. package/dist/embed/embed-page-chunk-IIIA5HUO.js +1 -0
  387. package/dist/embed/embed-page-chunk-IIYOOZDE.js +1 -0
  388. package/dist/embed/embed-page-chunk-IJPRKD63.js +1 -0
  389. package/dist/embed/embed-page-chunk-IK2TPQVX.js +1 -0
  390. package/dist/embed/embed-page-chunk-INGZ5SYE.js +1 -0
  391. package/dist/embed/embed-page-chunk-INUQ73SI.js +1 -0
  392. package/dist/embed/embed-page-chunk-IPI53MN3.js +1 -0
  393. package/dist/embed/embed-page-chunk-IPMWXKCK.js +1 -0
  394. package/dist/embed/embed-page-chunk-IRP2UOPH.js +1 -0
  395. package/dist/embed/embed-page-chunk-ISY7S7N6.js +1 -0
  396. package/dist/embed/embed-page-chunk-IT5VM3N7.js +1 -0
  397. package/dist/embed/embed-page-chunk-IX4WLWCY.js +28 -0
  398. package/dist/embed/embed-page-chunk-IYK5VAB3.js +1 -0
  399. package/dist/embed/embed-page-chunk-IZ6ZGFSG.js +1 -0
  400. package/dist/embed/embed-page-chunk-J4VBM2JB.js +1 -0
  401. package/dist/embed/embed-page-chunk-J7KNZGPV.js +1 -0
  402. package/dist/embed/embed-page-chunk-JADTV5YD.js +1 -0
  403. package/dist/embed/embed-page-chunk-JEW2Y2ED.js +1 -0
  404. package/dist/embed/embed-page-chunk-JFK56NZW.js +1 -0
  405. package/dist/embed/embed-page-chunk-JLWIJ4BP.js +1 -0
  406. package/dist/embed/embed-page-chunk-JNXBKMN6.js +1 -0
  407. package/dist/embed/embed-page-chunk-JOJ4VSO5.js +1 -0
  408. package/dist/embed/embed-page-chunk-JQQ6C3ST.js +1 -0
  409. package/dist/embed/embed-page-chunk-JUZFORQA.js +1 -0
  410. package/dist/embed/embed-page-chunk-JYEMOI5G.js +1 -0
  411. package/dist/embed/embed-page-chunk-JYQTTU7F.js +1 -0
  412. package/dist/embed/embed-page-chunk-K2NBNWDK.js +1 -0
  413. package/dist/embed/embed-page-chunk-K7I5Z2RN.js +1 -0
  414. package/dist/embed/embed-page-chunk-K7JAB46X.js +1 -0
  415. package/dist/embed/embed-page-chunk-KE32OJIP.js +1 -0
  416. package/dist/embed/embed-page-chunk-KEKB3BUG.js +1 -0
  417. package/dist/embed/embed-page-chunk-KG5A66WX.js +525 -0
  418. package/dist/embed/embed-page-chunk-KGP2RGEC.js +1 -0
  419. package/dist/embed/embed-page-chunk-KGX7G7XQ.js +1 -0
  420. package/dist/embed/embed-page-chunk-KM5NL7BL.js +1 -0
  421. package/dist/embed/embed-page-chunk-KQNRWZKR.js +1 -0
  422. package/dist/embed/embed-page-chunk-KUTM5AGJ.js +1 -0
  423. package/dist/embed/embed-page-chunk-KW44NUT4.js +1 -0
  424. package/dist/embed/embed-page-chunk-KWRAXHKX.js +1 -0
  425. package/dist/embed/embed-page-chunk-KZWWYO7Z.js +1 -0
  426. package/dist/embed/embed-page-chunk-L2QFIJ4P.js +1 -0
  427. package/dist/embed/embed-page-chunk-L3RQ76LD.js +1 -0
  428. package/dist/embed/embed-page-chunk-L6GX525D.js +1 -0
  429. package/dist/embed/embed-page-chunk-LDFGGZC6.js +1 -0
  430. package/dist/embed/embed-page-chunk-LEAHYMKH.js +1 -0
  431. package/dist/embed/embed-page-chunk-LH2NUQ2C.js +1 -0
  432. package/dist/embed/embed-page-chunk-LIJVWBYO.js +1 -0
  433. package/dist/embed/embed-page-chunk-LJBLK3MD.js +1 -0
  434. package/dist/embed/embed-page-chunk-LJJJJZT7.js +1 -0
  435. package/dist/embed/embed-page-chunk-LJZ2VDC6.js +1 -0
  436. package/dist/embed/embed-page-chunk-LKBECLX2.js +1 -0
  437. package/dist/embed/embed-page-chunk-LL4XKLOG.js +1 -0
  438. package/dist/embed/embed-page-chunk-LLFEIUVK.js +1 -0
  439. package/dist/embed/embed-page-chunk-LMLHHN2B.js +1 -0
  440. package/dist/embed/embed-page-chunk-LOLMAI3V.js +1 -0
  441. package/dist/embed/embed-page-chunk-LPXAKW7Q.js +1 -0
  442. package/dist/embed/embed-page-chunk-LRB5IXLV.js +1 -0
  443. package/dist/embed/embed-page-chunk-LW3LUJEG.js +1 -0
  444. package/dist/embed/embed-page-chunk-LWERP7BS.js +1 -0
  445. package/dist/embed/embed-page-chunk-M4ACA43K.js +1 -0
  446. package/dist/embed/embed-page-chunk-M5HO3OG6.js +1 -0
  447. package/dist/embed/embed-page-chunk-M7F46E23.js +1 -0
  448. package/dist/embed/embed-page-chunk-MASNBRHM.js +1 -0
  449. package/dist/embed/embed-page-chunk-MB65DZAX.js +14 -0
  450. package/dist/embed/embed-page-chunk-MB77ZI4D.js +1 -0
  451. package/dist/embed/embed-page-chunk-MEC3JUW7.js +1 -0
  452. package/dist/embed/embed-page-chunk-MG5LALIS.js +1 -0
  453. package/dist/embed/embed-page-chunk-MHSEFTKR.js +1 -0
  454. package/dist/embed/embed-page-chunk-MKV2QNSI.js +1 -0
  455. package/dist/embed/embed-page-chunk-MMHCEL7E.js +1 -0
  456. package/dist/embed/embed-page-chunk-MMXDBRLY.js +1 -0
  457. package/dist/embed/embed-page-chunk-MSYFW3OJ.js +1 -0
  458. package/dist/embed/embed-page-chunk-MVLHDASB.js +1 -0
  459. package/dist/embed/embed-page-chunk-N252QSMT.js +1 -0
  460. package/dist/embed/embed-page-chunk-N7NXBLSR.js +1 -0
  461. package/dist/embed/embed-page-chunk-NBNJGF7O.js +1 -0
  462. package/dist/embed/embed-page-chunk-NG7LKEPN.js +1 -0
  463. package/dist/embed/embed-page-chunk-NHOBB2JQ.js +1 -0
  464. package/dist/embed/embed-page-chunk-NIFSD4XH.js +1 -0
  465. package/dist/embed/embed-page-chunk-NJP7LGPJ.js +1 -0
  466. package/dist/embed/embed-page-chunk-NLMEH7HI.js +1 -0
  467. package/dist/embed/embed-page-chunk-NLZ6F3ON.js +1 -0
  468. package/dist/embed/embed-page-chunk-NMUKLFBY.js +1 -0
  469. package/dist/embed/embed-page-chunk-NMZP7U6I.js +1 -0
  470. package/dist/embed/embed-page-chunk-NN7VEJ2G.js +1 -0
  471. package/dist/embed/embed-page-chunk-NNNI4647.js +1 -0
  472. package/dist/embed/embed-page-chunk-NNZA747K.js +1 -0
  473. package/dist/embed/embed-page-chunk-NOMBKADH.js +1 -0
  474. package/dist/embed/embed-page-chunk-NQRVVPLU.js +1 -0
  475. package/dist/embed/embed-page-chunk-O2YMBFJK.js +1 -0
  476. package/dist/embed/embed-page-chunk-O6DJHMEC.js +1 -0
  477. package/dist/embed/embed-page-chunk-OAUK7LXS.js +1 -0
  478. package/dist/embed/embed-page-chunk-OCFVEAMV.js +1 -0
  479. package/dist/embed/embed-page-chunk-OEC4EWNI.js +1 -0
  480. package/dist/embed/embed-page-chunk-OF6SGGWX.js +1 -0
  481. package/dist/embed/embed-page-chunk-OJ7436DP.js +1 -0
  482. package/dist/embed/embed-page-chunk-OK6DC5YX.js +1 -0
  483. package/dist/embed/embed-page-chunk-ONZ74YHS.js +1 -0
  484. package/dist/embed/embed-page-chunk-OOZDPBUK.js +69 -0
  485. package/dist/embed/embed-page-chunk-OPME5GF2.js +1 -0
  486. package/dist/embed/embed-page-chunk-ORPDSJ5S.js +1 -0
  487. package/dist/embed/embed-page-chunk-ORPUVSKY.js +1 -0
  488. package/dist/embed/embed-page-chunk-OWGBADV6.js +3880 -0
  489. package/dist/embed/embed-page-chunk-OWTE7YMF.js +1 -0
  490. package/dist/embed/embed-page-chunk-OZKVHTL6.js +1 -0
  491. package/dist/embed/embed-page-chunk-OZUIA6GJ.js +1 -0
  492. package/dist/embed/embed-page-chunk-P4MXODKA.js +1 -0
  493. package/dist/embed/embed-page-chunk-P56KTNVT.js +1 -0
  494. package/dist/embed/embed-page-chunk-PADSMXWH.js +3 -0
  495. package/dist/embed/embed-page-chunk-PEFXE5Y4.js +1 -0
  496. package/dist/embed/embed-page-chunk-PHVA2KHO.js +1 -0
  497. package/dist/embed/embed-page-chunk-PJJPSDVD.js +1 -0
  498. package/dist/embed/embed-page-chunk-PKNTJERD.js +1 -0
  499. package/dist/embed/embed-page-chunk-PLAF2Q2L.js +1 -0
  500. package/dist/embed/embed-page-chunk-PLNJRORR.js +1 -0
  501. package/dist/embed/embed-page-chunk-PO2WVZC2.js +1 -0
  502. package/dist/embed/embed-page-chunk-PRYNHKKK.js +1 -0
  503. package/dist/embed/embed-page-chunk-PSTS2K7H.js +1 -0
  504. package/dist/embed/embed-page-chunk-PVL27S2O.js +1 -0
  505. package/dist/embed/embed-page-chunk-PVOA7ARZ.js +1 -0
  506. package/dist/embed/embed-page-chunk-PXADN2PY.js +1 -0
  507. package/dist/embed/embed-page-chunk-Q2HL7S3R.js +41 -0
  508. package/dist/embed/embed-page-chunk-Q2LWO44N.js +1 -0
  509. package/dist/embed/embed-page-chunk-Q2YEQQJF.js +1 -0
  510. package/dist/embed/embed-page-chunk-Q32Y7CP2.js +5 -0
  511. package/dist/embed/embed-page-chunk-Q3AOMIJ7.js +1 -0
  512. package/dist/embed/embed-page-chunk-Q4NFAO5G.js +1 -0
  513. package/dist/embed/embed-page-chunk-Q6ZPKMOZ.js +1 -0
  514. package/dist/embed/embed-page-chunk-QA2R2R55.js +165 -0
  515. package/dist/embed/embed-page-chunk-QANF3D34.js +1 -0
  516. package/dist/embed/embed-page-chunk-QBSFVKIB.js +1 -0
  517. package/dist/embed/embed-page-chunk-QCLLEPYT.js +1 -0
  518. package/dist/embed/embed-page-chunk-QDBK4ZDE.js +1 -0
  519. package/dist/embed/embed-page-chunk-QENDQ7H3.js +1 -0
  520. package/dist/embed/embed-page-chunk-QF7NBK3B.js +1 -0
  521. package/dist/embed/embed-page-chunk-QFTY233A.js +1 -0
  522. package/dist/embed/embed-page-chunk-QHV7PE5D.js +3 -0
  523. package/dist/embed/embed-page-chunk-QIJBDPZP.js +1 -0
  524. package/dist/embed/embed-page-chunk-QLA2XU73.js +1 -0
  525. package/dist/embed/embed-page-chunk-QNIB3Q7U.js +1 -0
  526. package/dist/embed/embed-page-chunk-QQLF4AV6.js +1 -0
  527. package/dist/embed/embed-page-chunk-QQUV5KZD.js +1 -0
  528. package/dist/embed/embed-page-chunk-QRKEL65F.js +1 -0
  529. package/dist/embed/embed-page-chunk-QRPDJVB7.js +1 -0
  530. package/dist/embed/embed-page-chunk-QVHTN5HT.js +1 -0
  531. package/dist/embed/embed-page-chunk-R2BGZIR7.js +1 -0
  532. package/dist/embed/embed-page-chunk-R2K4OIQO.js +1 -0
  533. package/dist/embed/embed-page-chunk-R4FTAO2H.js +1 -0
  534. package/dist/embed/embed-page-chunk-R54S6SKK.js +1 -0
  535. package/dist/embed/embed-page-chunk-R5I2GTYT.js +1 -0
  536. package/dist/embed/embed-page-chunk-R672RZXS.js +1 -0
  537. package/dist/embed/embed-page-chunk-RABAC5H3.js +1 -0
  538. package/dist/embed/embed-page-chunk-RG3BI65W.js +1 -0
  539. package/dist/embed/embed-page-chunk-RKPK7MLC.js +1 -0
  540. package/dist/embed/embed-page-chunk-RN7JLKLZ.js +1 -0
  541. package/dist/embed/embed-page-chunk-RNOETEGH.js +1 -0
  542. package/dist/embed/embed-page-chunk-RPK5SOLP.js +1 -0
  543. package/dist/embed/embed-page-chunk-RUOFG3OD.js +1 -0
  544. package/dist/embed/embed-page-chunk-RV2IAP52.js +1 -0
  545. package/dist/embed/embed-page-chunk-RXLB27EG.js +1 -0
  546. package/dist/embed/embed-page-chunk-S4XZPBRM.js +1 -0
  547. package/dist/embed/embed-page-chunk-SAML73QO.js +1 -0
  548. package/dist/embed/embed-page-chunk-SEH5ZYHX.js +1 -0
  549. package/dist/embed/embed-page-chunk-SL4X4KPS.js +1 -0
  550. package/dist/embed/embed-page-chunk-SMMEMIZS.js +1 -0
  551. package/dist/embed/embed-page-chunk-SMZUIXFD.js +1 -0
  552. package/dist/embed/embed-page-chunk-SQ4GANYE.js +1 -0
  553. package/dist/embed/embed-page-chunk-SRW4AAQ4.js +1 -0
  554. package/dist/embed/embed-page-chunk-SU5GXLKX.js +467 -0
  555. package/dist/embed/embed-page-chunk-SV2BM3WO.js +1 -0
  556. package/dist/embed/embed-page-chunk-SWGBMELE.js +1 -0
  557. package/dist/embed/embed-page-chunk-SYAPUMNM.js +1 -0
  558. package/dist/embed/embed-page-chunk-T4AZ556W.js +1 -0
  559. package/dist/embed/embed-page-chunk-T6QXBMXO.js +1 -0
  560. package/dist/embed/embed-page-chunk-TAOVZBLV.js +1 -0
  561. package/dist/embed/embed-page-chunk-TBRAGK3D.js +1 -0
  562. package/dist/embed/embed-page-chunk-TENLHB44.js +1 -0
  563. package/dist/embed/embed-page-chunk-TFSDCDJS.js +1 -0
  564. package/dist/embed/embed-page-chunk-TIGSOALR.js +1 -0
  565. package/dist/embed/embed-page-chunk-TKOSVUN2.js +1 -0
  566. package/dist/embed/embed-page-chunk-TLWGSINF.js +1 -0
  567. package/dist/embed/embed-page-chunk-TMUCZ7XO.js +1 -0
  568. package/dist/embed/embed-page-chunk-TP7772GL.js +1 -0
  569. package/dist/embed/embed-page-chunk-TPCI3CNJ.js +1 -0
  570. package/dist/embed/embed-page-chunk-TPGW6RUI.js +1 -0
  571. package/dist/embed/embed-page-chunk-TPQGFG2C.js +1 -0
  572. package/dist/embed/embed-page-chunk-TSZIWR3X.js +1 -0
  573. package/dist/embed/embed-page-chunk-TUFYJMMA.js +1 -0
  574. package/dist/embed/embed-page-chunk-TWDJUUXZ.js +1 -0
  575. package/dist/embed/embed-page-chunk-TWNAGURL.js +4 -0
  576. package/dist/embed/embed-page-chunk-TWU6UJLL.js +1 -0
  577. package/dist/embed/embed-page-chunk-TYA3PYZB.js +1 -0
  578. package/dist/embed/embed-page-chunk-U32PAI3Y.js +1 -0
  579. package/dist/embed/embed-page-chunk-U3B5KKSV.js +1 -0
  580. package/dist/embed/embed-page-chunk-U3YIXQYB.js +1 -0
  581. package/dist/embed/embed-page-chunk-U7OC25B3.js +1 -0
  582. package/dist/embed/embed-page-chunk-UBWHZLJN.js +1 -0
  583. package/dist/embed/embed-page-chunk-UCGT4CTV.js +1 -0
  584. package/dist/embed/embed-page-chunk-UCR4ZILJ.js +1 -0
  585. package/dist/embed/embed-page-chunk-UGBSF5HI.js +1 -0
  586. package/dist/embed/embed-page-chunk-UGCW7PZD.js +1 -0
  587. package/dist/embed/embed-page-chunk-UIZLGSJE.js +1 -0
  588. package/dist/embed/embed-page-chunk-UJODN4PG.js +1 -0
  589. package/dist/embed/embed-page-chunk-UPUUWWBK.js +1 -0
  590. package/dist/embed/embed-page-chunk-UR5VOXA3.js +1 -0
  591. package/dist/embed/embed-page-chunk-UZNSI2X3.js +1 -0
  592. package/dist/embed/embed-page-chunk-UZW2LQZV.js +1 -0
  593. package/dist/embed/embed-page-chunk-V2V73RFB.js +1 -0
  594. package/dist/embed/embed-page-chunk-V7R2Y72J.js +14 -0
  595. package/dist/embed/embed-page-chunk-VEYJHY36.js +1 -0
  596. package/dist/embed/embed-page-chunk-VNK6MED4.js +1 -0
  597. package/dist/embed/embed-page-chunk-VP2J7NES.js +1 -0
  598. package/dist/embed/embed-page-chunk-VRDH6A7Z.js +1 -0
  599. package/dist/embed/embed-page-chunk-VTUD3VPX.js +1 -0
  600. package/dist/embed/embed-page-chunk-VULBATQG.js +1 -0
  601. package/dist/embed/embed-page-chunk-VUOXEXHU.js +1 -0
  602. package/dist/embed/embed-page-chunk-VVTZ23LK.js +1 -0
  603. package/dist/embed/embed-page-chunk-VW3NF5NT.js +1 -0
  604. package/dist/embed/embed-page-chunk-VY6MAPHR.js +1 -0
  605. package/dist/embed/embed-page-chunk-WAANDEAQ.js +1 -0
  606. package/dist/embed/embed-page-chunk-WCKHIRD5.js +1 -0
  607. package/dist/embed/embed-page-chunk-WDS66MAN.js +1 -0
  608. package/dist/embed/embed-page-chunk-WLZW4FEZ.js +1 -0
  609. package/dist/embed/embed-page-chunk-WNEY2A2R.js +1 -0
  610. package/dist/embed/embed-page-chunk-WQOZWRIS.js +1 -0
  611. package/dist/embed/embed-page-chunk-WUYZIBLV.js +1 -0
  612. package/dist/embed/embed-page-chunk-WYJNNBFP.js +1 -0
  613. package/dist/embed/embed-page-chunk-X55NDWBH.js +1 -0
  614. package/dist/embed/embed-page-chunk-XA4KNRQW.js +1 -0
  615. package/dist/embed/embed-page-chunk-XAJFFWM3.js +1 -0
  616. package/dist/embed/embed-page-chunk-XIJHCNBW.js +1 -0
  617. package/dist/embed/embed-page-chunk-XNZ46IEF.js +1 -0
  618. package/dist/embed/embed-page-chunk-XO5WZF3D.js +1 -0
  619. package/dist/embed/embed-page-chunk-XPDEOKHX.js +1 -0
  620. package/dist/embed/embed-page-chunk-XQNO7AN3.js +1 -0
  621. package/dist/embed/embed-page-chunk-XR3Q4GDZ.js +1 -0
  622. package/dist/embed/embed-page-chunk-XRRCORI5.js +1 -0
  623. package/dist/embed/embed-page-chunk-XTMDFHMJ.js +1 -0
  624. package/dist/embed/embed-page-chunk-XUZKZF3V.js +1 -0
  625. package/dist/embed/embed-page-chunk-XWAJRAFC.js +1 -0
  626. package/dist/embed/embed-page-chunk-XWRBMESB.js +1 -0
  627. package/dist/embed/embed-page-chunk-XXT7RMBT.js +220 -0
  628. package/dist/embed/embed-page-chunk-XY5NGMFT.js +1 -0
  629. package/dist/embed/embed-page-chunk-XYCU2ZON.js +1 -0
  630. package/dist/embed/embed-page-chunk-XZ6CLWS2.js +1 -0
  631. package/dist/embed/embed-page-chunk-XZYJX7MY.js +1 -0
  632. package/dist/embed/embed-page-chunk-Y2JWLZJF.js +1 -0
  633. package/dist/embed/embed-page-chunk-Y4KTS6EE.js +1 -0
  634. package/dist/embed/embed-page-chunk-YBPVSBMU.js +1 -0
  635. package/dist/embed/embed-page-chunk-YEHTVTMO.js +1 -0
  636. package/dist/embed/embed-page-chunk-YFEUMUCL.js +1 -0
  637. package/dist/embed/embed-page-chunk-YFWCKZW7.js +1 -0
  638. package/dist/embed/embed-page-chunk-YHEFVON2.js +1 -0
  639. package/dist/embed/embed-page-chunk-YJBX3AFL.js +1 -0
  640. package/dist/embed/embed-page-chunk-YJZJFCLP.js +1 -0
  641. package/dist/embed/embed-page-chunk-YLUGLAWD.js +1 -0
  642. package/dist/embed/embed-page-chunk-YMMUR7L6.js +1 -0
  643. package/dist/embed/embed-page-chunk-YNIEMXW5.js +1 -0
  644. package/dist/embed/embed-page-chunk-YPK6G5D7.js +1 -0
  645. package/dist/embed/embed-page-chunk-Z26BSJ5Y.js +1 -0
  646. package/dist/embed/embed-page-chunk-Z2GE34ES.js +1 -0
  647. package/dist/embed/embed-page-chunk-Z6N3GKM5.js +1 -0
  648. package/dist/embed/embed-page-chunk-Z6PDLQOB.js +1 -0
  649. package/dist/embed/embed-page-chunk-ZESVZCWO.js +1 -0
  650. package/dist/embed/embed-page-chunk-ZITVGQ52.js +1 -0
  651. package/dist/embed/embed-page-chunk-ZNWEXQQ4.js +1 -0
  652. package/dist/embed/embed-page-chunk-ZQ6WYVOD.js +1 -0
  653. package/dist/embed/embed-page-chunk-ZR7ZLGLV.js +1 -0
  654. package/dist/embed/embed-page-chunk-ZT2EZUXI.js +1 -0
  655. package/dist/embed/embed-page-chunk-ZZCMWB6F.js +1 -0
  656. package/dist/embed/embed-page-cil-ZQIVHSN6.js +1 -0
  657. package/dist/embed/embed-page-cilkc-AJET62TW.js +1 -0
  658. package/dist/embed/embed-page-cilkcpp-FRBVBYEF.js +1 -0
  659. package/dist/embed/embed-page-classDiagram-2ON5EDUG-S5GEC2UC.js +1 -0
  660. package/dist/embed/embed-page-classDiagram-v2-WZHVMYZB-NL3HKXC3.js +1 -0
  661. package/dist/embed/embed-page-clean-OPHY52MY.js +1 -0
  662. package/dist/embed/embed-page-clike-5NRFTOCK.js +1 -0
  663. package/dist/embed/embed-page-clojure-4GC77VYK.js +1 -0
  664. package/dist/embed/embed-page-clojure-7B3FI7TH.js +1 -0
  665. package/dist/embed/embed-page-clojure-repl-56WG27Z3.js +1 -0
  666. package/dist/embed/embed-page-cmake-F3SKZMUJ.js +1 -0
  667. package/dist/embed/embed-page-cmake-UIBPQIVG.js +1 -0
  668. package/dist/embed/embed-page-cobol-7TW6OZHG.js +1 -0
  669. package/dist/embed/embed-page-code-highlighter-TBT4ICNZ.js +1 -0
  670. package/dist/embed/embed-page-coffeescript-BCKZ4N2E.js +1 -0
  671. package/dist/embed/embed-page-coffeescript-N2ENFNNR.js +1 -0
  672. package/dist/embed/embed-page-concurnas-MCN7VYPE.js +1 -0
  673. package/dist/embed/embed-page-cooklang-JSLOQBDM.js +1 -0
  674. package/dist/embed/embed-page-coq-WH3J7SKF.js +1 -0
  675. package/dist/embed/embed-page-coq-XRXAXI5X.js +1 -0
  676. package/dist/embed/embed-page-core-Q6IGWM4Q.js +1 -0
  677. package/dist/embed/embed-page-core-TQNBW2MM.js +1 -0
  678. package/dist/embed/embed-page-cos-MP7YM5FO.js +1 -0
  679. package/dist/embed/embed-page-cose-bilkent-S5V4N54A-KJMAAFJL.js +1 -0
  680. package/dist/embed/embed-page-cpp-FFAXKUCJ.js +1 -0
  681. package/dist/embed/embed-page-cpp-PRCT5QAC.js +1 -0
  682. package/dist/embed/embed-page-crmsh-PF5MF5PC.js +1 -0
  683. package/dist/embed/embed-page-crystal-GYFU35L2.js +1 -0
  684. package/dist/embed/embed-page-crystal-W2TOACW4.js +1 -0
  685. package/dist/embed/embed-page-csharp-DHR2XRZW.js +1 -0
  686. package/dist/embed/embed-page-csharp-UNF62ZBO.js +1 -0
  687. package/dist/embed/embed-page-cshtml-G7ML4LE3.js +1 -0
  688. package/dist/embed/embed-page-csp-UDQUZUZW.js +1 -0
  689. package/dist/embed/embed-page-csp-YPF3N7BE.js +1 -0
  690. package/dist/embed/embed-page-css-774MOM42.js +1 -0
  691. package/dist/embed/embed-page-css-EHGZALYG.js +1 -0
  692. package/dist/embed/embed-page-css-extras-SI7Q5IJ6.js +1 -0
  693. package/dist/embed/embed-page-csv-MT4GPPO7.js +1 -0
  694. package/dist/embed/embed-page-cue-BMTFVAKL.js +1 -0
  695. package/dist/embed/embed-page-cypher-QDHM3LFO.js +1 -0
  696. package/dist/embed/embed-page-d-KHBJT5ZU.js +1 -0
  697. package/dist/embed/embed-page-d-VF7XFFMN.js +1 -0
  698. package/dist/embed/embed-page-dagre-6UL2VRFP-QSIK5LGS.js +4 -0
  699. package/dist/embed/embed-page-dart-3L3U2DJ3.js +1 -0
  700. package/dist/embed/embed-page-dart-6AOCMAXR.js +1 -0
  701. package/dist/embed/embed-page-dataweave-LNNDNKWG.js +1 -0
  702. package/dist/embed/embed-page-dax-J2FYUNXR.js +1 -0
  703. package/dist/embed/embed-page-delphi-T3RKZ33G.js +1 -0
  704. package/dist/embed/embed-page-dhall-MGZ2X6D6.js +1 -0
  705. package/dist/embed/embed-page-diagram-PSM6KHXK-PLOM5KG7.js +24 -0
  706. package/dist/embed/embed-page-diagram-QEK2KX5R-RUNGK25X.js +43 -0
  707. package/dist/embed/embed-page-diagram-S2PKOQOG-LWDHM5TL.js +24 -0
  708. package/dist/embed/embed-page-diff-AZNWSOQ3.js +1 -0
  709. package/dist/embed/embed-page-diff-BYMKQAM5.js +1 -0
  710. package/dist/embed/embed-page-django-5BVMXLOO.js +1 -0
  711. package/dist/embed/embed-page-django-OLTKKRJC.js +1 -0
  712. package/dist/embed/embed-page-dns-LKEA7NVQ.js +1 -0
  713. package/dist/embed/embed-page-dns-zone-file-MLDJYBWW.js +1 -0
  714. package/dist/embed/embed-page-docker-7ZWVGIHF.js +1 -0
  715. package/dist/embed/embed-page-dockerfile-YJABIQ3Q.js +1 -0
  716. package/dist/embed/embed-page-dos-CZOUXBDN.js +1 -0
  717. package/dist/embed/embed-page-dot-USOBKZIN.js +1 -0
  718. package/dist/embed/embed-page-dsconfig-5E37MQM4.js +1 -0
  719. package/dist/embed/embed-page-dts-DPBFPVA5.js +1 -0
  720. package/dist/embed/embed-page-dust-OAZ4NEIP.js +1 -0
  721. package/dist/embed/embed-page-ebnf-XFC6NV6I.js +1 -0
  722. package/dist/embed/embed-page-ebnf-XSYP4JUB.js +1 -0
  723. package/dist/embed/embed-page-echarts-7KZDMH4F.js +1 -0
  724. package/dist/embed/embed-page-editorconfig-FQHUYGTR.js +1 -0
  725. package/dist/embed/embed-page-eiffel-Z22STSPG.js +1 -0
  726. package/dist/embed/embed-page-ejs-VHHMOK6Y.js +1 -0
  727. package/dist/embed/embed-page-elixir-BGO72I74.js +1 -0
  728. package/dist/embed/embed-page-elixir-H3KPRECP.js +1 -0
  729. package/dist/embed/embed-page-elm-HZWFYFUN.js +1 -0
  730. package/dist/embed/embed-page-elm-IZAWNYFC.js +1 -0
  731. package/dist/embed/embed-page-erDiagram-Q2GNP2WA-C6CZYEPF.js +60 -0
  732. package/dist/embed/embed-page-erb-AK646PXX.js +1 -0
  733. package/dist/embed/embed-page-erb-YBV2NO4W.js +1 -0
  734. package/dist/embed/embed-page-erlang-6LMYF4BN.js +1 -0
  735. package/dist/embed/embed-page-erlang-PXGHX7XB.js +1 -0
  736. package/dist/embed/embed-page-erlang-repl-UJPNMOCE.js +1 -0
  737. package/dist/embed/embed-page-etlua-XNKJ7UTQ.js +1 -0
  738. package/dist/embed/embed-page-excel-PCWQ5ZDK.js +1 -0
  739. package/dist/embed/embed-page-excel-formula-CEZ7KVDN.js +1 -0
  740. package/dist/embed/embed-page-factor-3PZO4CCJ.js +1 -0
  741. package/dist/embed/embed-page-false-OX3DNOF4.js +1 -0
  742. package/dist/embed/embed-page-firestore-security-rules-IQBOB7PZ.js +1 -0
  743. package/dist/embed/embed-page-fix-Q3F7Z2HQ.js +1 -0
  744. package/dist/embed/embed-page-flix-LVDGNPRS.js +1 -0
  745. package/dist/embed/embed-page-flow-4UPRJEF2.js +1 -0
  746. package/dist/embed/embed-page-flowDiagram-NV44I4VS-DLT3KEOP.js +162 -0
  747. package/dist/embed/embed-page-fortran-65P3TPQ7.js +1 -0
  748. package/dist/embed/embed-page-fortran-LWYFHCCB.js +1 -0
  749. package/dist/embed/embed-page-fsharp-BSA736XP.js +1 -0
  750. package/dist/embed/embed-page-fsharp-GDIVPYAB.js +1 -0
  751. package/dist/embed/embed-page-ftl-27Y3T2XT.js +1 -0
  752. package/dist/embed/embed-page-gams-7UM23CTD.js +1 -0
  753. package/dist/embed/embed-page-ganttDiagram-JELNMOA3-YXTLQI5X.js +267 -0
  754. package/dist/embed/embed-page-gap-JNDMTZYG.js +1 -0
  755. package/dist/embed/embed-page-gauss-4OCQQOQQ.js +1 -0
  756. package/dist/embed/embed-page-gcode-7ZDB2FDS.js +1 -0
  757. package/dist/embed/embed-page-gcode-U2UWK2IF.js +1 -0
  758. package/dist/embed/embed-page-gdscript-UOAGAMMO.js +1 -0
  759. package/dist/embed/embed-page-gedcom-WSTJUY6R.js +1 -0
  760. package/dist/embed/embed-page-gettext-BNGNGT6W.js +1 -0
  761. package/dist/embed/embed-page-gherkin-CPRNYA24.js +1 -0
  762. package/dist/embed/embed-page-gherkin-IVS5YUAH.js +1 -0
  763. package/dist/embed/embed-page-git-WWKMYMUR.js +1 -0
  764. package/dist/embed/embed-page-gitGraph-F6HP7TQM-AT36TKLZ.js +1 -0
  765. package/dist/embed/embed-page-gitGraphDiagram-NY62KEGX-U36ULO4Y.js +65 -0
  766. package/dist/embed/embed-page-glsl-2QJTMF6X.js +1 -0
  767. package/dist/embed/embed-page-glsl-6C6F26XK.js +1 -0
  768. package/dist/embed/embed-page-gml-67HHHYLB.js +1 -0
  769. package/dist/embed/embed-page-gml-ZFY32X23.js +1 -0
  770. package/dist/embed/embed-page-gn-KO2XPJDA.js +1 -0
  771. package/dist/embed/embed-page-go-HAQ77N2R.js +1 -0
  772. package/dist/embed/embed-page-go-SYFPAV4X.js +1 -0
  773. package/dist/embed/embed-page-go-module-XICPRQ5N.js +1 -0
  774. package/dist/embed/embed-page-golo-KQZ2PQG7.js +1 -0
  775. package/dist/embed/embed-page-gradle-7PN7DUJT.js +1 -0
  776. package/dist/embed/embed-page-gradle-GN34ZONG.js +1 -0
  777. package/dist/embed/embed-page-graphql-CVSK5MA2.js +1 -0
  778. package/dist/embed/embed-page-groovy-3R2X7GQD.js +1 -0
  779. package/dist/embed/embed-page-groovy-YCAJV7XB.js +1 -0
  780. package/dist/embed/embed-page-haml-6VEPXH2O.js +1 -0
  781. package/dist/embed/embed-page-haml-TYLXIXHD.js +1 -0
  782. package/dist/embed/embed-page-handlebars-7Y74ECRG.js +1 -0
  783. package/dist/embed/embed-page-handlebars-WVRARLIY.js +1 -0
  784. package/dist/embed/embed-page-haskell-7U743UEW.js +1 -0
  785. package/dist/embed/embed-page-haskell-BATAJHBH.js +1 -0
  786. package/dist/embed/embed-page-haxe-C234CZTQ.js +1 -0
  787. package/dist/embed/embed-page-haxe-PYBC3T4M.js +1 -0
  788. package/dist/embed/embed-page-hcl-BITT4ESF.js +1 -0
  789. package/dist/embed/embed-page-hlsl-KYOSJMB5.js +1 -0
  790. package/dist/embed/embed-page-hoon-NTFQ2YYJ.js +1 -0
  791. package/dist/embed/embed-page-hpkp-KN6XKLGI.js +1 -0
  792. package/dist/embed/embed-page-hsp-QFZDPSDA.js +1 -0
  793. package/dist/embed/embed-page-hsts-5COZ5S32.js +1 -0
  794. package/dist/embed/embed-page-html2canvas-HMTC4TFR.js +1 -0
  795. package/dist/embed/embed-page-htmlbars-L7NSSG62.js +1 -0
  796. package/dist/embed/embed-page-http-ALSJXSOJ.js +1 -0
  797. package/dist/embed/embed-page-http-E4UEITFW.js +1 -0
  798. package/dist/embed/embed-page-hy-5ROLZHNZ.js +1 -0
  799. package/dist/embed/embed-page-ichigojam-T6UG6OA7.js +1 -0
  800. package/dist/embed/embed-page-icon-74CJY73I.js +1 -0
  801. package/dist/embed/embed-page-icu-message-format-2RX6DV2B.js +1 -0
  802. package/dist/embed/embed-page-idris-OH6VYNRJ.js +1 -0
  803. package/dist/embed/embed-page-iecst-SJFFJ4PC.js +1 -0
  804. package/dist/embed/embed-page-ignore-QLXHF7QX.js +1 -0
  805. package/dist/embed/embed-page-index.es-N6YIYNKZ.js +23 -0
  806. package/dist/embed/embed-page-info-NVLQJR56-2XLQRFF4.js +1 -0
  807. package/dist/embed/embed-page-infoDiagram-WHAUD3N6-2U2VIHJP.js +2 -0
  808. package/dist/embed/embed-page-inform7-6Y7MAAME.js +1 -0
  809. package/dist/embed/embed-page-inform7-HZB3RNF4.js +1 -0
  810. package/dist/embed/embed-page-ini-7C2L4IDF.js +1 -0
  811. package/dist/embed/embed-page-ini-TMKFFGPD.js +1 -0
  812. package/dist/embed/embed-page-io-X5SCSO5G.js +1 -0
  813. package/dist/embed/embed-page-irpf90-A5FIGB26.js +1 -0
  814. package/dist/embed/embed-page-isbl-Q77V4FXF.js +1 -0
  815. package/dist/embed/embed-page-j-MA6BTTGA.js +1 -0
  816. package/dist/embed/embed-page-java-CYPVO64F.js +1 -0
  817. package/dist/embed/embed-page-java-O37XO6YL.js +1 -0
  818. package/dist/embed/embed-page-javadoc-LWLUAHHX.js +1 -0
  819. package/dist/embed/embed-page-javadoclike-BMEJGG2H.js +1 -0
  820. package/dist/embed/embed-page-javascript-GU26522Z.js +1 -0
  821. package/dist/embed/embed-page-javascript-M37PIZZC.js +1 -0
  822. package/dist/embed/embed-page-javastacktrace-ENINDMIF.js +1 -0
  823. package/dist/embed/embed-page-jboss-cli-Q2WN2KZS.js +1 -0
  824. package/dist/embed/embed-page-jexl-EU2C4LRG.js +1 -0
  825. package/dist/embed/embed-page-jolie-WJIQVPRR.js +1 -0
  826. package/dist/embed/embed-page-journeyDiagram-XKPGCS4Q-D4A2GN62.js +139 -0
  827. package/dist/embed/embed-page-jq-BRF5PIAN.js +1 -0
  828. package/dist/embed/embed-page-js-extras-WQMVOPIZ.js +1 -0
  829. package/dist/embed/embed-page-js-templates-YO6IJU6R.js +1 -0
  830. package/dist/embed/embed-page-jsdoc-ZKI7O6VF.js +1 -0
  831. package/dist/embed/embed-page-json-MRFYB7NT.js +1 -0
  832. package/dist/embed/embed-page-json-PSHSOWQY.js +1 -0
  833. package/dist/embed/embed-page-json5-VQKDKRNE.js +1 -0
  834. package/dist/embed/embed-page-jsonp-ANEJBBKD.js +1 -0
  835. package/dist/embed/embed-page-jsstacktrace-XYAXX4Z3.js +1 -0
  836. package/dist/embed/embed-page-jsx-FZEE3QI5.js +1 -0
  837. package/dist/embed/embed-page-julia-5W6JANPT.js +1 -0
  838. package/dist/embed/embed-page-julia-EY2DW2U2.js +1 -0
  839. package/dist/embed/embed-page-julia-repl-O5XO6CSL.js +1 -0
  840. package/dist/embed/embed-page-kanban-definition-3W4ZIXB7-5JTDNV4G.js +89 -0
  841. package/dist/embed/embed-page-katex-BO63LHUI.js +261 -0
  842. package/dist/embed/embed-page-keepalived-OPG3P3WJ.js +1 -0
  843. package/dist/embed/embed-page-keyman-CXJENJBT.js +1 -0
  844. package/dist/embed/embed-page-kotlin-62Q32YH3.js +1 -0
  845. package/dist/embed/embed-page-kotlin-V4IBLBDP.js +1 -0
  846. package/dist/embed/embed-page-kumir-TIJGTYC3.js +1 -0
  847. package/dist/embed/embed-page-kusto-BXI53DND.js +1 -0
  848. package/dist/embed/embed-page-lasso-2CPND7XH.js +1 -0
  849. package/dist/embed/embed-page-latex-F3X5K6QF.js +1 -0
  850. package/dist/embed/embed-page-latex-MVG52AHA.js +1 -0
  851. package/dist/embed/embed-page-latte-J3LVOB6S.js +1 -0
  852. package/dist/embed/embed-page-ldif-5OWTENAQ.js +1 -0
  853. package/dist/embed/embed-page-leaf-EYR425IG.js +1 -0
  854. package/dist/embed/embed-page-less-S6CBMQQZ.js +1 -0
  855. package/dist/embed/embed-page-less-WDPLNQ5B.js +1 -0
  856. package/dist/embed/embed-page-lilypond-IJV67NKP.js +1 -0
  857. package/dist/embed/embed-page-linker-script-MIX3HOEH.js +1 -0
  858. package/dist/embed/embed-page-liquid-CFWS6T2J.js +1 -0
  859. package/dist/embed/embed-page-lisp-C6XPBZ5U.js +1 -0
  860. package/dist/embed/embed-page-lisp-IM4ILKS7.js +1 -0
  861. package/dist/embed/embed-page-livecodeserver-6F3SUK5W.js +1 -0
  862. package/dist/embed/embed-page-livescript-GNIYPIHH.js +1 -0
  863. package/dist/embed/embed-page-livescript-HOLSYBIG.js +1 -0
  864. package/dist/embed/embed-page-llvm-IWL5DLNH.js +1 -0
  865. package/dist/embed/embed-page-llvm-K2USHCCC.js +1 -0
  866. package/dist/embed/embed-page-log-BLJX5RSC.js +1 -0
  867. package/dist/embed/embed-page-lolcode-6COIIRQ6.js +1 -0
  868. package/dist/embed/embed-page-lsl-KDZSWM6S.js +1 -0
  869. package/dist/embed/embed-page-lua-5KEV5KHK.js +1 -0
  870. package/dist/embed/embed-page-lua-F7VBLUI5.js +1 -0
  871. package/dist/embed/embed-page-magma-TTQUX26J.js +1 -0
  872. package/dist/embed/embed-page-makefile-4VQZE7FW.js +1 -0
  873. package/dist/embed/embed-page-makefile-LDN5QGHW.js +1 -0
  874. package/dist/embed/embed-page-markdown-GU3NFA6A.js +1 -0
  875. package/dist/embed/embed-page-markdown-ODPEZXUU.js +1 -0
  876. package/dist/embed/embed-page-markup-W6JMQ64H.js +1 -0
  877. package/dist/embed/embed-page-markup-templating-RYGNVTG7.js +1 -0
  878. package/dist/embed/embed-page-mata-D4O4BNGS.js +1 -0
  879. package/dist/embed/embed-page-mathematica-YSU2VUX4.js +1 -0
  880. package/dist/embed/embed-page-matlab-6TYO6LKK.js +1 -0
  881. package/dist/embed/embed-page-matlab-DCIHZIZM.js +1 -0
  882. package/dist/embed/embed-page-maxima-K2VWPGLA.js +1 -0
  883. package/dist/embed/embed-page-maxscript-3ARRWLS6.js +1 -0
  884. package/dist/embed/embed-page-mel-E3F6H7ZF.js +1 -0
  885. package/dist/embed/embed-page-mel-YGI273IY.js +1 -0
  886. package/dist/embed/embed-page-mercury-LXCDDOJN.js +1 -0
  887. package/dist/embed/embed-page-mermaid-4FMYB3TJ.js +1 -0
  888. package/dist/embed/embed-page-mermaid-TBO3M7GX.js +18 -0
  889. package/dist/embed/embed-page-metafont-33QDNLJC.js +1 -0
  890. package/dist/embed/embed-page-mindmap-definition-VGOIOE7T-LVIRJQDW.js +68 -0
  891. package/dist/embed/embed-page-mipsasm-HSMSNEPP.js +1 -0
  892. package/dist/embed/embed-page-mizar-OTR4FHWG.js +1 -0
  893. package/dist/embed/embed-page-mizar-ZDNSLX4H.js +1 -0
  894. package/dist/embed/embed-page-mojolicious-2VJDUL4M.js +1 -0
  895. package/dist/embed/embed-page-mongodb-E62Y62DN.js +1 -0
  896. package/dist/embed/embed-page-monkey-KOVSP7SE.js +1 -0
  897. package/dist/embed/embed-page-monkey-MWSXB6DH.js +1 -0
  898. package/dist/embed/embed-page-moonscript-7DWCIDI5.js +1 -0
  899. package/dist/embed/embed-page-moonscript-AIMMMW7W.js +1 -0
  900. package/dist/embed/embed-page-n1ql-TKR2PAQ4.js +1 -0
  901. package/dist/embed/embed-page-n1ql-VSPMFQEE.js +1 -0
  902. package/dist/embed/embed-page-n4js-VQSAFSQG.js +1 -0
  903. package/dist/embed/embed-page-nand2tetris-hdl-ZN4LQDMB.js +1 -0
  904. package/dist/embed/embed-page-naniscript-FX42SAZY.js +1 -0
  905. package/dist/embed/embed-page-nasm-FGR3ELJL.js +1 -0
  906. package/dist/embed/embed-page-neon-4JXYQJP3.js +1 -0
  907. package/dist/embed/embed-page-nevod-2EHVRC32.js +1 -0
  908. package/dist/embed/embed-page-nginx-3W4BPZZB.js +1 -0
  909. package/dist/embed/embed-page-nginx-672JEBEN.js +1 -0
  910. package/dist/embed/embed-page-nim-CNSA5KTJ.js +1 -0
  911. package/dist/embed/embed-page-nim-CS7GVCRH.js +1 -0
  912. package/dist/embed/embed-page-nix-H37VR2HL.js +1 -0
  913. package/dist/embed/embed-page-nix-ODG6AI37.js +1 -0
  914. package/dist/embed/embed-page-node-repl-F5RCYIN3.js +1 -0
  915. package/dist/embed/embed-page-nsis-LEW5NHHS.js +1 -0
  916. package/dist/embed/embed-page-nsis-P73IQUMW.js +1 -0
  917. package/dist/embed/embed-page-objectivec-GOD2BEHI.js +1 -0
  918. package/dist/embed/embed-page-objectivec-UO34JBT5.js +1 -0
  919. package/dist/embed/embed-page-ocaml-ODOKMPKS.js +1 -0
  920. package/dist/embed/embed-page-ocaml-PW67TSNU.js +1 -0
  921. package/dist/embed/embed-page-odin-42BCJRMU.js +1 -0
  922. package/dist/embed/embed-page-opencl-FWU2AVTW.js +1 -0
  923. package/dist/embed/embed-page-openqasm-D2QQCO47.js +1 -0
  924. package/dist/embed/embed-page-openscad-LZPRFY2W.js +1 -0
  925. package/dist/embed/embed-page-oxygene-HZG7OO7G.js +1 -0
  926. package/dist/embed/embed-page-oz-MQNQCKRU.js +1 -0
  927. package/dist/embed/embed-page-packet-BFZMPI3H-JUHAABU6.js +1 -0
  928. package/dist/embed/embed-page-parigp-MAX3X22G.js +1 -0
  929. package/dist/embed/embed-page-parser-2WFCRGYE.js +1 -0
  930. package/dist/embed/embed-page-parser3-C3KVU5ZC.js +1 -0
  931. package/dist/embed/embed-page-pascal-LVXMXCNE.js +1 -0
  932. package/dist/embed/embed-page-pascaligo-6RIW5OHU.js +1 -0
  933. package/dist/embed/embed-page-pcaxis-ZO5S5UAO.js +1 -0
  934. package/dist/embed/embed-page-peoplecode-EAE6M4AF.js +1 -0
  935. package/dist/embed/embed-page-perl-CAUIKKUT.js +1 -0
  936. package/dist/embed/embed-page-perl-NCR5YMVT.js +1 -0
  937. package/dist/embed/embed-page-pf-TXMTVH7H.js +1 -0
  938. package/dist/embed/embed-page-pgsql-M7L7YRCD.js +1 -0
  939. package/dist/embed/embed-page-php-IE2N3QI4.js +1 -0
  940. package/dist/embed/embed-page-php-QCBSAYIC.js +1 -0
  941. package/dist/embed/embed-page-php-extras-VRZO47SA.js +1 -0
  942. package/dist/embed/embed-page-php-template-U54UCRKN.js +1 -0
  943. package/dist/embed/embed-page-phpdoc-ZQWB2OXG.js +1 -0
  944. package/dist/embed/embed-page-pie-7BOR55EZ-GU56BHQJ.js +1 -0
  945. package/dist/embed/embed-page-pieDiagram-ADFJNKIX-JXFHXEAJ.js +30 -0
  946. package/dist/embed/embed-page-plaintext-OINTKMAM.js +1 -0
  947. package/dist/embed/embed-page-plant-uml-3RVWLPWM.js +1 -0
  948. package/dist/embed/embed-page-plsql-XQEBXO73.js +1 -0
  949. package/dist/embed/embed-page-pony-UEK5X7OI.js +1 -0
  950. package/dist/embed/embed-page-powerquery-DEKKCZY7.js +1 -0
  951. package/dist/embed/embed-page-powershell-EBW7RZTN.js +1 -0
  952. package/dist/embed/embed-page-powershell-UMB53SPC.js +1 -0
  953. package/dist/embed/embed-page-processing-56OIROQG.js +1 -0
  954. package/dist/embed/embed-page-processing-ZIDQ7SB3.js +1 -0
  955. package/dist/embed/embed-page-profile-6SSPU7PG.js +1 -0
  956. package/dist/embed/embed-page-prolog-7JA2UBRP.js +1 -0
  957. package/dist/embed/embed-page-prolog-L55HYSKT.js +1 -0
  958. package/dist/embed/embed-page-promql-L4YBO3EF.js +1 -0
  959. package/dist/embed/embed-page-properties-O3BOEJXJ.js +1 -0
  960. package/dist/embed/embed-page-properties-VGZTUJ5E.js +1 -0
  961. package/dist/embed/embed-page-protobuf-F7X2PLJJ.js +1 -0
  962. package/dist/embed/embed-page-protobuf-GS5HMEMS.js +1 -0
  963. package/dist/embed/embed-page-psl-HLKSMRWT.js +1 -0
  964. package/dist/embed/embed-page-pug-MI7HPGUX.js +1 -0
  965. package/dist/embed/embed-page-puppet-2HD3DPH2.js +1 -0
  966. package/dist/embed/embed-page-puppet-BRWZHTKL.js +1 -0
  967. package/dist/embed/embed-page-pure-FVSDVQ2B.js +1 -0
  968. package/dist/embed/embed-page-purebasic-PPHAGMQH.js +1 -0
  969. package/dist/embed/embed-page-purebasic-UVZDR2HE.js +1 -0
  970. package/dist/embed/embed-page-purescript-Q3TGKQZY.js +1 -0
  971. package/dist/embed/embed-page-purify-QTVE4GEG.js +8 -0
  972. package/dist/embed/embed-page-python-NO3SIOCK.js +1 -0
  973. package/dist/embed/embed-page-python-YAPGCWHR.js +1 -0
  974. package/dist/embed/embed-page-python-repl-EIGKWV4T.js +1 -0
  975. package/dist/embed/embed-page-q-5YCCZLRO.js +1 -0
  976. package/dist/embed/embed-page-q-FWJ5L5RH.js +1 -0
  977. package/dist/embed/embed-page-qml-PNZK27ST.js +1 -0
  978. package/dist/embed/embed-page-qml-YVZULPLY.js +1 -0
  979. package/dist/embed/embed-page-qore-QU7W2FQD.js +1 -0
  980. package/dist/embed/embed-page-qsharp-FNGNB3PK.js +1 -0
  981. package/dist/embed/embed-page-quadrantDiagram-AYHSOK5B-4BXTDPJ4.js +7 -0
  982. package/dist/embed/embed-page-r-52DQANKK.js +1 -0
  983. package/dist/embed/embed-page-r-B2QMYOFX.js +1 -0
  984. package/dist/embed/embed-page-racket-OA22GPFB.js +1 -0
  985. package/dist/embed/embed-page-radar-NHE76QYJ-A7QQXLRI.js +1 -0
  986. package/dist/embed/embed-page-reason-QQ4RYUQI.js +1 -0
  987. package/dist/embed/embed-page-reasonml-CQAWSREB.js +1 -0
  988. package/dist/embed/embed-page-regex-5JJLL4V6.js +1 -0
  989. package/dist/embed/embed-page-rego-OLGGN4OK.js +1 -0
  990. package/dist/embed/embed-page-renpy-72F6BTO6.js +1 -0
  991. package/dist/embed/embed-page-requirementDiagram-UZGBJVZJ-WA3XXOP7.js +64 -0
  992. package/dist/embed/embed-page-rescript-VYN4PAG7.js +1 -0
  993. package/dist/embed/embed-page-rest-YZNSQW6O.js +1 -0
  994. package/dist/embed/embed-page-rib-U4ELGIV2.js +1 -0
  995. package/dist/embed/embed-page-rip-ZA4CVYFN.js +1 -0
  996. package/dist/embed/embed-page-roboconf-5IGYRDNH.js +1 -0
  997. package/dist/embed/embed-page-roboconf-HKSGWVI6.js +1 -0
  998. package/dist/embed/embed-page-robotframework-ARNA4YNR.js +1 -0
  999. package/dist/embed/embed-page-routeros-DKQKHPKR.js +1 -0
  1000. package/dist/embed/embed-page-rsl-WZYNFUWJ.js +1 -0
  1001. package/dist/embed/embed-page-ruby-DLLZKK7A.js +1 -0
  1002. package/dist/embed/embed-page-ruby-TKJZO362.js +1 -0
  1003. package/dist/embed/embed-page-ruleslanguage-7CSB4CWD.js +1 -0
  1004. package/dist/embed/embed-page-rust-6JUJCSHC.js +1 -0
  1005. package/dist/embed/embed-page-rust-ZZUD5RKM.js +1 -0
  1006. package/dist/embed/embed-page-sankeyDiagram-TZEHDZUN-SAVUI2Q4.js +10 -0
  1007. package/dist/embed/embed-page-sas-6H3LYHVP.js +1 -0
  1008. package/dist/embed/embed-page-sas-EUBD2V4Z.js +1 -0
  1009. package/dist/embed/embed-page-sass-U6G7R7AZ.js +1 -0
  1010. package/dist/embed/embed-page-scala-HFYNBK2U.js +1 -0
  1011. package/dist/embed/embed-page-scala-OJM3677P.js +1 -0
  1012. package/dist/embed/embed-page-scheme-KBT7Z3ND.js +1 -0
  1013. package/dist/embed/embed-page-scheme-QQ2VPTFQ.js +1 -0
  1014. package/dist/embed/embed-page-scilab-LA3HLVKQ.js +1 -0
  1015. package/dist/embed/embed-page-scss-FDEUPWYR.js +1 -0
  1016. package/dist/embed/embed-page-scss-IH2AODYU.js +1 -0
  1017. package/dist/embed/embed-page-sequenceDiagram-WL72ISMW-C2QRTOTL.js +145 -0
  1018. package/dist/embed/embed-page-shell-O7OU7Y7F.js +1 -0
  1019. package/dist/embed/embed-page-shell-session-CPCKA76Q.js +1 -0
  1020. package/dist/embed/embed-page-smali-3HHDEBNE.js +1 -0
  1021. package/dist/embed/embed-page-smali-L7H7BQUY.js +1 -0
  1022. package/dist/embed/embed-page-smalltalk-KQLA6XRI.js +1 -0
  1023. package/dist/embed/embed-page-smalltalk-WMM37MR4.js +1 -0
  1024. package/dist/embed/embed-page-smarty-AF5LZRHA.js +1 -0
  1025. package/dist/embed/embed-page-sml-4ARWLXZU.js +1 -0
  1026. package/dist/embed/embed-page-sml-6BNN3PMR.js +1 -0
  1027. package/dist/embed/embed-page-solidity-5WL56MR7.js +1 -0
  1028. package/dist/embed/embed-page-solution-file-FJJU2R2L.js +1 -0
  1029. package/dist/embed/embed-page-soy-54PPSPCO.js +1 -0
  1030. package/dist/embed/embed-page-sparql-AC7LG2EE.js +1 -0
  1031. package/dist/embed/embed-page-splunk-spl-YBP24JOS.js +1 -0
  1032. package/dist/embed/embed-page-sqf-4E5P576B.js +1 -0
  1033. package/dist/embed/embed-page-sqf-CSHANDQB.js +1 -0
  1034. package/dist/embed/embed-page-sql-MGWNK6FE.js +1 -0
  1035. package/dist/embed/embed-page-sql-ZOJORZUC.js +1 -0
  1036. package/dist/embed/embed-page-sql_more-NACOUKSZ.js +1 -0
  1037. package/dist/embed/embed-page-squirrel-XG35KUR2.js +1 -0
  1038. package/dist/embed/embed-page-stan-GDB32LYB.js +1 -0
  1039. package/dist/embed/embed-page-stan-UJ7WCNJT.js +1 -0
  1040. package/dist/embed/embed-page-stata-DEQ57OIC.js +1 -0
  1041. package/dist/embed/embed-page-stata-WJUFDMUW.js +1 -0
  1042. package/dist/embed/embed-page-stateDiagram-FKZM4ZOC-6LDVHEHS.js +1 -0
  1043. package/dist/embed/embed-page-stateDiagram-v2-4FDKWEC3-UJYGEYF5.js +1 -0
  1044. package/dist/embed/embed-page-step21-6AYDKM5N.js +1 -0
  1045. package/dist/embed/embed-page-stylus-CFL6FZN3.js +1 -0
  1046. package/dist/embed/embed-page-stylus-MLEF22IY.js +1 -0
  1047. package/dist/embed/embed-page-subunit-OZQ2HNNA.js +1 -0
  1048. package/dist/embed/embed-page-supercollider-ZK2ECEDQ.js +1 -0
  1049. package/dist/embed/embed-page-swift-MNLMKF5F.js +1 -0
  1050. package/dist/embed/embed-page-swift-UJP2CPA4.js +1 -0
  1051. package/dist/embed/embed-page-systemd-DQXTIGWD.js +1 -0
  1052. package/dist/embed/embed-page-t4-cs-ZPHNHWPR.js +1 -0
  1053. package/dist/embed/embed-page-t4-templating-OA7FNPXM.js +1 -0
  1054. package/dist/embed/embed-page-t4-vb-XBX2HBI5.js +1 -0
  1055. package/dist/embed/embed-page-taggerscript-XVALJYA3.js +1 -0
  1056. package/dist/embed/embed-page-tap-EMOHKH5F.js +1 -0
  1057. package/dist/embed/embed-page-tap-HZHER7FY.js +1 -0
  1058. package/dist/embed/embed-page-tcl-GN4WSRHR.js +1 -0
  1059. package/dist/embed/embed-page-tcl-T3WWKS3Q.js +1 -0
  1060. package/dist/embed/embed-page-textile-OXFYF2DV.js +1 -0
  1061. package/dist/embed/embed-page-thrift-Q26IKVBC.js +1 -0
  1062. package/dist/embed/embed-page-timeline-definition-IT6M3QCI-OF6FTGVN.js +61 -0
  1063. package/dist/embed/embed-page-toml-ZVNI7WJB.js +1 -0
  1064. package/dist/embed/embed-page-tp-24NWOAQZ.js +1 -0
  1065. package/dist/embed/embed-page-treemap-KMMF4GRG-HPTV3SYE.js +1 -0
  1066. package/dist/embed/embed-page-tremor-443PBNWC.js +1 -0
  1067. package/dist/embed/embed-page-tsx-PX2Z4GDU.js +1 -0
  1068. package/dist/embed/embed-page-tt2-L43LNTGL.js +1 -0
  1069. package/dist/embed/embed-page-turtle-IXYYTHLU.js +1 -0
  1070. package/dist/embed/embed-page-twig-MZBQAWRC.js +1 -0
  1071. package/dist/embed/embed-page-twig-WSAAZNH3.js +1 -0
  1072. package/dist/embed/embed-page-typescript-5UWO3Y3K.js +1 -0
  1073. package/dist/embed/embed-page-typescript-BPIRCQG7.js +1 -0
  1074. package/dist/embed/embed-page-typoscript-UUKPTXPH.js +1 -0
  1075. package/dist/embed/embed-page-unrealscript-G2VHZRFN.js +1 -0
  1076. package/dist/embed/embed-page-uorazor-WYGVL7PT.js +1 -0
  1077. package/dist/embed/embed-page-uri-NRWWZBB7.js +1 -0
  1078. package/dist/embed/embed-page-v-LKVTPKDV.js +1 -0
  1079. package/dist/embed/embed-page-vala-EL5BNKYD.js +1 -0
  1080. package/dist/embed/embed-page-vala-MLIRE3PS.js +1 -0
  1081. package/dist/embed/embed-page-vbnet-5JKSIZ56.js +1 -0
  1082. package/dist/embed/embed-page-vbnet-KOGX2JTL.js +1 -0
  1083. package/dist/embed/embed-page-vbscript-637T6GXI.js +1 -0
  1084. package/dist/embed/embed-page-vbscript-html-YKWMMXG4.js +1 -0
  1085. package/dist/embed/embed-page-velocity-7Q63BBW2.js +1 -0
  1086. package/dist/embed/embed-page-verilog-B6EWQWMJ.js +1 -0
  1087. package/dist/embed/embed-page-verilog-G566LGG4.js +1 -0
  1088. package/dist/embed/embed-page-vhdl-R5JIOJNH.js +1 -0
  1089. package/dist/embed/embed-page-vhdl-RMOYZXLG.js +1 -0
  1090. package/dist/embed/embed-page-vim-47Q56RS4.js +1 -0
  1091. package/dist/embed/embed-page-vim-KBCAYMER.js +1 -0
  1092. package/dist/embed/embed-page-visual-basic-ZYE5FD6G.js +1 -0
  1093. package/dist/embed/embed-page-warpscript-65UOMFFU.js +1 -0
  1094. package/dist/embed/embed-page-wasm-MSBGNWUM.js +1 -0
  1095. package/dist/embed/embed-page-web-idl-7WW5RGOI.js +1 -0
  1096. package/dist/embed/embed-page-wgsl-FG3PI6M7.js +1 -0
  1097. package/dist/embed/embed-page-wiki-DGVS4GPN.js +1 -0
  1098. package/dist/embed/embed-page-wolfram-MOURXWVE.js +1 -0
  1099. package/dist/embed/embed-page-wren-PYL5ZRVR.js +1 -0
  1100. package/dist/embed/embed-page-x86asm-WQ6M3VHZ.js +1 -0
  1101. package/dist/embed/embed-page-xeora-JSPZIDKL.js +1 -0
  1102. package/dist/embed/embed-page-xl-DTY4E7YS.js +1 -0
  1103. package/dist/embed/embed-page-xml-P5QA5BKM.js +1 -0
  1104. package/dist/embed/embed-page-xml-doc-VAJOIYSW.js +1 -0
  1105. package/dist/embed/embed-page-xojo-L2PDU7MC.js +1 -0
  1106. package/dist/embed/embed-page-xquery-EWBQ7NVP.js +1 -0
  1107. package/dist/embed/embed-page-xquery-RUKMMBO2.js +1 -0
  1108. package/dist/embed/embed-page-xychartDiagram-PRI3JC2R-EWLR5Z3I.js +7 -0
  1109. package/dist/embed/embed-page-yaml-76KRB6BP.js +1 -0
  1110. package/dist/embed/embed-page-yaml-RR5MLWRK.js +1 -0
  1111. package/dist/embed/embed-page-yang-J62Y5RPD.js +1 -0
  1112. package/dist/embed/embed-page-zephir-OIOOQGNI.js +1 -0
  1113. package/dist/embed/embed-page-zig-75SL5ZWR.js +1 -0
  1114. package/dist/embed/embed-page.css +1 -0
  1115. package/dist/embed/embed-page.js +6 -0
  1116. package/dist/index.d.mts +19 -40
  1117. package/dist/index.d.ts +19 -40
  1118. package/dist/index.js +2082 -1142
  1119. package/dist/index.js.map +1 -1
  1120. package/dist/index.mjs +1647 -940
  1121. package/dist/index.mjs.map +1 -1
  1122. package/dist/{mcp-configs-SHRMQHIL.mjs → mcp-configs-IIKQM5GM.mjs} +2 -2
  1123. package/dist/mcpTransportRegistry-XMJ5Y2RG.mjs +13 -0
  1124. package/dist/mcpTransportRegistry-XMJ5Y2RG.mjs.map +1 -0
  1125. package/dist/open-DCAOL5CG.mjs +176 -0
  1126. package/dist/open-DCAOL5CG.mjs.map +1 -0
  1127. package/package.json +11 -8
  1128. package/dist/a2a-standard-G3J5ZHQ7.mjs.map +0 -1
  1129. /package/dist/{mcp-configs-SHRMQHIL.mjs.map → mcp-configs-IIKQM5GM.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -1,6 +1,10 @@
1
+ import {
2
+ getContentTypeFromFilename,
3
+ getFilenameFromPath
4
+ } from "./chunk-LHQY46YB.mjs";
1
5
  import {
2
6
  registerMcpServerConfigRoutes
3
- } from "./chunk-K4XELOSO.mjs";
7
+ } from "./chunk-QKPZWWHH.mjs";
4
8
  import {
5
9
  Logger,
6
10
  getQrCode,
@@ -16,10 +20,6 @@ import {
16
20
  resolvePathWithinRoot,
17
21
  saveProjectFile
18
22
  } from "./chunk-J4BK77PA.mjs";
19
- import {
20
- getContentTypeFromFilename,
21
- getFilenameFromPath
22
- } from "./chunk-LHQY46YB.mjs";
23
23
 
24
24
  // src/index.ts
25
25
  import "dotenv/config";
@@ -29,7 +29,7 @@ import multipart from "@fastify/multipart";
29
29
  import sensible from "@fastify/sensible";
30
30
  import websocket from "@fastify/websocket";
31
31
  import staticPlugin from "@fastify/static";
32
- import path3 from "path";
32
+ import path4 from "path";
33
33
 
34
34
  // src/routes/index.ts
35
35
  import { randomUUID as randomUUID19 } from "crypto";
@@ -4121,9 +4121,9 @@ var ExportImportService = class {
4121
4121
  if (!files || files.size === 0) return void 0;
4122
4122
  const prefix = `files/${entityType}/${entityId}/`;
4123
4123
  const result = /* @__PURE__ */ new Map();
4124
- for (const [path4, content] of files.entries()) {
4125
- if (path4.startsWith(prefix)) {
4126
- result.set(path4.slice(prefix.length), content);
4124
+ for (const [path5, content] of files.entries()) {
4125
+ if (path5.startsWith(prefix)) {
4126
+ result.set(path5.slice(prefix.length), content);
4127
4127
  }
4128
4128
  }
4129
4129
  return result.size > 0 ? result : void 0;
@@ -6224,21 +6224,21 @@ var WorkspaceController = class {
6224
6224
  async listPath(request) {
6225
6225
  const tenantId = this.getTenantId(request);
6226
6226
  const { workspaceId, projectId } = request.params;
6227
- const path4 = request.query.path || "/";
6227
+ const path5 = request.query.path || "/";
6228
6228
  const assistantId = request.query.assistantId;
6229
- console.log(`[listPath] tenantId=${tenantId} workspaceId=${workspaceId} projectId=${projectId} path=${path4} assistantId=${assistantId}`);
6230
- const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path4);
6231
- console.log(`[listPath] backend type=${backend.constructor.name} calling lsInfo(${path4})`);
6232
- const files = await backend.lsInfo(path4);
6229
+ console.log(`[listPath] tenantId=${tenantId} workspaceId=${workspaceId} projectId=${projectId} path=${path5} assistantId=${assistantId}`);
6230
+ const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path5);
6231
+ console.log(`[listPath] backend type=${backend.constructor.name} calling lsInfo(${path5})`);
6232
+ const files = await backend.lsInfo(path5);
6233
6233
  console.log(`[listPath] result count=${files.length}`);
6234
6234
  return { success: true, data: files };
6235
6235
  }
6236
6236
  async readFile(request) {
6237
6237
  const tenantId = this.getTenantId(request);
6238
6238
  const { workspaceId, projectId } = request.params;
6239
- const { path: path4, offset = 0, limit = 1e3, assistantId } = request.query;
6240
- const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path4);
6241
- const content = await backend.read(path4, Number(offset), Number(limit));
6239
+ const { path: path5, offset = 0, limit = 1e3, assistantId } = request.query;
6240
+ const { backend } = await this.getBackend(tenantId, workspaceId, projectId, assistantId, path5);
6241
+ const content = await backend.read(path5, Number(offset), Number(limit));
6242
6242
  return { success: true, data: { content, offset, limit } };
6243
6243
  }
6244
6244
  /**
@@ -6424,14 +6424,202 @@ function registerWorkspaceRoutes(app2, projectCollaboration) {
6424
6424
  "/api/filesystem/browse",
6425
6425
  controller.browseFilesystem.bind(controller)
6426
6426
  );
6427
+ return controller;
6428
+ }
6429
+
6430
+ // src/services/collaboration/ProjectAccessService.ts
6431
+ import { randomUUID as randomUUID6 } from "crypto";
6432
+ var ProjectCollaborationError = class extends Error {
6433
+ /** Creates a project collaboration error. */
6434
+ constructor(code, statusCode, message) {
6435
+ super(message);
6436
+ this.code = code;
6437
+ this.statusCode = statusCode;
6438
+ this.name = "ProjectCollaborationError";
6439
+ }
6440
+ };
6441
+ var allowedRoles = {
6442
+ read: /* @__PURE__ */ new Set(["owner", "admin", "member", "viewer"]),
6443
+ send: /* @__PURE__ */ new Set(["owner", "admin", "member"]),
6444
+ manage: /* @__PURE__ */ new Set(["owner", "admin"])
6445
+ };
6446
+ var membershipConflictNames = /* @__PURE__ */ new Set([
6447
+ "DuplicateProjectMembershipError",
6448
+ "ProjectMembershipIdConflictError"
6449
+ ]);
6450
+ function isProjectMembershipConflict(error) {
6451
+ return error instanceof Error && membershipConflictNames.has(error.name);
6427
6452
  }
6453
+ var ProjectAccessService = class {
6454
+ /** Creates a project access service from explicitly injected stores. */
6455
+ constructor(deps) {
6456
+ this.deps = deps;
6457
+ this.idFactory = deps.idFactory ?? randomUUID6;
6458
+ }
6459
+ /** Returns the project and active membership when the user has the requested capability. */
6460
+ async requireProjectAccess(input) {
6461
+ const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
6462
+ if (!project) {
6463
+ throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
6464
+ }
6465
+ if (project.kind === "public") {
6466
+ return this.requirePublicProjectAccess(project, input);
6467
+ }
6468
+ const membership = await this.deps.membershipStore.findByUser(
6469
+ input.tenantId,
6470
+ input.projectId,
6471
+ input.userId
6472
+ );
6473
+ if (membership?.status === "active") {
6474
+ this.requireCapability(membership, input.capability);
6475
+ return { project, membership };
6476
+ }
6477
+ const memberships = await this.deps.membershipStore.list(input.tenantId, input.projectId);
6478
+ if (memberships.length !== 0) this.accessDenied();
6479
+ if (project.kind === "personal") this.accessDenied();
6480
+ const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
6481
+ if (tenantLink?.role !== "owner" && tenantLink?.role !== "admin") this.accessDenied();
6482
+ let claim;
6483
+ try {
6484
+ claim = await this.deps.membershipStore.createInitialOwner({
6485
+ id: this.idFactory(),
6486
+ tenantId: input.tenantId,
6487
+ projectId: input.projectId,
6488
+ userId: input.userId
6489
+ });
6490
+ } catch (error) {
6491
+ if (isProjectMembershipConflict(error)) {
6492
+ throw new ProjectCollaborationError(
6493
+ "PROJECT_MEMBERSHIP_CONFLICT",
6494
+ 409,
6495
+ "Project membership could not be initialized"
6496
+ );
6497
+ }
6498
+ throw error;
6499
+ }
6500
+ if (claim.kind === "created" || claim.kind === "existing") {
6501
+ return { project, membership: claim.membership };
6502
+ }
6503
+ const racedMembership = await this.deps.membershipStore.findByUser(
6504
+ input.tenantId,
6505
+ input.projectId,
6506
+ input.userId
6507
+ );
6508
+ if (racedMembership?.status !== "active") this.accessDenied();
6509
+ this.requireCapability(racedMembership, input.capability);
6510
+ return { project, membership: racedMembership };
6511
+ }
6512
+ /** Authorizes an already-existing membership, or any tenant member for public rooms; never mutates persistence. */
6513
+ async requireExistingProjectAccess(input) {
6514
+ const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
6515
+ if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
6516
+ if (project.kind === "public") {
6517
+ return this.requireExistingPublicProjectAccess(project, input);
6518
+ }
6519
+ const membership = await this.deps.membershipStore.findByUser(
6520
+ input.tenantId,
6521
+ input.projectId,
6522
+ input.userId
6523
+ );
6524
+ if (!membership || membership.tenantId !== input.tenantId || membership.projectId !== input.projectId || membership.userId !== input.userId || membership.status !== "active") this.accessDenied();
6525
+ this.requireCapability(membership, input.capability);
6526
+ return { project, membership };
6527
+ }
6528
+ /** Authorizes roster visibility: read for public rooms, manage elsewhere. */
6529
+ async requireRosterAccess(input) {
6530
+ const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
6531
+ if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
6532
+ return this.requireProjectAccess({
6533
+ ...input,
6534
+ capability: project.kind === "public" ? "read" : "manage"
6535
+ });
6536
+ }
6537
+ async requirePublicProjectAccess(project, input) {
6538
+ const membership = await this.deps.membershipStore.findByUser(
6539
+ input.tenantId,
6540
+ input.projectId,
6541
+ input.userId
6542
+ );
6543
+ if (membership?.status === "active") {
6544
+ this.requireCapability(membership, input.capability);
6545
+ return { project, membership };
6546
+ }
6547
+ const materialized = await this.materializePublicMembership(input);
6548
+ this.requireCapability(materialized, input.capability);
6549
+ return { project, membership: materialized };
6550
+ }
6551
+ async requireExistingPublicProjectAccess(project, input) {
6552
+ const membership = await this.deps.membershipStore.findByUser(
6553
+ input.tenantId,
6554
+ input.projectId,
6555
+ input.userId
6556
+ );
6557
+ if (membership?.status === "active") {
6558
+ this.requireCapability(membership, input.capability);
6559
+ return { project, membership };
6560
+ }
6561
+ if (membership) this.accessDenied();
6562
+ const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
6563
+ if (!tenantLink) this.accessDenied();
6564
+ const role = tenantLink.role === "owner" || tenantLink.role === "admin" ? "admin" : "member";
6565
+ const synthetic = {
6566
+ id: `public:${input.userId}`,
6567
+ tenantId: input.tenantId,
6568
+ projectId: input.projectId,
6569
+ userId: input.userId,
6570
+ role,
6571
+ status: "active",
6572
+ joinedAt: project.createdAt,
6573
+ updatedAt: project.updatedAt
6574
+ };
6575
+ this.requireCapability(synthetic, input.capability);
6576
+ return { project, membership: synthetic };
6577
+ }
6578
+ async materializePublicMembership(input) {
6579
+ const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
6580
+ if (!tenantLink) this.accessDenied();
6581
+ const existing = await this.deps.membershipStore.findByUser(
6582
+ input.tenantId,
6583
+ input.projectId,
6584
+ input.userId
6585
+ );
6586
+ if (existing) this.accessDenied();
6587
+ const role = tenantLink.role === "owner" || tenantLink.role === "admin" ? "admin" : "member";
6588
+ try {
6589
+ return await this.deps.membershipStore.create({
6590
+ id: this.idFactory(),
6591
+ tenantId: input.tenantId,
6592
+ projectId: input.projectId,
6593
+ userId: input.userId,
6594
+ role,
6595
+ status: "active"
6596
+ });
6597
+ } catch (error) {
6598
+ if (isProjectMembershipConflict(error)) {
6599
+ const raced = await this.deps.membershipStore.findByUser(
6600
+ input.tenantId,
6601
+ input.projectId,
6602
+ input.userId
6603
+ );
6604
+ if (raced?.status === "active") return raced;
6605
+ }
6606
+ throw error;
6607
+ }
6608
+ }
6609
+ requireCapability(membership, capability2) {
6610
+ if (!allowedRoles[capability2].has(membership.role)) this.accessDenied();
6611
+ }
6612
+ accessDenied() {
6613
+ throw new ProjectCollaborationError("PROJECT_ACCESS_DENIED", 403, "Project access denied");
6614
+ }
6615
+ };
6428
6616
 
6429
6617
  // src/controllers/database-configs.ts
6430
6618
  import {
6431
6619
  getStoreLattice as getStoreLattice7,
6432
6620
  sqlDatabaseManager
6433
6621
  } from "@axiom-lattice/core";
6434
- import { randomUUID as randomUUID6 } from "crypto";
6622
+ import { randomUUID as randomUUID7 } from "crypto";
6435
6623
  function getTenantId9(request) {
6436
6624
  const userTenantId = request.user?.tenantId;
6437
6625
  if (userTenantId) {
@@ -6509,7 +6697,7 @@ async function createDatabaseConfig(request, reply) {
6509
6697
  message: "Database configuration with this key already exists"
6510
6698
  };
6511
6699
  }
6512
- const id3 = body.id || randomUUID6();
6700
+ const id3 = body.id || randomUUID7();
6513
6701
  const config = await store.createConfig(tenantId, id3, body);
6514
6702
  try {
6515
6703
  sqlDatabaseManager.registerDatabase(tenantId, config.key, config.config);
@@ -6714,7 +6902,7 @@ import {
6714
6902
  metricsServerManager as metricsServerManager2,
6715
6903
  SemanticMetricsClient as SemanticMetricsClient2
6716
6904
  } from "@axiom-lattice/core";
6717
- import { randomUUID as randomUUID7 } from "crypto";
6905
+ import { randomUUID as randomUUID8 } from "crypto";
6718
6906
  function getTenantId10(request) {
6719
6907
  const userTenantId = request.user?.tenantId;
6720
6908
  if (userTenantId) {
@@ -6795,7 +6983,7 @@ async function createMetricsServerConfig(request, reply) {
6795
6983
  message: "selectedDataSources is required for semantic metrics servers"
6796
6984
  };
6797
6985
  }
6798
- const id3 = body.id || randomUUID7();
6986
+ const id3 = body.id || randomUUID8();
6799
6987
  const configData = {
6800
6988
  key: body.key,
6801
6989
  name: body.name,
@@ -8911,13 +9099,13 @@ function isStaleConsoleSessionCredential(authHeader) {
8911
9099
  }
8912
9100
  }
8913
9101
  function bypassesConsoleAuth(request) {
8914
- const path4 = request.url.split("?")[0];
9102
+ const path5 = request.url.split("?")[0];
8915
9103
  const method = request.method;
8916
- if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path4) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path4) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path4) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path4) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path4) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path4)) return true;
8917
- if (request.method === "GET" && /^\/api\/a2a\/agents\/[^/]+\/\.well-known\/agent-card\.json$/.test(path4)) {
9104
+ if (method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/bootstrap$/.test(path5) || (method === "GET" || method === "POST") && /^\/api\/web-apps\/[^/]+\/runtime\/threads$/.test(path5) || (method === "PATCH" || method === "DELETE") && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/messages$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/files\/(viewfile|downloadfile)$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/runtime\/api\/assistants\/[^/]+\/threads\/[^/]+\/sandbox\/(viewfile|downloadfile)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/(messages\/stream|abort|attachments)$/.test(path5) || method === "POST" && /^\/api\/web-apps\/[^/]+\/runtime\/threads\/[^/]+\/interrupts\/[^/]+\/resume$/.test(path5) || method === "GET" && /^\/api\/web-apps\/[^/]+\/chat$/.test(path5) || method === "GET" && /^\/embed\/[^/]+$/.test(path5) || (method === "POST" || method === "DELETE") && path5 === "/open/mcp") return true;
9105
+ if (request.method === "GET" && /^\/api\/a2a\/agents\/[^/]+\/\.well-known\/agent-card\.json$/.test(path5)) {
8918
9106
  return true;
8919
9107
  }
8920
- return request.method === "POST" && /^\/api\/a2a\/agents\/[^/]+\/jsonrpc$/.test(path4);
9108
+ return request.method === "POST" && /^\/api\/a2a\/agents\/[^/]+\/jsonrpc$/.test(path5);
8921
9109
  }
8922
9110
  function registerConsoleAuthHook(app2, options) {
8923
9111
  app2.addHook("preHandler", async (request, reply) => {
@@ -8940,8 +9128,8 @@ function registerConsoleAuthHook(app2, options) {
8940
9128
  }
8941
9129
  if (PUBLIC_ROUTES.some((route) => request.url === route)) return;
8942
9130
  if (request.url.startsWith("/s/")) return;
8943
- const path4 = request.url.split("?")[0];
8944
- if (request.method === "GET" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/viewfile$/.test(path4) || request.method === "GET" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/downloadfile$/.test(path4) || request.method === "POST" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/uploadfile$/.test(path4) || path4.startsWith("/f/") || path4 === "/f") {
9131
+ const path5 = request.url.split("?")[0];
9132
+ if (request.method === "GET" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/viewfile$/.test(path5) || request.method === "GET" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/downloadfile$/.test(path5) || request.method === "POST" && /^\/api\/workspaces\/[^/]+\/projects\/[^/]+\/uploadfile$/.test(path5) || path5.startsWith("/f/") || path5 === "/f") {
8945
9133
  return;
8946
9134
  }
8947
9135
  await reply.status(401).send({
@@ -9302,7 +9490,7 @@ function registerChannelRoutes(app2, dependencies) {
9302
9490
  }
9303
9491
 
9304
9492
  // src/controllers/channel-installations.ts
9305
- import { randomUUID as randomUUID8 } from "crypto";
9493
+ import { randomUUID as randomUUID9 } from "crypto";
9306
9494
  import {
9307
9495
  descriptorDataValue
9308
9496
  } from "@axiom-lattice/protocols";
@@ -9506,7 +9694,7 @@ async function createChannelInstallation(request, reply) {
9506
9694
  };
9507
9695
  }
9508
9696
  const store = await getInstallationStore();
9509
- const installationId = randomUUID8();
9697
+ const installationId = randomUUID9();
9510
9698
  const createInput = {
9511
9699
  channel: body.channel,
9512
9700
  name: body.name,
@@ -10069,8 +10257,8 @@ var log = {
10069
10257
  };
10070
10258
  var connections = /* @__PURE__ */ new Map();
10071
10259
  var pending = /* @__PURE__ */ new Map();
10072
- function getAgentIdFromPath(path4) {
10073
- const match = path4.match(/^\/api\/a2a\/bridge\/proxy\/([^/]+)/);
10260
+ function getAgentIdFromPath(path5) {
10261
+ const match = path5.match(/^\/api\/a2a\/bridge\/proxy\/([^/]+)/);
10074
10262
  return match ? match[1] : null;
10075
10263
  }
10076
10264
  function handleBridgeConnection(socket, _request) {
@@ -10466,7 +10654,7 @@ async function getLocalA2ATemplates(_request, reply) {
10466
10654
  }
10467
10655
 
10468
10656
  // src/routes/a2a-test-connection.ts
10469
- import { randomUUID as randomUUID9 } from "crypto";
10657
+ import { randomUUID as randomUUID10 } from "crypto";
10470
10658
  function describeTestConnectionError(error, agentCardUrl) {
10471
10659
  if (!(error instanceof Error)) {
10472
10660
  return `Failed to fetch agent card from ${agentCardUrl}: ${String(error)}`;
@@ -10506,7 +10694,7 @@ async function ensureLocalRuntimeForConnectionTest(localRuntime, agentCardUrl) {
10506
10694
  return { error: portValidation.error };
10507
10695
  }
10508
10696
  const state = await localA2AService.startProvider(
10509
- `test-${randomUUID9()}`,
10697
+ `test-${randomUUID10()}`,
10510
10698
  testRuntime
10511
10699
  );
10512
10700
  if (state.status === "running") return { runtimeId: state.runtimeId };
@@ -10595,193 +10783,6 @@ import {
10595
10783
  import { snapshotExactRecord as snapshotExactRecord3 } from "@axiom-lattice/protocols";
10596
10784
  import { ProjectTaskOwnerPolicyError, projectTaskAdmissionNotifier } from "@axiom-lattice/core";
10597
10785
 
10598
- // src/services/collaboration/ProjectAccessService.ts
10599
- import { randomUUID as randomUUID10 } from "crypto";
10600
- var ProjectCollaborationError = class extends Error {
10601
- /** Creates a project collaboration error. */
10602
- constructor(code, statusCode, message) {
10603
- super(message);
10604
- this.code = code;
10605
- this.statusCode = statusCode;
10606
- this.name = "ProjectCollaborationError";
10607
- }
10608
- };
10609
- var allowedRoles = {
10610
- read: /* @__PURE__ */ new Set(["owner", "admin", "member", "viewer"]),
10611
- send: /* @__PURE__ */ new Set(["owner", "admin", "member"]),
10612
- manage: /* @__PURE__ */ new Set(["owner", "admin"])
10613
- };
10614
- var membershipConflictNames = /* @__PURE__ */ new Set([
10615
- "DuplicateProjectMembershipError",
10616
- "ProjectMembershipIdConflictError"
10617
- ]);
10618
- function isProjectMembershipConflict(error) {
10619
- return error instanceof Error && membershipConflictNames.has(error.name);
10620
- }
10621
- var ProjectAccessService = class {
10622
- /** Creates a project access service from explicitly injected stores. */
10623
- constructor(deps) {
10624
- this.deps = deps;
10625
- this.idFactory = deps.idFactory ?? randomUUID10;
10626
- }
10627
- /** Returns the project and active membership when the user has the requested capability. */
10628
- async requireProjectAccess(input) {
10629
- const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
10630
- if (!project) {
10631
- throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
10632
- }
10633
- if (project.kind === "public") {
10634
- return this.requirePublicProjectAccess(project, input);
10635
- }
10636
- const membership = await this.deps.membershipStore.findByUser(
10637
- input.tenantId,
10638
- input.projectId,
10639
- input.userId
10640
- );
10641
- if (membership?.status === "active") {
10642
- this.requireCapability(membership, input.capability);
10643
- return { project, membership };
10644
- }
10645
- const memberships = await this.deps.membershipStore.list(input.tenantId, input.projectId);
10646
- if (memberships.length !== 0) this.accessDenied();
10647
- if (project.kind === "personal") this.accessDenied();
10648
- const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
10649
- if (tenantLink?.role !== "owner" && tenantLink?.role !== "admin") this.accessDenied();
10650
- let claim;
10651
- try {
10652
- claim = await this.deps.membershipStore.createInitialOwner({
10653
- id: this.idFactory(),
10654
- tenantId: input.tenantId,
10655
- projectId: input.projectId,
10656
- userId: input.userId
10657
- });
10658
- } catch (error) {
10659
- if (isProjectMembershipConflict(error)) {
10660
- throw new ProjectCollaborationError(
10661
- "PROJECT_MEMBERSHIP_CONFLICT",
10662
- 409,
10663
- "Project membership could not be initialized"
10664
- );
10665
- }
10666
- throw error;
10667
- }
10668
- if (claim.kind === "created" || claim.kind === "existing") {
10669
- return { project, membership: claim.membership };
10670
- }
10671
- const racedMembership = await this.deps.membershipStore.findByUser(
10672
- input.tenantId,
10673
- input.projectId,
10674
- input.userId
10675
- );
10676
- if (racedMembership?.status !== "active") this.accessDenied();
10677
- this.requireCapability(racedMembership, input.capability);
10678
- return { project, membership: racedMembership };
10679
- }
10680
- /** Authorizes an already-existing membership, or any tenant member for public rooms; never mutates persistence. */
10681
- async requireExistingProjectAccess(input) {
10682
- const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
10683
- if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
10684
- if (project.kind === "public") {
10685
- return this.requireExistingPublicProjectAccess(project, input);
10686
- }
10687
- const membership = await this.deps.membershipStore.findByUser(
10688
- input.tenantId,
10689
- input.projectId,
10690
- input.userId
10691
- );
10692
- if (!membership || membership.tenantId !== input.tenantId || membership.projectId !== input.projectId || membership.userId !== input.userId || membership.status !== "active") this.accessDenied();
10693
- this.requireCapability(membership, input.capability);
10694
- return { project, membership };
10695
- }
10696
- /** Authorizes roster visibility: read for public rooms, manage elsewhere. */
10697
- async requireRosterAccess(input) {
10698
- const project = await this.deps.projectStore.getProjectById(input.tenantId, input.projectId);
10699
- if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
10700
- return this.requireProjectAccess({
10701
- ...input,
10702
- capability: project.kind === "public" ? "read" : "manage"
10703
- });
10704
- }
10705
- async requirePublicProjectAccess(project, input) {
10706
- const membership = await this.deps.membershipStore.findByUser(
10707
- input.tenantId,
10708
- input.projectId,
10709
- input.userId
10710
- );
10711
- if (membership?.status === "active") {
10712
- this.requireCapability(membership, input.capability);
10713
- return { project, membership };
10714
- }
10715
- const materialized = await this.materializePublicMembership(input);
10716
- this.requireCapability(materialized, input.capability);
10717
- return { project, membership: materialized };
10718
- }
10719
- async requireExistingPublicProjectAccess(project, input) {
10720
- const membership = await this.deps.membershipStore.findByUser(
10721
- input.tenantId,
10722
- input.projectId,
10723
- input.userId
10724
- );
10725
- if (membership?.status === "active") {
10726
- this.requireCapability(membership, input.capability);
10727
- return { project, membership };
10728
- }
10729
- if (membership) this.accessDenied();
10730
- const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
10731
- if (!tenantLink) this.accessDenied();
10732
- const role = tenantLink.role === "owner" || tenantLink.role === "admin" ? "admin" : "member";
10733
- const synthetic = {
10734
- id: `public:${input.userId}`,
10735
- tenantId: input.tenantId,
10736
- projectId: input.projectId,
10737
- userId: input.userId,
10738
- role,
10739
- status: "active",
10740
- joinedAt: project.createdAt,
10741
- updatedAt: project.updatedAt
10742
- };
10743
- this.requireCapability(synthetic, input.capability);
10744
- return { project, membership: synthetic };
10745
- }
10746
- async materializePublicMembership(input) {
10747
- const tenantLink = await this.deps.userTenantLinkStore.getLink(input.userId, input.tenantId);
10748
- if (!tenantLink) this.accessDenied();
10749
- const existing = await this.deps.membershipStore.findByUser(
10750
- input.tenantId,
10751
- input.projectId,
10752
- input.userId
10753
- );
10754
- if (existing) this.accessDenied();
10755
- const role = tenantLink.role === "owner" || tenantLink.role === "admin" ? "admin" : "member";
10756
- try {
10757
- return await this.deps.membershipStore.create({
10758
- id: this.idFactory(),
10759
- tenantId: input.tenantId,
10760
- projectId: input.projectId,
10761
- userId: input.userId,
10762
- role,
10763
- status: "active"
10764
- });
10765
- } catch (error) {
10766
- if (isProjectMembershipConflict(error)) {
10767
- const raced = await this.deps.membershipStore.findByUser(
10768
- input.tenantId,
10769
- input.projectId,
10770
- input.userId
10771
- );
10772
- if (raced?.status === "active") return raced;
10773
- }
10774
- throw error;
10775
- }
10776
- }
10777
- requireCapability(membership, capability2) {
10778
- if (!allowedRoles[capability2].has(membership.role)) this.accessDenied();
10779
- }
10780
- accessDenied() {
10781
- throw new ProjectCollaborationError("PROJECT_ACCESS_DENIED", 403, "Project access denied");
10782
- }
10783
- };
10784
-
10785
10786
  // src/services/collaboration/ProjectTaskThreadService.ts
10786
10787
  import { isProjectLifecycleTask } from "@axiom-lattice/core";
10787
10788
  import {
@@ -11320,9 +11321,6 @@ function governedUpdate(task, body) {
11320
11321
  if (has("ownerType") && body.ownerType !== task.ownerType || has("ownerId") && body.ownerId !== task.ownerId) {
11321
11322
  return "TASK_OWNERSHIP_IMMUTABLE";
11322
11323
  }
11323
- if (task.ownerType !== "agent") return void 0;
11324
- if (has("parentId") && body.parentId !== task.parentId || has("dependencies") || has("requireReview") || has("result") || has("failureReason") || has("status")) return "TASK_LIFECYCLE_TRANSITION_REQUIRED";
11325
- if (has("context") || has("description")) return "COMPLETION_CONTEXT_MUTATION";
11326
11324
  return void 0;
11327
11325
  }
11328
11326
  function lifecycleStatus(code) {
@@ -11763,7 +11761,8 @@ var AgentWebAppService = class {
11763
11761
  integration: current.integration,
11764
11762
  scope: { ...current.scope, ...patch.scope },
11765
11763
  features: { ...current.features, ...patch.features },
11766
- appearance: { ...current.appearance, ...patch.appearance }
11764
+ appearance: { ...current.appearance, ...patch.appearance },
11765
+ identity: patch.identity ?? current.identity
11767
11766
  };
11768
11767
  await this.validateAssistant(context, current.assistantId);
11769
11768
  const validated = await this.validateConfig(context.tenantId, effective);
@@ -11772,7 +11771,8 @@ var AgentWebAppService = class {
11772
11771
  ...Object.prototype.hasOwnProperty.call(patch, "description") ? { description: validated.description } : {},
11773
11772
  ...patch.scope ? { scope: validated.scope } : {},
11774
11773
  ...patch.features ? { features: validated.features } : {},
11775
- ...patch.appearance ? { appearance: validated.appearance } : {}
11774
+ ...patch.appearance ? { appearance: validated.appearance } : {},
11775
+ ...patch.identity !== void 0 ? { identity: patch.identity } : {}
11776
11776
  };
11777
11777
  return this.writeSnapshot(context, current, update);
11778
11778
  }
@@ -11885,13 +11885,28 @@ var agentWebAppFeaturesSchema = z4.object({
11885
11885
  threadManagement: z4.boolean(),
11886
11886
  attachments: z4.boolean(),
11887
11887
  hitl: z4.boolean(),
11888
- genUI: z4.boolean()
11888
+ genUI: z4.boolean(),
11889
+ files: z4.boolean().optional()
11889
11890
  }).strict();
11890
11891
  var agentWebAppAppearanceSchema = z4.object({
11891
11892
  title: z4.string().max(120).optional(),
11892
11893
  welcomeMessage: z4.string().max(1e3).optional(),
11893
11894
  primaryColor: z4.string().regex(/^#[0-9A-Fa-f]{6}$/).optional()
11894
11895
  }).strict();
11896
+ var agentWebAppIssuerSchema = z4.object({
11897
+ iss: z4.string().min(1).max(255),
11898
+ aud: z4.string().min(1).max(255),
11899
+ alg: z4.enum(["HS256", "RS256"]),
11900
+ secret: z4.string().min(1).max(512).optional(),
11901
+ jwksUrl: z4.string().url().max(2048).optional()
11902
+ }).strict().refine(
11903
+ (value) => value.alg === "HS256" ? value.secret !== void 0 : value.jwksUrl !== void 0,
11904
+ { message: "HS256 requires secret; RS256 requires jwksUrl" }
11905
+ );
11906
+ var agentWebAppIdentitySchema = z4.object({
11907
+ policy: z4.enum(["unverified", "verified", "both"]),
11908
+ issuers: z4.array(agentWebAppIssuerSchema).min(1).max(10)
11909
+ }).strict();
11895
11910
  var createAgentWebAppSchema = z4.object({
11896
11911
  assistantId: externalId,
11897
11912
  name: z4.string().min(1).max(120),
@@ -11899,14 +11914,16 @@ var createAgentWebAppSchema = z4.object({
11899
11914
  integration: z4.object({ type: z4.literal("react_sdk") }).strict(),
11900
11915
  scope: agentWebAppScopeSchema,
11901
11916
  features: agentWebAppFeaturesSchema,
11902
- appearance: agentWebAppAppearanceSchema
11917
+ appearance: agentWebAppAppearanceSchema,
11918
+ identity: agentWebAppIdentitySchema.optional()
11903
11919
  }).strict();
11904
11920
  var updateAgentWebAppSchema = z4.object({
11905
11921
  name: z4.string().min(1).max(120).optional(),
11906
11922
  description: z4.string().max(1e3).optional(),
11907
11923
  scope: agentWebAppScopeSchema.partial().strict().optional(),
11908
11924
  features: agentWebAppFeaturesSchema.partial().strict().optional(),
11909
- appearance: agentWebAppAppearanceSchema.partial().strict().optional()
11925
+ appearance: agentWebAppAppearanceSchema.partial().strict().optional(),
11926
+ identity: agentWebAppIdentitySchema.optional()
11910
11927
  }).strict().refine((value) => Object.keys(value).length > 0, "Patch must not be empty");
11911
11928
  var listAgentWebAppsQuerySchema = z4.object({
11912
11929
  assistantId: externalId.optional()
@@ -11993,6 +12010,7 @@ function invalidRequest(reply, statusCode) {
11993
12010
  }
11994
12011
 
11995
12012
  // src/routes/agent-web-app-runtime.ts
12013
+ import { createHmac as createHmac3 } from "crypto";
11996
12014
  import { z as z5, ZodError as ZodError2 } from "zod";
11997
12015
 
11998
12016
  // src/services/agent-web-app/AgentWebAppRuntimeService.ts
@@ -12013,7 +12031,16 @@ var AgentWebAppRuntimeService = class {
12013
12031
  constructor(deps) {
12014
12032
  this.deps = deps;
12015
12033
  }
12016
- async bootstrap(webAppId, userId, selection) {
12034
+ /** Identity policy configuration for the web app, or null when the app is missing/unconfigured. */
12035
+ async getIdentityConfig(webAppId) {
12036
+ try {
12037
+ const runtime = await this.resolveRuntime(webAppId, {});
12038
+ return runtime.webApp.identity ?? null;
12039
+ } catch {
12040
+ return null;
12041
+ }
12042
+ }
12043
+ async bootstrap(webAppId, userId, selection, identity) {
12017
12044
  const runtime = await this.resolveRuntime(webAppId, selection);
12018
12045
  const assistant = await this.deps.assistantResolver.resolve(
12019
12046
  runtime.webApp.tenantId,
@@ -12046,7 +12073,7 @@ var AgentWebAppRuntimeService = class {
12046
12073
  defaultModelKey: runtime.webApp.scope.defaultModelKey,
12047
12074
  features: runtime.webApp.features,
12048
12075
  appearance: runtime.webApp.appearance,
12049
- identityAssurance: "unverified"
12076
+ identityAssurance: identity?.assurance ?? "unverified"
12050
12077
  },
12051
12078
  projects,
12052
12079
  models
@@ -12067,6 +12094,14 @@ var AgentWebAppRuntimeService = class {
12067
12094
  this.requireFeature(runtime.webApp.features.threadManagement);
12068
12095
  return this.createOwnedThread(runtime, userId, input.label);
12069
12096
  }
12097
+ /** Fetch one owned thread. */
12098
+ async getThread(webAppId, userId, threadId, selection) {
12099
+ const runtime = await this.resolveRuntime(webAppId, selection);
12100
+ await this.requireOwnedThread(runtime, userId, threadId);
12101
+ const thread = await this.deps.threadStore.getThreadById(runtime.webApp.tenantId, threadId);
12102
+ if (!thread) this.threadNotFound();
12103
+ return toRuntimeThread(thread);
12104
+ }
12070
12105
  /** Update a thread label; omitted or blank labels preserve the existing label. */
12071
12106
  async updateThread(webAppId, userId, threadId, input) {
12072
12107
  const runtime = await this.resolveRuntime(webAppId, input);
@@ -12101,6 +12136,60 @@ var AgentWebAppRuntimeService = class {
12101
12136
  return [{ id: message.id, role: message.role, ...content && (typeof content === "string" || content.length > 0) ? { content } : {} }];
12102
12137
  });
12103
12138
  }
12139
+ async getState(webAppId, userId, threadId, selection) {
12140
+ const runtime = await this.resolveRuntime(webAppId, selection);
12141
+ await this.requireOwnedThread(runtime, userId, threadId);
12142
+ const agent = this.resolveAgent(runtime, threadId);
12143
+ const state = await agent.getCurrentState();
12144
+ const pendingMessages = await agent.getPendingMessages();
12145
+ const normalized = pendingMessages.map((message) => ({
12146
+ ...message,
12147
+ content: typeof message.content === "object" && message.content !== null ? "message" in message.content ? message.content.message : JSON.stringify(message.content) : String(message.content ?? "")
12148
+ }));
12149
+ return { ...state && typeof state === "object" ? state : {}, pendingMessages: normalized };
12150
+ }
12151
+ /** Raw stored messages (Console memory contract, tool/interrupt preserved). */
12152
+ async getConsoleMessages(webAppId, userId, threadId, selection) {
12153
+ const runtime = await this.resolveRuntime(webAppId, selection);
12154
+ await this.requireOwnedThread(runtime, userId, threadId);
12155
+ return this.deps.messageReader.getCurrentMessages({
12156
+ tenantId: runtime.webApp.tenantId,
12157
+ assistantId: runtime.webApp.assistantId,
12158
+ threadId,
12159
+ workspaceId: runtime.project.workspaceId,
12160
+ projectId: runtime.project.id
12161
+ });
12162
+ }
12163
+ /** Background enqueue only (ADR-026): returns the message id; delivery happens over resume_stream. */
12164
+ async enqueueMessage(webAppId, userId, threadId, content, selection) {
12165
+ const runtime = await this.resolveOwnedRuntime(webAppId, userId, threadId, selection);
12166
+ const agent = this.resolveAgent(runtime, threadId);
12167
+ const execution = await this.execute(agent, runtime, { input: { message: content } });
12168
+ return { messageId: execution.messageId };
12169
+ }
12170
+ async removePendingMessage(webAppId, userId, threadId, messageId, selection) {
12171
+ const runtime = await this.resolveRuntime(webAppId, selection);
12172
+ await this.requireOwnedThread(runtime, userId, threadId);
12173
+ const agent = this.resolveAgent(runtime, threadId);
12174
+ if (!await agent.removePendingMessage(messageId)) this.threadNotFound();
12175
+ }
12176
+ /** Thread-lifetime SSE resume from the last known client message id. */
12177
+ async resumeStream(webAppId, userId, threadId, messageId, selection) {
12178
+ const runtime = await this.resolveRuntime(webAppId, selection);
12179
+ await this.requireOwnedThread(runtime, userId, threadId);
12180
+ const agent = this.resolveAgent(runtime, threadId);
12181
+ return { stream: agent.chunkStream(messageId, []) };
12182
+ }
12183
+ async resolveFileScope(webAppId, selection) {
12184
+ const runtime = await this.resolveRuntime(webAppId, selection);
12185
+ return {
12186
+ tenantId: runtime.webApp.tenantId,
12187
+ workspaceId: runtime.project.workspaceId,
12188
+ projectId: runtime.project.id,
12189
+ assistantId: runtime.webApp.assistantId,
12190
+ enabled: runtime.webApp.features.files === true
12191
+ };
12192
+ }
12104
12193
  async streamMessage(webAppId, userId, threadId, input) {
12105
12194
  const runtime = await this.resolveOwnedRuntime(webAppId, userId, threadId, input);
12106
12195
  const refs = this.resolveAttachmentRefs(runtime, userId, threadId, input.attachmentRefs ?? []);
@@ -12345,96 +12434,102 @@ function toRuntimeThread(thread) {
12345
12434
  };
12346
12435
  }
12347
12436
 
12348
- // src/services/agent-web-app/AgentWebAppStreamProjector.ts
12349
- import {
12350
- MessageChunkTypes as MessageChunkTypes4,
12351
- parseAgentWebAppGenUIBlock as parseAgentWebAppGenUIBlock2
12352
- } from "@axiom-lattice/protocols";
12353
- function createAgentWebAppStreamProjectionContext(options = {}) {
12354
- return { startedToolIds: /* @__PURE__ */ new Set(), allowInterrupts: options.allowInterrupts ?? true, allowGenUI: options.allowGenUI ?? false };
12355
- }
12356
- function projectAgentWebAppChunk(chunk, context) {
12357
- if (chunk.type === MessageChunkTypes4.AI) {
12358
- const events = [];
12359
- const startedToolIds = context?.startedToolIds ?? /* @__PURE__ */ new Set();
12360
- if (typeof chunk.data.content === "string" && chunk.data.content) events.push({ type: "message.delta", text: chunk.data.content });
12361
- if (context?.allowGenUI && Array.isArray(chunk.data.content)) {
12362
- for (const value of chunk.data.content) {
12363
- const block = parseAgentWebAppGenUIBlock2(value);
12364
- if (block) events.push({ type: "genui.render", block });
12365
- }
12366
- }
12367
- for (const call of chunk.data.tool_call_chunks ?? []) {
12368
- if (call.id && call.name && !startedToolIds.has(call.id)) {
12369
- startedToolIds.add(call.id);
12370
- events.push({ type: "tool.started", id: call.id, name: call.name });
12371
- }
12372
- }
12373
- for (const call of chunk.data.tool_calls ?? []) {
12374
- if (!startedToolIds.has(call.id)) {
12375
- startedToolIds.add(call.id);
12376
- events.push({ type: "tool.started", id: call.id, name: call.name });
12377
- }
12378
- }
12379
- return events;
12380
- }
12381
- if (chunk.type === MessageChunkTypes4.TOOL && chunk.data.tool_call_id) {
12382
- return [{ type: "tool.completed", id: chunk.data.tool_call_id }];
12383
- }
12384
- if (chunk.type === MessageChunkTypes4.INTERRUPT) {
12385
- if (context && !context.allowInterrupts) return [{ type: "stream.completed" }];
12386
- const interrupt = publicInterrupt(chunk);
12387
- return interrupt ? [{ type: "interrupt.created", interrupt }, { type: "stream.completed" }] : [{ type: "stream.completed" }];
12388
- }
12389
- if (chunk.type === MessageChunkTypes4.MESSAGE_COMPLETED) {
12390
- return [
12391
- { type: "message.completed", messageId: chunk.data.id },
12392
- { type: "stream.completed" }
12393
- ];
12394
- }
12395
- if (chunk.type === MessageChunkTypes4.MESSAGE_FAILED) {
12396
- return [
12397
- { type: "error", error: { code: "STREAM_FAILED", message: "Stream failed", retryable: true } },
12398
- { type: "stream.completed" }
12399
- ];
12437
+ // src/services/agent-web-app/AgentWebAppTokenVerifier.ts
12438
+ import { createHmac as createHmac2, createPublicKey, timingSafeEqual as timingSafeEqual2, verify as cryptoVerify } from "crypto";
12439
+ var WebAppTokenError = class extends Error {
12440
+ constructor(message) {
12441
+ super(message);
12442
+ this.name = "WebAppTokenError";
12400
12443
  }
12401
- return [];
12402
- }
12403
- function publicInterrupt(chunk) {
12404
- const value = parseInterruptContent(chunk.data.content);
12405
- if (!value) return void 0;
12406
- const topLevelId = chunk.id;
12407
- const id3 = typeof topLevelId === "string" ? topLevelId : chunk.data.id;
12408
- if (!id3) return void 0;
12409
- return {
12410
- id: id3,
12411
- type: typeof value.type === "string" ? value.type : "input",
12412
- prompt: typeof value.prompt === "string" ? value.prompt : typeof value.message === "string" ? value.message : "Input required",
12413
- ...isRecord3(value.data) ? { data: value.data } : {}
12414
- };
12415
- }
12416
- function parseInterruptContent(content) {
12417
- if (!content) return {};
12418
- if (isRecord3(content)) return content;
12419
- if (typeof content !== "string") return void 0;
12444
+ };
12445
+ var MAX_TOKEN_BYTES = 8 * 1024;
12446
+ var CLOCK_SKEW_SECONDS = 60;
12447
+ var JWKS_TTL_MS = 10 * 60 * 1e3;
12448
+ var jwksCache = /* @__PURE__ */ new Map();
12449
+ function decodeSegment(segment) {
12450
+ const json = Buffer.from(segment, "base64url").toString("utf8");
12451
+ let value;
12420
12452
  try {
12421
- const parsed = JSON.parse(content);
12422
- return isRecord3(parsed) ? parsed : { prompt: content };
12453
+ value = JSON.parse(json);
12423
12454
  } catch {
12424
- return { prompt: content };
12455
+ throw new WebAppTokenError("Malformed token segment");
12425
12456
  }
12457
+ if (typeof value !== "object" || value === null) throw new WebAppTokenError("Malformed token segment");
12458
+ return value;
12426
12459
  }
12427
- function isRecord3(value) {
12428
- return typeof value === "object" && value !== null && !Array.isArray(value);
12460
+ async function resolveKey(issuer, kid, fetchImpl) {
12461
+ const cacheKey = issuer.jwksUrl ?? "";
12462
+ const load = async () => {
12463
+ const response = await fetchImpl(issuer.jwksUrl ?? "");
12464
+ if (!response.ok) throw new WebAppTokenError("JWKS fetch failed");
12465
+ const document = await response.json();
12466
+ const keys2 = document.keys;
12467
+ const entry2 = { keys: Array.isArray(keys2) ? keys2 : [], fetchedAt: Date.now() };
12468
+ jwksCache.set(cacheKey, entry2);
12469
+ return entry2;
12470
+ };
12471
+ const cached = jwksCache.get(cacheKey);
12472
+ let entry = cached && Date.now() - cached.fetchedAt < JWKS_TTL_MS ? cached : await load();
12473
+ let jwk = entry.keys.find((key) => kid === void 0 ? true : key.kid === kid);
12474
+ if (!jwk && kid !== void 0) {
12475
+ entry = await load();
12476
+ jwk = entry.keys.find((key) => key.kid === kid);
12477
+ }
12478
+ if (!jwk) throw new WebAppTokenError("No matching JWKS key");
12479
+ return createPublicKey({ key: jwk, format: "jwk" });
12480
+ }
12481
+ async function verifyWebAppToken(token, issuer, options = {}) {
12482
+ const nowMs = options.now ? options.now() : Date.now();
12483
+ const now = Math.floor(nowMs / 1e3);
12484
+ if (token.length === 0 || Buffer.byteLength(token) > MAX_TOKEN_BYTES) throw new WebAppTokenError("Token size invalid");
12485
+ const parts = token.split(".");
12486
+ if (parts.length !== 3) throw new WebAppTokenError("Token structure invalid");
12487
+ const [rawHeader, rawPayload, rawSignature] = parts;
12488
+ const header2 = decodeSegment(rawHeader);
12489
+ const payload = decodeSegment(rawPayload);
12490
+ if (header2.alg !== issuer.alg) throw new WebAppTokenError("Token algorithm mismatch");
12491
+ if (payload.iss !== issuer.iss) throw new WebAppTokenError("Token issuer mismatch");
12492
+ if (payload.aud !== issuer.aud) throw new WebAppTokenError("Token audience mismatch");
12493
+ const exp = typeof payload.exp === "number" ? payload.exp : void 0;
12494
+ if (exp === void 0 || exp + CLOCK_SKEW_SECONDS < now) throw new WebAppTokenError("Token expired");
12495
+ const nbf = typeof payload.nbf === "number" ? payload.nbf : void 0;
12496
+ if (nbf !== void 0 && nbf - CLOCK_SKEW_SECONDS > now) throw new WebAppTokenError("Token not yet valid");
12497
+ const signature = Buffer.from(rawSignature, "base64url");
12498
+ const data = Buffer.from(`${rawHeader}.${rawPayload}`);
12499
+ if (issuer.alg === "HS256") {
12500
+ if (typeof issuer.secret !== "string" || issuer.secret.length === 0) throw new WebAppTokenError("Issuer secret missing");
12501
+ const expected = createHmac2("sha256", issuer.secret).update(data).digest();
12502
+ if (signature.length !== expected.length || !timingSafeEqual2(signature, expected)) {
12503
+ throw new WebAppTokenError("Token signature invalid");
12504
+ }
12505
+ } else {
12506
+ if (typeof issuer.jwksUrl !== "string") throw new WebAppTokenError("Issuer JWKS URL missing");
12507
+ const key = await resolveKey(issuer, typeof header2.kid === "string" ? header2.kid : void 0, options.fetchImpl ?? fetch);
12508
+ let valid = false;
12509
+ try {
12510
+ valid = cryptoVerify("RSA-SHA256", data, key, signature);
12511
+ } catch {
12512
+ valid = false;
12513
+ }
12514
+ if (!valid) throw new WebAppTokenError("Token signature invalid");
12515
+ }
12516
+ const sub = payload.sub;
12517
+ if (typeof sub !== "string" || sub.length === 0 || sub.length > 128 || !/^[A-Za-z0-9._:@-]+$/.test(sub)) {
12518
+ throw new WebAppTokenError("Token subject invalid");
12519
+ }
12520
+ return sub;
12429
12521
  }
12430
12522
 
12431
12523
  // src/routes/agent-web-app-runtime.ts
12524
+ import { createAgentWebAppStreamProjectionContext, projectAgentWebAppChunk } from "@axiom-lattice/protocols";
12432
12525
  var idSchema = z5.string().min(1).max(128);
12433
12526
  var paramsSchema = z5.object({ webAppId: idSchema }).strict();
12434
12527
  var threadParamsSchema = z5.object({ webAppId: idSchema, threadId: idSchema }).strict();
12435
12528
  var interruptParamsSchema = z5.object({ webAppId: idSchema, threadId: idSchema, interruptId: idSchema }).strict();
12529
+ var pendingMessageParamsSchema = z5.object({ webAppId: idSchema, threadId: idSchema, messageId: idSchema }).strict();
12436
12530
  var bootstrapQuerySchema = z5.object({ projectId: idSchema.optional(), modelKey: idSchema.optional() }).strict();
12437
12531
  var projectQuerySchema = z5.object({ projectId: idSchema.optional() }).strict();
12532
+ var projectQueryLenientSchema = projectQuerySchema.passthrough();
12438
12533
  var threadBodySchema = z5.object({ projectId: idSchema.optional(), label: z5.string().max(128).optional() }).strict();
12439
12534
  var streamBodySchema = z5.object({
12440
12535
  content: z5.string().trim().min(1).max(32768),
@@ -12453,8 +12548,27 @@ var resumeBodySchema = z5.object({
12453
12548
  ])
12454
12549
  }).strict();
12455
12550
  var MAX_ATTACHMENT_BYTES = 10 * 1024 * 1024;
12551
+ var stateQuerySchema = z5.object({
12552
+ threadId: idSchema,
12553
+ projectId: idSchema.optional(),
12554
+ modelKey: idSchema.optional()
12555
+ }).strict();
12556
+ var resumeSchema = z5.object({
12557
+ messageId: idSchema,
12558
+ projectId: idSchema.optional(),
12559
+ modelKey: idSchema.optional()
12560
+ }).strict();
12561
+ var devTokenSchema = z5.object({
12562
+ iss: z5.string().min(1).max(255).optional(),
12563
+ sub: z5.string().regex(/^[A-Za-z0-9._:@-]+$/).max(128).optional(),
12564
+ hours: z5.number().gt(0).max(720).optional()
12565
+ }).strict();
12566
+ var fileQuerySchema = z5.object({
12567
+ projectId: idSchema.optional(),
12568
+ modelKey: idSchema.optional()
12569
+ }).passthrough();
12456
12570
  function createExternalHeaderIdentityResolver() {
12457
- return { resolve(request) {
12571
+ return { async resolve(request) {
12458
12572
  const raw = request.headers["x-axiom-external-user-id"];
12459
12573
  if (raw === void 0) throw new AgentWebAppRuntimeError("USER_ID_REQUIRED", 401, "External user id is required");
12460
12574
  if (Array.isArray(raw) || typeof raw !== "string") throw new AgentWebAppRuntimeError("INVALID_USER_ID", 400, "External user id is invalid");
@@ -12463,47 +12577,109 @@ function createExternalHeaderIdentityResolver() {
12463
12577
  return { userId, assurance: "unverified" };
12464
12578
  } };
12465
12579
  }
12580
+ function createWebAppIdentityResolver(deps) {
12581
+ const headerResolver = createExternalHeaderIdentityResolver();
12582
+ return {
12583
+ async resolve(request, webAppId) {
12584
+ let config;
12585
+ try {
12586
+ config = await deps.getIdentityConfig(webAppId);
12587
+ } catch {
12588
+ config = void 0;
12589
+ }
12590
+ const policy = config?.policy ?? "unverified";
12591
+ const authHeader = request.headers.authorization;
12592
+ const bearer = typeof authHeader === "string" && authHeader.startsWith("Bearer ") ? authHeader.slice(7).trim() : void 0;
12593
+ if (policy !== "unverified" && bearer !== void 0) {
12594
+ const issuers = config?.issuers ?? [];
12595
+ if (issuers.length === 0) throw new AgentWebAppRuntimeError("INVALID_REQUEST", 401, "No trusted issuer configured");
12596
+ let lastError = new AgentWebAppRuntimeError("INVALID_REQUEST", 401, "Invalid identity token");
12597
+ for (const issuer of issuers) {
12598
+ try {
12599
+ const sub = await verifyWebAppToken(bearer, issuer);
12600
+ return { userId: sub, assurance: "verified" };
12601
+ } catch (error) {
12602
+ if (error instanceof WebAppTokenError) {
12603
+ lastError = error;
12604
+ continue;
12605
+ }
12606
+ throw error;
12607
+ }
12608
+ }
12609
+ const message = lastError instanceof WebAppTokenError ? `Invalid identity token: ${lastError.message}` : "Invalid identity token";
12610
+ throw new AgentWebAppRuntimeError("INVALID_REQUEST", 401, message);
12611
+ }
12612
+ if (policy === "verified") throw new AgentWebAppRuntimeError("USER_ID_REQUIRED", 401, "A verified identity token is required");
12613
+ return headerResolver.resolve(request, webAppId);
12614
+ }
12615
+ };
12616
+ }
12466
12617
  function registerAgentWebAppRuntimeRoutes(app2, deps) {
12467
- const identities = deps.identityResolver ?? createExternalHeaderIdentityResolver();
12618
+ const identities = deps.identityResolver ?? createWebAppIdentityResolver({ getIdentityConfig: (webAppId) => deps.service.getIdentityConfig(webAppId) });
12468
12619
  app2.register(async (routes) => {
12469
12620
  routes.setErrorHandler((error, _request, reply) => normalizeError2(reply, error));
12470
12621
  routes.get("/api/web-apps/:webAppId/runtime/bootstrap", async (request, reply) => handle2(reply, async () => {
12471
12622
  const { webAppId } = paramsSchema.parse(request.params);
12472
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12473
- return { data: await deps.service.bootstrap(webAppId, identity.userId, withPreview(bootstrapQuerySchema.parse(request.query), identity.preview)) };
12623
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12624
+ return { data: await deps.service.bootstrap(webAppId, identity.userId, withPreview(bootstrapQuerySchema.parse(request.query), identity.preview), { assurance: identity.assurance ?? "unverified" }) };
12474
12625
  }));
12475
12626
  routes.get("/api/web-apps/:webAppId/runtime/threads", async (request, reply) => handle2(reply, async () => {
12476
12627
  const { webAppId } = paramsSchema.parse(request.params);
12477
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12628
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12478
12629
  const records = await deps.service.listThreads(webAppId, identity.userId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12479
12630
  return { data: { records, total: records.length } };
12480
12631
  }));
12481
12632
  routes.post("/api/web-apps/:webAppId/runtime/threads", async (request, reply) => handle2(reply, async () => {
12482
12633
  const { webAppId } = paramsSchema.parse(request.params);
12483
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12634
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12484
12635
  return { statusCode: 201, data: await deps.service.createThread(webAppId, identity.userId, withPreview(threadBodySchema.parse(request.body), identity.preview)) };
12485
12636
  }));
12486
12637
  routes.patch("/api/web-apps/:webAppId/runtime/threads/:threadId", async (request, reply) => handle2(reply, async () => {
12487
12638
  const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12488
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12639
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12489
12640
  return { data: await deps.service.updateThread(webAppId, identity.userId, threadId, withPreview(threadBodySchema.parse(request.body), identity.preview)) };
12490
12641
  }));
12491
12642
  routes.delete("/api/web-apps/:webAppId/runtime/threads/:threadId", async (request, reply) => handle2(reply, async () => {
12492
12643
  const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12493
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12644
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12494
12645
  await deps.service.deleteThread(webAppId, identity.userId, threadId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12495
12646
  return { data: { id: threadId } };
12496
12647
  }));
12497
12648
  routes.get("/api/web-apps/:webAppId/runtime/threads/:threadId/messages", async (request, reply) => handle2(reply, async () => {
12498
12649
  const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12499
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12650
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12500
12651
  const messages = await deps.service.getMessages(webAppId, identity.userId, threadId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12501
12652
  return { data: { messages } };
12502
12653
  }));
12654
+ routes.get("/api/web-apps/:webAppId/runtime/state", async (request, reply) => handle2(reply, async () => {
12655
+ const { webAppId } = paramsSchema.parse(request.params);
12656
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12657
+ const { threadId, projectId, modelKey: modelKey2 } = stateQuerySchema.parse(request.query);
12658
+ const state = await deps.service.getState(webAppId, identity.userId, threadId, withPreview({ projectId, modelKey: modelKey2 }, identity.preview));
12659
+ return { data: state };
12660
+ }));
12661
+ routes.delete("/api/web-apps/:webAppId/runtime/threads/:threadId/pending-messages/:messageId", async (request, reply) => handle2(reply, async () => {
12662
+ const { webAppId, threadId, messageId } = pendingMessageParamsSchema.parse(request.params);
12663
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12664
+ await deps.service.removePendingMessage(webAppId, identity.userId, threadId, messageId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12665
+ return { data: { removed: true } };
12666
+ }));
12503
12667
  routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/messages/stream", async (request, reply) => {
12504
12668
  try {
12505
12669
  const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12506
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12670
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12671
+ const input = streamBodySchema.parse(request.body);
12672
+ const result = await deps.service.streamMessage(webAppId, identity.userId, threadId, withPreview(input, identity.preview));
12673
+ beginSse(reply);
12674
+ await pipeNativeWebAppStream(reply.raw, result.stream);
12675
+ } catch (error) {
12676
+ return normalizeError2(reply, error);
12677
+ }
12678
+ });
12679
+ routes.post("/api/web-apps/:webAppId/runtime/v1/threads/:threadId/messages/stream", async (request, reply) => {
12680
+ try {
12681
+ const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12682
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12507
12683
  const input = streamBodySchema.parse(request.body);
12508
12684
  const result = await deps.service.streamMessage(webAppId, identity.userId, threadId, withPreview(input, identity.preview));
12509
12685
  beginSse(reply);
@@ -12512,15 +12688,27 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
12512
12688
  return normalizeError2(reply, error);
12513
12689
  }
12514
12690
  });
12515
- routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/abort", async (request, reply) => handle2(reply, async () => {
12516
- const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12517
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12518
- await deps.service.abort(webAppId, identity.userId, threadId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12519
- return { data: { aborted: true } };
12520
- }));
12521
- routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/attachments", async (request, reply) => handle2(reply, async () => {
12691
+ routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/resume", async (request, reply) => {
12692
+ try {
12693
+ const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12694
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12695
+ const { messageId, projectId, modelKey: modelKey2 } = resumeSchema.parse(request.body);
12696
+ const result = await deps.service.resumeStream(webAppId, identity.userId, threadId, messageId, withPreview({ projectId, modelKey: modelKey2 }, identity.preview));
12697
+ beginSse(reply);
12698
+ await pipeNativeWebAppStream(reply.raw, result.stream);
12699
+ } catch (error) {
12700
+ return normalizeError2(reply, error);
12701
+ }
12702
+ });
12703
+ routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/abort", async (request, reply) => handle2(reply, async () => {
12522
12704
  const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12523
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12705
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12706
+ await deps.service.abort(webAppId, identity.userId, threadId, withPreview(projectQuerySchema.parse(request.query), identity.preview));
12707
+ return { data: { aborted: true } };
12708
+ }));
12709
+ routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/attachments", async (request, reply) => handle2(reply, async () => {
12710
+ const { webAppId, threadId } = threadParamsSchema.parse(request.params);
12711
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12524
12712
  if (!request.isMultipart()) throw new ZodError2([]);
12525
12713
  const part = await request.file({ limits: { files: 1, fileSize: MAX_ATTACHMENT_BYTES } });
12526
12714
  if (!part || !part.filename || part.filename.length > 255) throw new ZodError2([]);
@@ -12536,7 +12724,7 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
12536
12724
  routes.post("/api/web-apps/:webAppId/runtime/threads/:threadId/interrupts/:interruptId/resume", async (request, reply) => {
12537
12725
  try {
12538
12726
  const { webAppId, threadId, interruptId } = interruptParamsSchema.parse(request.params);
12539
- const identity = resolveRuntimeIdentity(request, webAppId, identities);
12727
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12540
12728
  const { projectId, modelKey: modelKey2, message, response } = resumeBodySchema.parse(request.body);
12541
12729
  const result = await deps.service.resumeInterrupt(webAppId, identity.userId, threadId, interruptId, withPreview({ projectId, modelKey: modelKey2 }, identity.preview), { message, response });
12542
12730
  beginSse(reply);
@@ -12545,13 +12733,264 @@ function registerAgentWebAppRuntimeRoutes(app2, deps) {
12545
12733
  return normalizeError2(reply, error);
12546
12734
  }
12547
12735
  });
12736
+ routes.post("/api/web-apps/:webAppId/dev/token", async (request, reply) => handle2(reply, async () => {
12737
+ if (process.env.WEB_APP_DEV_TOKEN_ENABLED !== "true") {
12738
+ throw new AgentWebAppRuntimeError("FEATURE_DISABLED", 403, "Dev token issuance is disabled (set WEB_APP_DEV_TOKEN_ENABLED=true)");
12739
+ }
12740
+ const { webAppId } = paramsSchema.parse(request.params);
12741
+ const { iss, sub, hours } = devTokenSchema.parse(request.body ?? {});
12742
+ const config = await deps.service.getIdentityConfig(webAppId);
12743
+ const issuer = (config?.issuers ?? []).find((entry) => entry.alg === "HS256" && (iss === void 0 || entry.iss === iss));
12744
+ if (!issuer || typeof issuer.secret !== "string") {
12745
+ throw new AgentWebAppRuntimeError("INVALID_REQUEST", 400, "Web app has no HS256 issuer configured");
12746
+ }
12747
+ const now = Math.floor(Date.now() / 1e3);
12748
+ const expiresIn = (hours ?? 24) * 3600;
12749
+ const subject = sub ?? "dev-user";
12750
+ const b64url = (input) => Buffer.from(input).toString("base64url");
12751
+ const body = `${b64url(JSON.stringify({ alg: "HS256", typ: "JWT" }))}.${b64url(JSON.stringify({ sub: subject, iss: issuer.iss, aud: issuer.aud, iat: now, exp: now + expiresIn }))}`;
12752
+ const token = `${body}.${createHmac3("sha256", issuer.secret).update(body).digest("base64url")}`;
12753
+ return { data: { token, tokenType: "Bearer", expiresIn, subject } };
12754
+ }));
12755
+ if (deps.taskController) {
12756
+ const tasks = deps.taskController;
12757
+ const withSubject = (handler) => async (request, reply) => {
12758
+ const { webAppId } = paramsSchema.parse(request.params);
12759
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12760
+ const proxy = Object.create(request);
12761
+ proxy.headers = { ...request.headers, "x-user-id": identity.userId };
12762
+ return handler(proxy, reply);
12763
+ };
12764
+ routes.get("/api/web-apps/:webAppId/runtime/tasks", withSubject((request, reply) => tasks.list(request, reply)));
12765
+ routes.post("/api/web-apps/:webAppId/runtime/tasks", withSubject((request, reply) => tasks.create(request, reply)));
12766
+ routes.get("/api/web-apps/:webAppId/runtime/tasks/:taskId", withSubject((request, reply) => tasks.get(request, reply)));
12767
+ routes.put("/api/web-apps/:webAppId/runtime/tasks/:taskId", withSubject((request, reply) => tasks.update(request, reply)));
12768
+ routes.patch("/api/web-apps/:webAppId/runtime/tasks/:taskId", withSubject((request, reply) => tasks.update(request, reply)));
12769
+ routes.delete("/api/web-apps/:webAppId/runtime/tasks/:taskId", withSubject((request, reply) => tasks.remove(request, reply)));
12770
+ routes.patch("/api/web-apps/:webAppId/runtime/tasks/:taskId/complete", withSubject((request, reply) => tasks.complete(request, reply)));
12771
+ routes.get("/api/web-apps/:webAppId/runtime/tasks/:taskId/work-items", withSubject((request, reply) => tasks.workItems(request, reply)));
12772
+ }
12773
+ if (deps.workspaceController) {
12774
+ const workspace = deps.workspaceController;
12775
+ const fileScope = async (webAppId, selection) => {
12776
+ const scope = await deps.service.resolveFileScope(webAppId, selection);
12777
+ if (!scope.enabled) throw new AgentWebAppRuntimeError("FEATURE_DISABLED", 403, "Files are disabled for this web app");
12778
+ return scope;
12779
+ };
12780
+ const scopedRequest = (request, scope, params, query) => {
12781
+ const proxy = Object.create(request);
12782
+ proxy.params = params;
12783
+ proxy.query = query;
12784
+ proxy.headers = { ...request.headers, "x-tenant-id": scope.tenantId };
12785
+ return proxy;
12786
+ };
12787
+ const unwrap = (result) => ({ data: result.data });
12788
+ routes.get("/api/web-apps/:webAppId/runtime/files/listpath", async (request) => {
12789
+ const { webAppId } = paramsSchema.parse(request.params);
12790
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12791
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12792
+ const query = { ...request.query, assistantId: scope.assistantId };
12793
+ const result = await workspace.listPath(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query));
12794
+ return unwrap(result);
12795
+ });
12796
+ routes.get("/api/web-apps/:webAppId/runtime/files/readfile", async (request) => {
12797
+ const { webAppId } = paramsSchema.parse(request.params);
12798
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12799
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12800
+ const query = { ...request.query, assistantId: scope.assistantId };
12801
+ const result = await workspace.readFile(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query));
12802
+ return unwrap(result);
12803
+ });
12804
+ routes.post("/api/web-apps/:webAppId/runtime/files/uploadfile", async (request, reply) => {
12805
+ const { webAppId } = paramsSchema.parse(request.params);
12806
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12807
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12808
+ const scoped = scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, { assistantId: scope.assistantId });
12809
+ await workspace.uploadFile(scoped, reply);
12810
+ return reply;
12811
+ });
12812
+ routes.get("/api/web-apps/:webAppId/runtime/files/viewfile", async (request, reply) => {
12813
+ const { webAppId } = paramsSchema.parse(request.params);
12814
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12815
+ const query = { ...request.query, assistantId: scope.assistantId };
12816
+ await workspace.viewFile(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query), reply);
12817
+ return reply;
12818
+ });
12819
+ routes.get("/api/web-apps/:webAppId/runtime/files/downloadfile", async (request, reply) => {
12820
+ const { webAppId } = paramsSchema.parse(request.params);
12821
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12822
+ const query = { ...request.query, assistantId: scope.assistantId };
12823
+ await workspace.downloadFile(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query), reply);
12824
+ return reply;
12825
+ });
12826
+ routes.get("/api/web-apps/:webAppId/runtime/files/downloadfolder", async (request, reply) => {
12827
+ const { webAppId } = paramsSchema.parse(request.params);
12828
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12829
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12830
+ const query = { ...request.query, assistantId: scope.assistantId };
12831
+ await workspace.downloadFolder(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query), reply);
12832
+ return reply;
12833
+ });
12834
+ const genuiSandboxParams = z5.object({ webAppId: idSchema, assistantId: idSchema, threadId: idSchema }).strict();
12835
+ const delegateGenuiFile = (method) => async (request, reply) => {
12836
+ const { webAppId } = genuiSandboxParams.parse(request.params);
12837
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12838
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12839
+ const query = { ...request.query, assistantId: scope.assistantId };
12840
+ await method(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query), reply);
12841
+ return reply;
12842
+ };
12843
+ routes.get("/api/web-apps/:webAppId/runtime/assistants/:assistantId/threads/:threadId/sandbox/downloadfile", delegateGenuiFile(workspace.downloadFile.bind(workspace)));
12844
+ routes.get("/api/web-apps/:webAppId/runtime/assistants/:assistantId/threads/:threadId/sandbox/viewfile", delegateGenuiFile(workspace.viewFile.bind(workspace)));
12845
+ const delegateAnonGenuiFile = (method) => async (request, reply) => {
12846
+ const { webAppId } = genuiSandboxParams.parse(request.params);
12847
+ const scope = await fileScope(webAppId, fileQuerySchema.parse(request.query));
12848
+ const query = { ...request.query, assistantId: scope.assistantId };
12849
+ await method(scopedRequest(request, scope, { workspaceId: scope.workspaceId, projectId: scope.projectId }, query), reply);
12850
+ return reply;
12851
+ };
12852
+ routes.get("/api/web-apps/:webAppId/runtime/api/assistants/:assistantId/threads/:threadId/sandbox/downloadfile", delegateAnonGenuiFile(workspace.downloadFile.bind(workspace)));
12853
+ routes.get("/api/web-apps/:webAppId/runtime/api/assistants/:assistantId/threads/:threadId/sandbox/viewfile", delegateAnonGenuiFile(workspace.viewFile.bind(workspace)));
12854
+ }
12855
+ const mirrorThreadParams = z5.object({ webAppId: idSchema, assistantId: idSchema, threadId: idSchema }).strict();
12856
+ const mirrorBody = z5.object({ metadata: z5.object({ label: z5.string().max(300).optional() }).strict().optional(), projectId: idSchema.optional(), modelKey: idSchema.optional() }).strict();
12857
+ const toConsoleThread = (thread, assistantId) => ({
12858
+ id: thread.id,
12859
+ assistantId,
12860
+ metadata: thread.label ? { label: thread.label } : {},
12861
+ createdAt: thread.createdAt,
12862
+ updatedAt: thread.updatedAt
12863
+ });
12864
+ const mirrorAssistantParams = z5.object({ webAppId: idSchema, assistantId: idSchema }).strict();
12865
+ const mirrorPendingParams = z5.object({ webAppId: idSchema, assistantId: idSchema, threadId: idSchema, messageId: idSchema }).strict();
12866
+ const registerMirror = (prefix) => {
12867
+ routes.get(`${prefix}/assistants/:assistantId/threads`, async (request, reply) => handle2(reply, async () => {
12868
+ const { webAppId, assistantId } = mirrorAssistantParams.parse(request.params);
12869
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12870
+ const threads = await deps.service.listThreads(webAppId, identity.userId, projectQueryLenientSchema.parse(request.query));
12871
+ return { data: { records: threads.map((thread) => toConsoleThread(thread, assistantId)) } };
12872
+ }));
12873
+ routes.post(`${prefix}/assistants/:assistantId/threads`, async (request, reply) => handle2(reply, async () => {
12874
+ const { webAppId, assistantId } = mirrorAssistantParams.parse(request.params);
12875
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12876
+ const body = mirrorBody.parse(request.body ?? {});
12877
+ const created = await deps.service.createThread(webAppId, identity.userId, { label: body.metadata?.label, ...body.projectId ? { projectId: body.projectId } : {} });
12878
+ return { statusCode: 201, data: { id: created.id } };
12879
+ }));
12880
+ routes.get(`${prefix}/assistants/:assistantId/threads/:threadId`, async (request, reply) => handle2(reply, async () => {
12881
+ const { webAppId, assistantId, threadId } = mirrorThreadParams.parse(request.params);
12882
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12883
+ const thread = await deps.service.getThread(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query));
12884
+ return { data: toConsoleThread(thread, assistantId) };
12885
+ }));
12886
+ routes.put(`${prefix}/assistants/:assistantId/threads/:threadId`, async (request, reply) => handle2(reply, async () => {
12887
+ const { webAppId, assistantId, threadId } = mirrorThreadParams.parse(request.params);
12888
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12889
+ const body = mirrorBody.parse(request.body ?? {});
12890
+ const updated = await deps.service.updateThread(webAppId, identity.userId, threadId, { label: body.metadata?.label, ...body.projectId ? { projectId: body.projectId } : {} });
12891
+ return { data: toConsoleThread(updated, assistantId) };
12892
+ }));
12893
+ routes.delete(`${prefix}/assistants/:assistantId/threads/:threadId`, async (request, reply) => handle2(reply, async () => {
12894
+ const { webAppId, threadId } = mirrorThreadParams.parse(request.params);
12895
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12896
+ await deps.service.deleteThread(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query));
12897
+ return { data: { success: true, message: "Thread deleted" } };
12898
+ }));
12899
+ routes.post(`${prefix}/assistants/:assistantId/threads/:threadId/sandbox/uploadfile`, async (request, reply) => handle2(reply, async () => {
12900
+ const { webAppId, threadId } = mirrorThreadParams.parse(request.params);
12901
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12902
+ if (!request.isMultipart()) throw new ZodError2([]);
12903
+ const part = await request.file({ limits: { files: 1, fileSize: MAX_ATTACHMENT_BYTES } });
12904
+ if (!part || !part.filename || part.filename.length > 255) throw new ZodError2([]);
12905
+ const bytes = await part.toBuffer();
12906
+ if (bytes.length === 0 || part.file.truncated) throw new ZodError2([]);
12907
+ const uploaded = await deps.service.uploadAttachment(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query), {
12908
+ name: part.filename,
12909
+ mimeType: part.mimetype || "application/octet-stream",
12910
+ bytes
12911
+ });
12912
+ return { statusCode: 201, data: { id: uploaded.ref, path: uploaded.ref, name: uploaded.name, mimeType: uploaded.mimeType, size: uploaded.size } };
12913
+ }));
12914
+ routes.get(`${prefix}/assistants/:assistantId/:threadId/memory`, async (request) => {
12915
+ const { webAppId, threadId } = mirrorThreadParams.parse(request.params);
12916
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12917
+ const messages = await deps.service.getConsoleMessages(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query));
12918
+ return messages;
12919
+ });
12920
+ routes.get(`${prefix}/assistants/:assistantId/:threadId/state`, async (request) => {
12921
+ const { webAppId, threadId } = mirrorThreadParams.parse(request.params);
12922
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12923
+ return deps.service.getState(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query));
12924
+ });
12925
+ routes.delete(`${prefix}/assistants/:assistantId/threads/:threadId/pending-messages/:messageId`, async (request, reply) => handle2(reply, async () => {
12926
+ const { webAppId, threadId, messageId } = mirrorPendingParams.parse(request.params);
12927
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12928
+ await deps.service.removePendingMessage(webAppId, identity.userId, threadId, messageId, projectQueryLenientSchema.parse(request.query));
12929
+ return { data: { removed: true } };
12930
+ }));
12931
+ routes.post(`${prefix}/assistants/:assistantId/threads/:threadId/abort`, async (request, reply) => handle2(reply, async () => {
12932
+ const { webAppId, threadId } = mirrorThreadParams.parse(request.params);
12933
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12934
+ await deps.service.abort(webAppId, identity.userId, threadId, projectQueryLenientSchema.parse(request.query));
12935
+ return { data: { aborted: true } };
12936
+ }));
12937
+ const runsBodySchema = z5.object({
12938
+ thread_id: idSchema.optional(),
12939
+ assistant_id: idSchema.optional(),
12940
+ messages: z5.array(z5.object({ content: z5.string().min(1).max(32768) }).passthrough()).min(1).max(20),
12941
+ background: z5.boolean().optional(),
12942
+ streaming: z5.boolean().optional(),
12943
+ projectId: idSchema.optional(),
12944
+ modelKey: idSchema.optional()
12945
+ }).passthrough();
12946
+ routes.post(`${prefix}/runs`, async (request, reply) => {
12947
+ try {
12948
+ const { webAppId } = paramsSchema.parse(request.params);
12949
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12950
+ const body = runsBodySchema.parse(request.body ?? {});
12951
+ if (!body.background || body.streaming) {
12952
+ throw new AgentWebAppRuntimeError("INVALID_REQUEST", 400, "Mirror runs supports only background enqueue (stream via resume_stream)");
12953
+ }
12954
+ const threadId = body.thread_id ?? "";
12955
+ if (!threadId) throw new AgentWebAppRuntimeError("INVALID_REQUEST", 400, "thread_id is required");
12956
+ const content = body.messages.map((message) => message.content).join("\n");
12957
+ const { messageId } = await deps.service.enqueueMessage(webAppId, identity.userId, threadId, content, { projectId: body.projectId, modelKey: body.modelKey });
12958
+ return reply.code(202).send({ success: true, messageId, queued: true });
12959
+ } catch (error) {
12960
+ return normalizeError2(reply, error);
12961
+ }
12962
+ });
12963
+ const resumeStreamSchema2 = z5.object({
12964
+ assistant_id: idSchema.optional(),
12965
+ thread_id: idSchema,
12966
+ message_id: idSchema,
12967
+ known_content: z5.string().optional(),
12968
+ poll_interval: z5.number().optional(),
12969
+ projectId: idSchema.optional(),
12970
+ modelKey: idSchema.optional()
12971
+ }).strict();
12972
+ routes.post(`${prefix}/resume_stream`, async (request, reply) => {
12973
+ try {
12974
+ const { webAppId } = paramsSchema.parse(request.params);
12975
+ const identity = await resolveRuntimeIdentity(request, webAppId, identities);
12976
+ const body = resumeStreamSchema2.parse(request.body ?? {});
12977
+ const result = await deps.service.resumeStream(webAppId, identity.userId, body.thread_id, body.message_id, { projectId: body.projectId, modelKey: body.modelKey });
12978
+ beginSse(reply);
12979
+ await pipeNativeWebAppStream(reply.raw, result.stream);
12980
+ } catch (error) {
12981
+ return normalizeError2(reply, error);
12982
+ }
12983
+ });
12984
+ };
12985
+ registerMirror("/api/web-apps/:webAppId/runtime");
12986
+ registerMirror("/api/web-apps/:webAppId/runtime/api");
12548
12987
  });
12549
12988
  }
12550
- function resolveRuntimeIdentity(request, webAppId, identities) {
12551
- if (request.headers["x-axiom-web-app-preview"] !== "true") return identities.resolve(request);
12989
+ async function resolveRuntimeIdentity(request, webAppId, identities) {
12990
+ if (request.headers["x-axiom-web-app-preview"] !== "true") return identities.resolve(request, webAppId);
12552
12991
  const user = request.user;
12553
12992
  if (!user?.id || !user.tenantId) throw new AgentWebAppRuntimeError("USER_ID_REQUIRED", 401, "Authenticated Console preview is required");
12554
- return { userId: `console-preview:${user.id}:${webAppId}`, preview: { tenantId: user.tenantId, userId: user.id } };
12993
+ return { userId: `console-preview:${user.id}:${webAppId}`, assurance: "unverified", preview: { tenantId: user.tenantId, userId: user.id } };
12555
12994
  }
12556
12995
  function withPreview(selection, preview) {
12557
12996
  return { ...selection, ...preview ? { preview } : {} };
@@ -12566,13 +13005,22 @@ async function pipeAgentWebAppStream(raw, stream, options = {}) {
12566
13005
  ]
12567
13006
  });
12568
13007
  }
13008
+ async function pipeNativeWebAppStream(raw, stream) {
13009
+ await pipeAsyncIterableToSse(raw, stream, {
13010
+ onError: () => [{
13011
+ type: "error",
13012
+ data: { id: "", content: "Stream failed" }
13013
+ }]
13014
+ });
13015
+ }
12569
13016
  function beginSse(reply) {
12570
13017
  reply.hijack();
12571
13018
  reply.raw.writeHead(200, {
12572
13019
  "Content-Type": "text/event-stream; charset=utf-8",
12573
13020
  "Cache-Control": "no-cache, no-transform",
12574
13021
  Connection: "keep-alive",
12575
- "X-Accel-Buffering": "no"
13022
+ "X-Accel-Buffering": "no",
13023
+ "Access-Control-Allow-Origin": "*"
12576
13024
  });
12577
13025
  }
12578
13026
  async function handle2(reply, operation) {
@@ -12593,6 +13041,105 @@ function isMultipartRequestError(error) {
12593
13041
  return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" && error.code.startsWith("FST_");
12594
13042
  }
12595
13043
 
13044
+ // src/routes/agent-web-app-embed.ts
13045
+ import { existsSync as existsSync2 } from "fs";
13046
+ import { readFile, readdir as readdir2 } from "fs/promises";
13047
+ import path3 from "path";
13048
+ import { z as z6 } from "zod";
13049
+ var idSchema2 = z6.string().min(1).max(128).regex(/^[A-Za-z0-9._:@-]+$/);
13050
+ var JS_CONTENT_TYPE = "application/javascript; charset=utf-8";
13051
+ var CSS_CONTENT_TYPE = "text/css; charset=utf-8";
13052
+ var EXACT_ASSETS = {
13053
+ "agent-chat-loader.js": { contentType: JS_CONTENT_TYPE },
13054
+ "embed-page.js": { contentType: JS_CONTENT_TYPE },
13055
+ "embed-page.css": { contentType: CSS_CONTENT_TYPE }
13056
+ };
13057
+ var HASHED_CHUNK_PATTERN = /^embed-page-[A-Za-z0-9._-]+\.(js|css)$/;
13058
+ var CHUNK_CSS_PATTERN = /^embed-page-[A-Za-z0-9._-]+\.css$/;
13059
+ function resolveAsset(asset) {
13060
+ if (asset.includes("..")) return null;
13061
+ const exact2 = EXACT_ASSETS[asset];
13062
+ if (exact2 !== void 0) return { contentType: exact2.contentType, immutable: false };
13063
+ const hashed = HASHED_CHUNK_PATTERN.exec(asset);
13064
+ if (hashed) {
13065
+ return { contentType: hashed[1] === "css" ? CSS_CONTENT_TYPE : JS_CONTENT_TYPE, immutable: true };
13066
+ }
13067
+ return null;
13068
+ }
13069
+ async function listChunkCssFiles(assetsDir) {
13070
+ try {
13071
+ return (await readdir2(assetsDir)).filter((name) => CHUNK_CSS_PATTERN.test(name) && !name.includes("..")).sort();
13072
+ } catch {
13073
+ return [];
13074
+ }
13075
+ }
13076
+ var BUNDLED_MARKER = "agent-chat-loader.js";
13077
+ function resolveBundledEmbedDir() {
13078
+ if (typeof __dirname === "string") {
13079
+ const compiled = path3.resolve(__dirname, "embed");
13080
+ if (existsSync2(path3.join(compiled, BUNDLED_MARKER))) return compiled;
13081
+ }
13082
+ let dir = path3.dirname(path3.resolve(process.argv[1] ?? process.cwd()));
13083
+ for (let depth = 0; depth < 8; depth += 1) {
13084
+ const candidate = path3.join(dir, "packages", "gateway", "dist", "embed");
13085
+ if (existsSync2(path3.join(candidate, BUNDLED_MARKER))) return candidate;
13086
+ const parent = path3.dirname(dir);
13087
+ if (parent === dir) break;
13088
+ dir = parent;
13089
+ }
13090
+ return null;
13091
+ }
13092
+ function renderChatShell(chunkCssFiles) {
13093
+ const chunkCssLinks = chunkCssFiles.map(
13094
+ (name) => ` <link rel="stylesheet" href="/embed/${name}" />`
13095
+ );
13096
+ return [
13097
+ "<!doctype html>",
13098
+ '<html lang="en">',
13099
+ " <head>",
13100
+ ' <meta charset="utf-8" />',
13101
+ ' <meta name="viewport" content="width=device-width, initial-scale=1" />',
13102
+ " <title>Agent chat</title>",
13103
+ ' <link rel="stylesheet" href="/embed/embed-page.css" />',
13104
+ ...chunkCssLinks,
13105
+ " </head>",
13106
+ " <body>",
13107
+ ' <div id="axiom-embed-root">',
13108
+ " <noscript>This chat requires JavaScript.</noscript>",
13109
+ ' <p class="axiom-embed-loading">Loading chat\u2026</p>',
13110
+ " </div>",
13111
+ ' <script type="module" src="/embed/embed-page.js"></script>',
13112
+ " </body>",
13113
+ "</html>"
13114
+ ].join("\n");
13115
+ }
13116
+ function registerAgentWebAppEmbedRoutes(app2, deps = {}) {
13117
+ const bundledDir = resolveBundledEmbedDir();
13118
+ const assetsDir = deps.assetsDir ?? process.env.AXIOM_EMBED_ASSETS_DIR ?? bundledDir ?? path3.resolve(process.cwd(), "assets/embed");
13119
+ let chunkCssFiles = null;
13120
+ app2.get("/api/web-apps/:webAppId/chat", async (request, reply) => {
13121
+ const parsed = idSchema2.safeParse(request.params.webAppId);
13122
+ if (!parsed.success) {
13123
+ return reply.code(400).send({ success: false, error: { code: "INVALID_REQUEST", message: "Invalid web app id", retryable: false } });
13124
+ }
13125
+ chunkCssFiles ?? (chunkCssFiles = await listChunkCssFiles(assetsDir));
13126
+ return reply.header("content-type", "text/html; charset=utf-8").header("cache-control", "no-store").send(renderChatShell(chunkCssFiles));
13127
+ });
13128
+ app2.get("/embed/:asset", async (request, reply) => {
13129
+ const asset = request.params.asset ?? "";
13130
+ const resolved = resolveAsset(asset);
13131
+ if (resolved === null) {
13132
+ return reply.code(404).send({ success: false, error: { code: "INVALID_REQUEST", message: "Unknown embed asset", retryable: false } });
13133
+ }
13134
+ try {
13135
+ const body = await readFile(path3.join(assetsDir, asset));
13136
+ return reply.header("content-type", resolved.contentType).header("cache-control", resolved.immutable ? "public, max-age=31536000, immutable" : "public, max-age=300").send(body);
13137
+ } catch {
13138
+ return reply.code(404).send({ success: false, error: { code: "INVALID_REQUEST", message: "Embed asset not built", retryable: false } });
13139
+ }
13140
+ });
13141
+ }
13142
+
12596
13143
  // src/services/agent-web-app/AgentWebAppAttachmentRef.ts
12597
13144
  import { createCipheriv, createDecipheriv, createHash as createHash3, randomBytes as randomBytes2 } from "crypto";
12598
13145
  var TTL_MS = 15 * 6e4;
@@ -12675,10 +13222,10 @@ function isAttachmentPayload(value) {
12675
13222
  }
12676
13223
 
12677
13224
  // src/controllers/capability-bundles.ts
12678
- import { z as z7 } from "zod";
13225
+ import { z as z8 } from "zod";
12679
13226
 
12680
13227
  // src/services/capability/CapabilityBundleService.ts
12681
- import { z as z6 } from "zod";
13228
+ import { z as z7 } from "zod";
12682
13229
  import { CapabilityBundleMergeError, CapabilityBundleValidationError, mergeCapabilityBundles, validateCapabilityBundleInput } from "@axiom-lattice/core";
12683
13230
  var CapabilityBundleServiceError = class extends Error {
12684
13231
  constructor(code, message, statusCode) {
@@ -12688,7 +13235,7 @@ var CapabilityBundleServiceError = class extends Error {
12688
13235
  this.name = "CapabilityBundleServiceError";
12689
13236
  }
12690
13237
  };
12691
- var uuid = z6.string().uuid();
13238
+ var uuid = z7.string().uuid();
12692
13239
  function ownRecord(value) {
12693
13240
  if (value === void 0 || value === null) return {};
12694
13241
  if (typeof value !== "object" || Array.isArray(value)) throw new CapabilityBundleServiceError("INVALID_BUNDLE_CONFIG", "Project config must be an object", 409);
@@ -12890,12 +13437,12 @@ var CapabilityBundleService = class {
12890
13437
 
12891
13438
  // src/controllers/capability-bundles.ts
12892
13439
  var logger3 = new Logger({ serviceName: "lattice/gateway/capability-bundles" });
12893
- var capability = z7.unknown();
12894
- var createSchema = z7.object({ name: z7.string(), description: z7.string().optional(), capabilities: z7.array(capability) }).strict();
12895
- var updateSchema = createSchema.partial().extend({ expectedUpdatedAt: z7.string().optional() });
12896
- var bundleIdSchema = z7.string().uuid();
12897
- var bundleParamsSchema = z7.object({ bundleId: bundleIdSchema });
12898
- var projectSchema = z7.object({ bundleIds: z7.array(bundleIdSchema), expectedRevisions: z7.record(z7.string()).optional() }).strict();
13440
+ var capability = z8.unknown();
13441
+ var createSchema = z8.object({ name: z8.string(), description: z8.string().optional(), capabilities: z8.array(capability) }).strict();
13442
+ var updateSchema = createSchema.partial().extend({ expectedUpdatedAt: z8.string().optional() });
13443
+ var bundleIdSchema = z8.string().uuid();
13444
+ var bundleParamsSchema = z8.object({ bundleId: bundleIdSchema });
13445
+ var projectSchema = z8.object({ bundleIds: z8.array(bundleIdSchema), expectedRevisions: z8.record(z8.string()).optional() }).strict();
12899
13446
  function tenant(request, authRequired2) {
12900
13447
  const authenticated = request.user?.tenantId;
12901
13448
  const header2 = request.headers["x-tenant-id"];
@@ -13163,6 +13710,14 @@ var ProjectMembershipService = class {
13163
13710
  const room = await this.deps.roomStore.getMainRoom(membership.tenantId, membership.projectId);
13164
13711
  if (!room) throw new Error("Project main room not found");
13165
13712
  this.deps.realtime.membershipChanged({ tenantId: membership.tenantId, roomId: room.id, membership, change, sourceKey });
13713
+ this.deps.realtime.membershipAffected({
13714
+ tenantId: membership.tenantId,
13715
+ userId: membership.userId,
13716
+ change,
13717
+ projectId: membership.projectId,
13718
+ roomId: room.id,
13719
+ sourceKey: `membership-affected:${sourceKey}`
13720
+ });
13166
13721
  }).catch((error) => {
13167
13722
  this.reportRealtimeFailure(membership.id);
13168
13723
  });
@@ -13767,45 +14322,46 @@ function matchesNormalizedPayload(message, input) {
13767
14322
 
13768
14323
  // src/routes/project-rooms.ts
13769
14324
  import { ZodError as ZodError3 } from "zod";
14325
+ import { toProjectRoomPublicMessage } from "@axiom-lattice/protocols";
13770
14326
 
13771
14327
  // src/schemas/project-room.ts
13772
- import { z as z8 } from "zod";
13773
- var id2 = z8.string().trim().min(1).max(128);
13774
- var isoDate = z8.string().datetime({ offset: true }).transform((value) => new Date(value));
13775
- var expectedUpdatedAt = z8.object({ expectedUpdatedAt: isoDate }).strict();
13776
- var projectRoomParamsSchema = z8.object({ projectId: id2 }).strict();
13777
- var membershipParamsSchema = z8.object({ projectId: id2, membershipId: id2 }).strict();
13778
- var roomMessagesQuerySchema = z8.object({
13779
- beforeCreatedAt: z8.string().datetime({ offset: true }).transform((value) => new Date(value)).optional(),
14328
+ import { z as z9 } from "zod";
14329
+ var id2 = z9.string().trim().min(1).max(128);
14330
+ var isoDate = z9.string().datetime({ offset: true }).transform((value) => new Date(value));
14331
+ var expectedUpdatedAt = z9.object({ expectedUpdatedAt: isoDate }).strict();
14332
+ var projectRoomParamsSchema = z9.object({ projectId: id2 }).strict();
14333
+ var membershipParamsSchema = z9.object({ projectId: id2, membershipId: id2 }).strict();
14334
+ var roomMessagesQuerySchema = z9.object({
14335
+ beforeCreatedAt: z9.string().datetime({ offset: true }).transform((value) => new Date(value)).optional(),
13780
14336
  beforeId: id2.optional(),
13781
- limit: z8.coerce.number().int().min(1).max(100).optional()
14337
+ limit: z9.coerce.number().int().min(1).max(100).optional()
13782
14338
  }).strict().refine((value) => value.beforeCreatedAt === void 0 === (value.beforeId === void 0), { message: "Both cursor fields are required" });
13783
- var createRoomMessageSchema = z8.object({
13784
- text: z8.string(),
13785
- mentions: z8.array(z8.union([
13786
- z8.object({ type: z8.literal("team") }).strict(),
13787
- z8.object({ type: z8.literal("bot"), membershipId: id2 }).strict()
14339
+ var createRoomMessageSchema = z9.object({
14340
+ text: z9.string(),
14341
+ mentions: z9.array(z9.union([
14342
+ z9.object({ type: z9.literal("team") }).strict(),
14343
+ z9.object({ type: z9.literal("bot"), membershipId: id2 }).strict()
13788
14344
  ])).optional(),
13789
14345
  replyToMessageId: id2.optional()
13790
14346
  }).strict();
13791
- var addProjectMemberSchema = z8.object({ userId: id2, role: z8.enum(["owner", "admin", "member", "viewer"]) }).strict();
13792
- var updateProjectMemberSchema = z8.object({ role: z8.enum(["owner", "admin", "member", "viewer"]), expectedUpdatedAt: isoDate }).strict();
14347
+ var addProjectMemberSchema = z9.object({ userId: id2, role: z9.enum(["owner", "admin", "member", "viewer"]) }).strict();
14348
+ var updateProjectMemberSchema = z9.object({ role: z9.enum(["owner", "admin", "member", "viewer"]), expectedUpdatedAt: isoDate }).strict();
13793
14349
  var mutationExpectedUpdatedAtSchema = expectedUpdatedAt;
13794
- var roomMessageRetryParamsSchema = z8.object({ projectId: id2, messageId: id2 }).strict();
13795
- var emptyObjectSchema = z8.object({}).strict();
13796
- var idempotencyKeySchema = z8.string().refine((value) => value.trim().length >= 1 && value.trim().length <= 200 && /^[\x20-\x7e]+$/.test(value.trim()), "Invalid idempotency key").transform((value) => value.trim());
13797
- var addProjectBotSchema = z8.object({
14350
+ var roomMessageRetryParamsSchema = z9.object({ projectId: id2, messageId: id2 }).strict();
14351
+ var emptyObjectSchema = z9.object({}).strict();
14352
+ var idempotencyKeySchema = z9.string().refine((value) => value.trim().length >= 1 && value.trim().length <= 200 && /^[\x20-\x7e]+$/.test(value.trim()), "Invalid idempotency key").transform((value) => value.trim());
14353
+ var addProjectBotSchema = z9.object({
13798
14354
  assistantId: id2,
13799
- role: z8.enum(["coordinator", "specialist"]),
13800
- title: z8.string(),
13801
- responsibility: z8.string().optional(),
13802
- mentionName: z8.string()
14355
+ role: z9.enum(["coordinator", "specialist"]),
14356
+ title: z9.string(),
14357
+ responsibility: z9.string().optional(),
14358
+ mentionName: z9.string()
13803
14359
  }).strict();
13804
- var updateProjectBotSchema = z8.object({
13805
- role: z8.enum(["coordinator", "specialist"]).optional(),
13806
- title: z8.string().optional(),
13807
- responsibility: z8.string().optional(),
13808
- mentionName: z8.string().optional(),
14360
+ var updateProjectBotSchema = z9.object({
14361
+ role: z9.enum(["coordinator", "specialist"]).optional(),
14362
+ title: z9.string().optional(),
14363
+ responsibility: z9.string().optional(),
14364
+ mentionName: z9.string().optional(),
13809
14365
  expectedUpdatedAt: isoDate
13810
14366
  }).strict().refine((value) => value.role !== void 0 || value.title !== void 0 || value.responsibility !== void 0 || value.mentionName !== void 0, { message: "At least one mutable field is required" });
13811
14367
 
@@ -13823,7 +14379,8 @@ function registerProjectRoomRoutes(app2, deps) {
13823
14379
  const params = projectRoomParamsSchema.parse(request.params);
13824
14380
  const query = roomMessagesQuerySchema.parse(request.query);
13825
14381
  const before = query.beforeCreatedAt === void 0 && query.beforeId === void 0 ? void 0 : { createdAt: query.beforeCreatedAt, id: query.beforeId };
13826
- return { data: await deps.messageService.list(actor(request, params.projectId), { ...before ? { before } : {}, ...query.limit === void 0 ? {} : { limit: query.limit } }) };
14382
+ const messages = await deps.messageService.list(actor(request, params.projectId), { ...before ? { before } : {}, ...query.limit === void 0 ? {} : { limit: query.limit } });
14383
+ return { data: messages.map(toProjectRoomMessage) };
13827
14384
  }));
13828
14385
  app2.post("/api/projects/:projectId/room/messages", async (request, reply) => run(reply, async () => {
13829
14386
  const params = projectRoomParamsSchema.parse(request.params);
@@ -13834,7 +14391,7 @@ function registerProjectRoomRoutes(app2, deps) {
13834
14391
  const idempotencyKey = rawIdempotencyKey === void 0 ? void 0 : idempotencyKeySchema.parse(rawIdempotencyKey);
13835
14392
  const result = await deps.messageService.createAndDispatch(requestActor, { ...input, ...idempotencyKey === void 0 ? {} : { requestIdempotencyKey: idempotencyKey } });
13836
14393
  const allSucceeded = result.dispatch.length > 0 && result.dispatch.every((entry) => entry.success);
13837
- return { statusCode: allSucceeded ? result.replayed ? 200 : 201 : 202, data: result };
14394
+ return { statusCode: allSucceeded ? result.replayed ? 200 : 201 : 202, data: { message: toProjectRoomMessage(result.message), dispatch: result.dispatch, replayed: result.replayed } };
13838
14395
  }));
13839
14396
  app2.post("/api/projects/:projectId/room/messages/:messageId/retry", async (request, reply) => run(reply, async () => {
13840
14397
  const params = roomMessageRetryParamsSchema.parse(request.params);
@@ -13843,6 +14400,12 @@ function registerProjectRoomRoutes(app2, deps) {
13843
14400
  const dispatch = await deps.messageService.retry(actor(request, params.projectId), params.messageId);
13844
14401
  return { statusCode: dispatch.length > 0 && dispatch.every((entry) => entry.success) ? 200 : 202, data: dispatch };
13845
14402
  }));
14403
+ app2.post("/api/projects/:projectId/room/read-state", async (request, reply) => run(reply, async () => {
14404
+ const params = projectRoomParamsSchema.parse(request.params);
14405
+ emptyObjectSchema.parse(request.body ?? {});
14406
+ await deps.readStateService.mark(actor(request, params.projectId));
14407
+ return { data: { marked: true } };
14408
+ }));
13846
14409
  app2.get("/api/projects/:projectId/members", async (request, reply) => run(reply, async () => ({ data: await deps.membershipService.list(actor(request, projectRoomParamsSchema.parse(request.params).projectId)) })));
13847
14410
  app2.post("/api/projects/:projectId/members", async (request, reply) => run(reply, async () => {
13848
14411
  const p = projectRoomParamsSchema.parse(request.params);
@@ -13865,6 +14428,11 @@ function actor(request, projectId) {
13865
14428
  projectRoomParamsSchema.parse({ projectId });
13866
14429
  return { tenantId: user.tenantId, userId: user.id, projectId };
13867
14430
  }
14431
+ function toProjectRoomMessage(message) {
14432
+ const publicMessage = toProjectRoomPublicMessage(message);
14433
+ if (publicMessage === void 0) throw new Error("Room message could not be mapped to its public DTO");
14434
+ return publicMessage;
14435
+ }
13868
14436
  async function run(reply, operation) {
13869
14437
  try {
13870
14438
  const result = await operation();
@@ -13930,6 +14498,7 @@ import {
13930
14498
  generateDirectHumanProjectId,
13931
14499
  generateDirectBotProjectId
13932
14500
  } from "@axiom-lattice/core";
14501
+ import { toProjectRoomPublicMessage as toProjectRoomPublicMessage2 } from "@axiom-lattice/protocols";
13933
14502
  var CoSpaceAuthError = class extends Error {
13934
14503
  constructor() {
13935
14504
  super(...arguments);
@@ -13944,6 +14513,18 @@ function getActor2(request) {
13944
14513
  }
13945
14514
  return { tenantId: user.tenantId, userId: user.id };
13946
14515
  }
14516
+ async function computeUnread(deps, tenantId, userId, roomId, lastMessage) {
14517
+ if (!lastMessage) return 0;
14518
+ const readState = await deps.readStateStore.get(tenantId, roomId, userId);
14519
+ const horizon = readState?.lastReadAt;
14520
+ if (horizon && lastMessage.createdAt.getTime() <= horizon.getTime()) return 0;
14521
+ return deps.messageStore.countAfter({
14522
+ tenantId,
14523
+ roomId,
14524
+ after: horizon ?? /* @__PURE__ */ new Date(0),
14525
+ excludeAuthorUserId: userId
14526
+ });
14527
+ }
13947
14528
  function registerCoSpaceRoutes(app2, deps) {
13948
14529
  const idFactory = deps.idFactory ?? (() => randomUUID16());
13949
14530
  app2.get(
@@ -13994,6 +14575,7 @@ function registerCoSpaceRoutes(app2, deps) {
13994
14575
  limit: 1
13995
14576
  });
13996
14577
  const lastMessage = messages[0];
14578
+ const publicLastMessage = lastMessage === void 0 ? void 0 : toProjectRoomPublicMessage2(lastMessage);
13997
14579
  const memberships = await deps.membershipStore.list(
13998
14580
  actor2.tenantId,
13999
14581
  project.id
@@ -14009,19 +14591,26 @@ function registerCoSpaceRoutes(app2, deps) {
14009
14591
  rooms.push({
14010
14592
  project,
14011
14593
  room,
14012
- lastMessage,
14594
+ lastMessage: publicLastMessage,
14013
14595
  participantCount: memberships.filter(
14014
14596
  (m) => m.status === "active"
14015
14597
  ).length,
14016
- participantNames
14598
+ participantNames,
14599
+ unreadCount: await computeUnread(
14600
+ deps,
14601
+ actor2.tenantId,
14602
+ actor2.userId,
14603
+ room.id,
14604
+ lastMessage
14605
+ )
14017
14606
  });
14018
14607
  } catch (e) {
14019
14608
  console.error("[CoSpace] Failed to process room for project:", project.id, e);
14020
14609
  }
14021
14610
  }
14022
14611
  rooms.sort((a, b) => {
14023
- const aTime = a.lastMessage?.createdAt?.getTime() ?? 0;
14024
- const bTime = b.lastMessage?.createdAt?.getTime() ?? 0;
14612
+ const aTime = a.lastMessage ? Date.parse(a.lastMessage.createdAt) : 0;
14613
+ const bTime = b.lastMessage ? Date.parse(b.lastMessage.createdAt) : 0;
14025
14614
  return bTime - aTime;
14026
14615
  });
14027
14616
  const publicRoom = await deps.publicRoom.ensure(actor2.tenantId, params.workspaceId);
@@ -14031,6 +14620,7 @@ function registerCoSpaceRoutes(app2, deps) {
14031
14620
  roomId: publicRoom.room.id,
14032
14621
  limit: 1
14033
14622
  });
14623
+ const publicLastMessage = publicMessages[0];
14034
14624
  const publicMemberships = await deps.membershipStore.list(
14035
14625
  actor2.tenantId,
14036
14626
  publicRoom.project.id
@@ -14046,10 +14636,17 @@ function registerCoSpaceRoutes(app2, deps) {
14046
14636
  rooms.unshift({
14047
14637
  project: publicRoom.project,
14048
14638
  room: publicRoom.room,
14049
- lastMessage: publicMessages[0],
14639
+ lastMessage: publicLastMessage === void 0 ? void 0 : toProjectRoomPublicMessage2(publicLastMessage),
14050
14640
  participantCount: publicMemberships.filter((m) => m.status === "active").length,
14051
14641
  participantNames: publicParticipantNames,
14052
- isPublic: true
14642
+ isPublic: true,
14643
+ unreadCount: await computeUnread(
14644
+ deps,
14645
+ actor2.tenantId,
14646
+ actor2.userId,
14647
+ publicRoom.room.id,
14648
+ publicLastMessage
14649
+ )
14053
14650
  });
14054
14651
  }
14055
14652
  return { data: { rooms } };
@@ -16604,7 +17201,7 @@ function snapshotProjectableWorkItem(value) {
16604
17201
  if (!row || !createdAt || typeof row.id !== "string" || !row.id || typeof row.taskId !== "string" || !row.taskId || typeof row.tenantId !== "string" || !row.tenantId || typeof row.workspaceId !== "string" || !row.workspaceId || typeof row.projectId !== "string" || !row.projectId || typeof row.actor !== "string" || !row.actor || typeof row.eventKey !== "string" || !row.eventKey || !PROJECT_TASK_LIFECYCLE_ACTIONS.includes(row.action) || row.threadId !== void 0 && typeof row.threadId !== "string" || row.summary !== void 0 && typeof row.summary !== "string" || row.attempt !== void 0 && (typeof row.attempt !== "number" || !Number.isFinite(row.attempt))) return void 0;
16605
17202
  try {
16606
17203
  const detail = row.detail === void 0 ? void 0 : snapshotJsonValue(row.detail);
16607
- if (detail !== void 0 && !isRecord4(detail)) return void 0;
17204
+ if (detail !== void 0 && !isRecord3(detail)) return void 0;
16608
17205
  return {
16609
17206
  id: row.id,
16610
17207
  taskId: row.taskId,
@@ -16751,7 +17348,7 @@ function snapshotLifecycleCursor(value) {
16751
17348
  const createdAt = cloneExactDate(row?.createdAt);
16752
17349
  return row && typeof row.id === "string" && row.id.length > 0 && createdAt ? { id: row.id, createdAt } : void 0;
16753
17350
  }
16754
- function isRecord4(value) {
17351
+ function isRecord3(value) {
16755
17352
  return typeof value === "object" && value !== null && !Array.isArray(value);
16756
17353
  }
16757
17354
 
@@ -17108,6 +17705,7 @@ function snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
17108
17705
  // src/services/collaboration/ProjectRoomRealtimePublisher.ts
17109
17706
  import { createHash as createHash7 } from "crypto";
17110
17707
  import {
17708
+ projectRoomUserEventScope,
17111
17709
  snapshotExactRecord as snapshotExactRecord10,
17112
17710
  snapshotProjectRoomBotMembershipRealtime,
17113
17711
  snapshotProjectRoomMembershipRealtime,
@@ -17182,6 +17780,46 @@ var BrokerProjectRoomRealtimePublisher = class {
17182
17780
  };
17183
17781
  });
17184
17782
  }
17783
+ /** Publishes a membership notice onto the affected user's channel scope. */
17784
+ membershipAffected(input) {
17785
+ this.publish("membership.affected", () => {
17786
+ const value = snapshotExactRecord10(input, ["tenantId", "userId", "change", "projectId", "roomId", "sourceKey"]);
17787
+ if (!value || !safeId2(value.tenantId) || !safeId2(value.userId) || !safeId2(value.projectId) || !safeId2(value.roomId) || !safeSourceKey(value.sourceKey) || !["added", "removed", "role_changed"].includes(value.change)) {
17788
+ throw new TypeError("Invalid membership input");
17789
+ }
17790
+ const scope = projectRoomUserEventScope(value.tenantId, value.userId);
17791
+ return {
17792
+ sourceKey: value.sourceKey,
17793
+ id: value.sourceKey,
17794
+ scope,
17795
+ draft: {
17796
+ type: "membership.affected",
17797
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
17798
+ data: { change: value.change, projectId: value.projectId, roomId: value.roomId }
17799
+ }
17800
+ };
17801
+ });
17802
+ }
17803
+ /** Publishes a read-marker update onto the acting user's channel scope. */
17804
+ readChanged(input) {
17805
+ this.publish("read.changed", () => {
17806
+ const value = snapshotExactRecord10(input, ["tenantId", "userId", "projectId", "roomId", "lastReadAt", "sourceKey"]);
17807
+ if (!value || !safeId2(value.tenantId) || !safeId2(value.userId) || !safeId2(value.projectId) || !safeId2(value.roomId) || !safeSourceKey(value.sourceKey) || typeof value.lastReadAt !== "string" || !Number.isFinite(Date.parse(value.lastReadAt))) {
17808
+ throw new TypeError("Invalid read input");
17809
+ }
17810
+ const scope = projectRoomUserEventScope(value.tenantId, value.userId);
17811
+ return {
17812
+ sourceKey: value.sourceKey,
17813
+ id: value.sourceKey,
17814
+ scope,
17815
+ draft: {
17816
+ type: "read.changed",
17817
+ occurredAt: (/* @__PURE__ */ new Date()).toISOString(),
17818
+ data: { projectId: value.projectId, roomId: value.roomId, lastReadAt: new Date(Date.parse(value.lastReadAt)).toISOString() }
17819
+ }
17820
+ };
17821
+ });
17822
+ }
17185
17823
  publish(type, build) {
17186
17824
  let event;
17187
17825
  try {
@@ -17240,88 +17878,296 @@ function safeErrorCode(error) {
17240
17878
  return error instanceof Error && error.name === "Error" ? "Error" : "UnknownError";
17241
17879
  }
17242
17880
 
17243
- // src/services/collaboration/ProjectRoomRealtimeService.ts
17244
- import { ProjectRoomCursorError as ProjectRoomCursorError2 } from "@axiom-lattice/protocols";
17245
-
17246
- // src/services/collaboration/ProjectRoomSseWriter.ts
17247
- var DEFAULT_MAX_FRAMES = 256;
17248
- var DEFAULT_MAX_BYTES = 1024 * 1024;
17249
- var DEFAULT_DRAIN_TIMEOUT_MS = 1e4;
17250
- function serializeBusiness(event) {
17251
- return `id: ${event.id}
17252
- event: ${event.type}
17253
- data: ${JSON.stringify(event)}
17254
-
17255
- `;
17256
- }
17257
- function serializeControl(event) {
17258
- return `event: ${event.type}
17259
- data: ${JSON.stringify(event.data)}
17260
-
17261
- `;
17262
- }
17263
- var ProjectRoomSseWriter = class {
17264
- /** Creates a writer over a raw HTTP response/socket. */
17265
- constructor(raw, options = {}) {
17266
- this.raw = raw;
17267
- this.frames = [];
17268
- this.queuedBytes = 0;
17269
- this.blockedBytes = 0;
17270
- this.writing = false;
17881
+ // src/services/collaboration/ProjectRoomTaskEventSubscriber.ts
17882
+ import { isProjectLifecycleTask as isProjectLifecycleTask6 } from "@axiom-lattice/core";
17883
+ import { snapshotExactRecord as snapshotExactRecord11 } from "@axiom-lattice/protocols";
17884
+ var ProjectRoomTaskEventSubscriber = class {
17885
+ /** Creates a bounded Project task lifecycle observer. */
17886
+ constructor(deps) {
17887
+ this.deps = deps;
17888
+ this.queues = /* @__PURE__ */ new Map();
17889
+ this.pendingCount = 0;
17890
+ this.accepting = true;
17271
17891
  this.closed = false;
17272
- this.terminal = false;
17273
- this.slowConsumerAttempted = false;
17274
- this.closeListener = () => this.close();
17275
- this.errorListener = () => this.close();
17276
- this.drainListener = () => {
17277
- if (this.closed || !this.writing) return;
17278
- this.clearDrainTimer();
17279
- this.blockedBytes = 0;
17280
- this.writing = false;
17281
- this.flush();
17282
- };
17283
- this.maxFrames = positive(options.maxFrames ?? DEFAULT_MAX_FRAMES, "maxFrames");
17284
- this.maxBytes = positive(options.maxBytes ?? DEFAULT_MAX_BYTES, "maxBytes");
17285
- this.drainTimeoutMs = positive(options.drainTimeoutMs ?? DEFAULT_DRAIN_TIMEOUT_MS, "drainTimeoutMs");
17286
- this.onClose = options.onClose;
17287
- raw.on("close", this.closeListener).on("error", this.errorListener).on("drain", this.drainListener);
17892
+ this.accepted = /* @__PURE__ */ new Set();
17893
+ this.maxPending = deps.maxPending ?? 1024;
17894
+ if (!Number.isSafeInteger(this.maxPending) || this.maxPending < 1) throw new RangeError("maxPending must be a positive safe integer");
17288
17895
  }
17289
- /** Enqueues one public business event. */
17290
- enqueueBusiness(event) {
17291
- this.enqueue(serializeBusiness(event));
17896
+ /** Admits one notification without awaiting any store operation. */
17897
+ handle(value) {
17898
+ const event = this.parse(value);
17899
+ if (!event) {
17900
+ this.warn("Project task realtime notification rejected", { code: "INVALID_TASK_REALTIME_EVENT" });
17901
+ return Promise.resolve();
17902
+ }
17903
+ if (!this.accepting || this.closed) return Promise.resolve();
17904
+ const scopeKey3 = JSON.stringify([event.tenantId, event.workspaceId, event.projectId, event.taskId]);
17905
+ const eventKey = event.eventKey;
17906
+ let queue = this.queues.get(scopeKey3);
17907
+ if (!queue) {
17908
+ if (this.pendingCount >= this.maxPending) return this.overflow(event.taskId);
17909
+ queue = { events: [], keys: /* @__PURE__ */ new Set(), tail: Promise.resolve() };
17910
+ this.queues.set(scopeKey3, queue);
17911
+ }
17912
+ if (queue.keys.has(eventKey)) return queue.tail;
17913
+ if (this.pendingCount >= this.maxPending) return this.overflow(event.taskId);
17914
+ queue.keys.add(eventKey);
17915
+ queue.events.push(event);
17916
+ this.pendingCount += 1;
17917
+ const previousTail = queue.tail;
17918
+ queue.tail = previousTail.then(() => this.processQueue(scopeKey3, queue)).catch((error) => {
17919
+ this.warn("project-room:task-realtime-failed", { code: "TASK_REALTIME_NOTIFICATION_FAILED", error: error instanceof Error ? error.name : "UnknownError" });
17920
+ });
17921
+ const accepted = queue.tail;
17922
+ this.accepted.add(accepted);
17923
+ void accepted.finally(() => this.accepted.delete(accepted));
17924
+ return accepted;
17292
17925
  }
17293
- /** Enqueues one connection control event. */
17294
- enqueueControl(event) {
17295
- this.enqueue(serializeControl(event));
17926
+ /** Closes admission without interrupting accepted work. */
17927
+ closeAdmission() {
17928
+ this.accepting = false;
17296
17929
  }
17297
- /** Writes a heartbeat comment when the socket is not currently blocked. */
17298
- heartbeat() {
17299
- if (!this.closed && !this.writing) this.writeFrame(": heartbeat\n\n");
17930
+ /** Drains accepted work, closing permanently if the bound expires. */
17931
+ async drain(timeoutMs = 5e3) {
17932
+ const work = Promise.allSettled([...this.accepted]).then(() => void 0);
17933
+ let timer;
17934
+ const timeout = new Promise((resolve3) => {
17935
+ timer = setTimeout(() => resolve3("timeout"), timeoutMs);
17936
+ timer.unref?.();
17937
+ });
17938
+ const outcome = await Promise.race([work.then(() => "drained"), timeout]);
17939
+ if (timer) clearTimeout(timer);
17940
+ this.closed = true;
17941
+ if (outcome === "timeout") this.queues.clear();
17300
17942
  }
17301
- /** Closes the writer and removes every socket listener exactly once. */
17302
- close() {
17303
- if (this.closed) return;
17943
+ /** Closes admission and drains accepted work. */
17944
+ async dispose() {
17945
+ this.closeAdmission();
17946
+ await this.drain();
17304
17947
  this.closed = true;
17305
- this.clearDrainTimer();
17306
- if (this.terminalTimer !== void 0) clearTimeout(this.terminalTimer);
17307
- this.terminalResolve?.();
17308
- this.terminalResolve = void 0;
17309
- this.terminalFinish = void 0;
17310
- this.raw.off("close", this.closeListener).off("error", this.errorListener).off("drain", this.drainListener);
17311
- this.frames.length = 0;
17312
- this.queuedBytes = 0;
17313
- try {
17314
- this.raw.end();
17315
- } catch {
17316
- this.raw.destroy();
17948
+ }
17949
+ async processQueue(scopeKey3, queue) {
17950
+ while (queue.events.length > 0) {
17951
+ const event = queue.events.shift();
17952
+ try {
17953
+ if (!this.closed) await this.publish(event);
17954
+ } finally {
17955
+ queue.keys.delete(event.eventKey);
17956
+ this.pendingCount -= 1;
17957
+ }
17317
17958
  }
17318
- this.onClose?.();
17959
+ if (queue.events.length === 0 && this.queues.get(scopeKey3) === queue) this.queues.delete(scopeKey3);
17319
17960
  }
17320
- /** Stops ordinary delivery and attempts one terminal control before ending. */
17321
- closeWithControl(control, deadlineMs = 250) {
17322
- if (this.closed) return Promise.resolve();
17323
- if (this.terminal) return new Promise((resolve3) => {
17324
- this.terminalResolve = resolve3;
17961
+ async publish(event) {
17962
+ try {
17963
+ const taskValue = await this.deps.tasks.getById(event.tenantId, event.taskId);
17964
+ const task = taskValue === null ? void 0 : snapshotTaskItem(taskValue);
17965
+ if (this.closed) return;
17966
+ if (!task || !isProjectLifecycleTask6(task) || task.tenantId !== event.tenantId || task.workspaceId !== event.workspaceId || task.projectId !== event.projectId || task.status !== event.status || task.updatedAt.toISOString() !== event.updatedAt || event.threadId !== void 0 && task.context?.thread_id !== event.threadId) {
17967
+ this.warn("project-room:task-event-stale", { taskId: safeId3(event.taskId), eventKey: safeId3(event.eventKey) });
17968
+ return;
17969
+ }
17970
+ const roomValue = await this.deps.rooms.getMainRoom(event.tenantId, event.projectId);
17971
+ const room = snapshotProjectRoom(roomValue);
17972
+ if (this.closed) return;
17973
+ if (!room || room.tenantId !== event.tenantId || room.workspaceId !== event.workspaceId || room.projectId !== event.projectId) return;
17974
+ const membershipValue = await this.deps.memberships.findByAssistant(event.tenantId, event.projectId, task.ownerId);
17975
+ const membership = snapshotProjectBotMembership(membershipValue);
17976
+ if (this.closed) return;
17977
+ if (!membership || membership.tenantId !== event.tenantId || membership.workspaceId !== event.workspaceId || membership.projectId !== event.projectId || membership.roomId !== room.id || membership.assistantId !== task.ownerId) return;
17978
+ this.deps.realtime.taskChanged({
17979
+ tenantId: event.tenantId,
17980
+ roomId: room.id,
17981
+ projectId: event.projectId,
17982
+ taskId: task.id,
17983
+ status: task.status,
17984
+ ownerMembershipId: membership.id,
17985
+ updatedAt: task.updatedAt.toISOString(),
17986
+ sourceKey: `task:${task.id}:${event.eventKey}`
17987
+ });
17988
+ } catch (error) {
17989
+ this.warn("project-room:task-realtime-failed", { code: "TASK_REALTIME_NOTIFICATION_FAILED", taskId: safeId3(event.taskId), error: error instanceof Error ? error.name : "UnknownError" });
17990
+ }
17991
+ }
17992
+ parse(value) {
17993
+ const row = snapshotExactRecord11(value, ["tenantId", "workspaceId", "projectId", "taskId", "status", "action", "eventKey", "updatedAt"], ["threadId"]);
17994
+ const actions = ["in_progress", "interrupted", "failed", "completed", "cancelled", "reassigned"];
17995
+ const statuses = ["pending", "in_progress", "review", "failed", "interrupted", "completed", "cancelled"];
17996
+ if (!row || !actions.includes(String(row.action)) || !statuses.includes(String(row.status)) || !["tenantId", "workspaceId", "projectId", "taskId", "eventKey", "updatedAt"].every((key) => typeof row[key] === "string" && row[key].length > 0) || !Number.isFinite(Date.parse(row.updatedAt)) || row.threadId !== void 0 && typeof row.threadId !== "string") return void 0;
17997
+ return row;
17998
+ }
17999
+ warn(message, context) {
18000
+ try {
18001
+ this.deps.log.warn(message, context);
18002
+ } catch {
18003
+ }
18004
+ }
18005
+ overflow(taskId) {
18006
+ this.warn("project-room:task-realtime-overflow", { code: "TASK_REALTIME_QUEUE_FULL", taskId });
18007
+ return Promise.resolve();
18008
+ }
18009
+ };
18010
+ function safeId3(value) {
18011
+ return typeof value === "string" && value.length > 0 ? value : void 0;
18012
+ }
18013
+
18014
+ // src/services/collaboration/ProjectRoomRealtimeRuntime.ts
18015
+ var ProjectRoomRealtimeRuntime = class {
18016
+ constructor(deps) {
18017
+ this.deps = deps;
18018
+ this.accepted = /* @__PURE__ */ new Set();
18019
+ this.broker = deps.broker;
18020
+ this.publisher = deps.publisher;
18021
+ this.shutdownTimeoutMs = deps.shutdownTimeoutMs ?? 5e3;
18022
+ this.unsubscribe = deps.subscribe(((event) => {
18023
+ let work;
18024
+ try {
18025
+ work = Promise.resolve(deps.subscriber.handle(event));
18026
+ } catch (error) {
18027
+ work = Promise.reject(error);
18028
+ }
18029
+ const accepted = work.catch((error) => {
18030
+ deps.log.warn("project-room:task-subscriber-failed", { error: error instanceof Error ? error.name : "UnknownError" });
18031
+ });
18032
+ this.accepted.add(accepted);
18033
+ void accepted.finally(() => this.accepted.delete(accepted));
18034
+ }));
18035
+ }
18036
+ /** Stops admission, drains accepted work, and closes transport resources exactly once. */
18037
+ close() {
18038
+ this.closing ?? (this.closing = this.dispose());
18039
+ return this.closing;
18040
+ }
18041
+ async dispose() {
18042
+ this.unsubscribe();
18043
+ this.deps.subscriber.closeAdmission();
18044
+ const accepted = [...this.accepted];
18045
+ const drained = await boundedAllSettled(accepted, this.shutdownTimeoutMs);
18046
+ if (!drained) this.deps.log.warn("project-room:runtime-drain-timeout", {
18047
+ timeoutMs: this.shutdownTimeoutMs,
18048
+ pending: accepted.length
18049
+ });
18050
+ await this.deps.subscriber.drain(drained ? this.shutdownTimeoutMs : 0);
18051
+ this.broker.close();
18052
+ }
18053
+ };
18054
+ function createProjectRoomRealtimeRuntime(deps) {
18055
+ const broker = new ProjectRoomEventBroker({ log: deps.log });
18056
+ const publisher = new BrokerProjectRoomRealtimePublisher({ broker, log: deps.log });
18057
+ const subscriber = new ProjectRoomTaskEventSubscriber({
18058
+ tasks: deps.tasks,
18059
+ rooms: deps.rooms,
18060
+ memberships: deps.memberships,
18061
+ realtime: publisher,
18062
+ log: deps.log
18063
+ });
18064
+ return new ProjectRoomRealtimeRuntime({
18065
+ broker,
18066
+ publisher,
18067
+ subscriber,
18068
+ subscribe: (listener) => taskLifecycleNotifier.subscribe(listener),
18069
+ log: deps.log,
18070
+ shutdownTimeoutMs: deps.shutdownTimeoutMs
18071
+ });
18072
+ }
18073
+ async function boundedAllSettled(promises, timeoutMs) {
18074
+ if (promises.length === 0) return true;
18075
+ let timer;
18076
+ const timeout = new Promise((resolve3) => {
18077
+ timer = setTimeout(() => resolve3(false), timeoutMs);
18078
+ timer.unref?.();
18079
+ });
18080
+ const result = await Promise.race([Promise.allSettled(promises).then(() => true), timeout]);
18081
+ if (timer) clearTimeout(timer);
18082
+ return result;
18083
+ }
18084
+
18085
+ // src/services/collaboration/WorkspaceRoomEventsService.ts
18086
+ import { PROJECT_ROOM_USER_CHANNEL_PROJECT, projectRoomUserEventScope as projectRoomUserEventScope2 } from "@axiom-lattice/protocols";
18087
+
18088
+ // src/services/collaboration/ProjectRoomSseWriter.ts
18089
+ var DEFAULT_MAX_FRAMES = 256;
18090
+ var DEFAULT_MAX_BYTES = 1024 * 1024;
18091
+ var DEFAULT_DRAIN_TIMEOUT_MS = 1e4;
18092
+ function serializeBusiness(event) {
18093
+ return `id: ${event.id}
18094
+ event: ${event.type}
18095
+ data: ${JSON.stringify(event)}
18096
+
18097
+ `;
18098
+ }
18099
+ function serializeControl(event) {
18100
+ return `event: ${event.type}
18101
+ data: ${JSON.stringify(event.data)}
18102
+
18103
+ `;
18104
+ }
18105
+ var ProjectRoomSseWriter = class {
18106
+ /** Creates a writer over a raw HTTP response/socket. */
18107
+ constructor(raw, options = {}) {
18108
+ this.raw = raw;
18109
+ this.frames = [];
18110
+ this.queuedBytes = 0;
18111
+ this.blockedBytes = 0;
18112
+ this.writing = false;
18113
+ this.closed = false;
18114
+ this.terminal = false;
18115
+ this.slowConsumerAttempted = false;
18116
+ this.closeListener = () => this.close();
18117
+ this.errorListener = () => this.close();
18118
+ this.drainListener = () => {
18119
+ if (this.closed || !this.writing) return;
18120
+ this.clearDrainTimer();
18121
+ this.blockedBytes = 0;
18122
+ this.writing = false;
18123
+ this.flush();
18124
+ };
18125
+ this.maxFrames = positive(options.maxFrames ?? DEFAULT_MAX_FRAMES, "maxFrames");
18126
+ this.maxBytes = positive(options.maxBytes ?? DEFAULT_MAX_BYTES, "maxBytes");
18127
+ this.drainTimeoutMs = positive(options.drainTimeoutMs ?? DEFAULT_DRAIN_TIMEOUT_MS, "drainTimeoutMs");
18128
+ this.onClose = options.onClose;
18129
+ raw.on("close", this.closeListener).on("error", this.errorListener).on("drain", this.drainListener);
18130
+ }
18131
+ /** Enqueues one public business event. */
18132
+ enqueueBusiness(event) {
18133
+ this.enqueue(serializeBusiness(event));
18134
+ }
18135
+ /** Enqueues one connection control event. */
18136
+ enqueueControl(event) {
18137
+ this.enqueue(serializeControl(event));
18138
+ }
18139
+ /** Enqueues a pre-serialized SSE frame (used by scoped multi-room streams). */
18140
+ enqueueRaw(frame) {
18141
+ this.enqueue(frame);
18142
+ }
18143
+ /** Writes a heartbeat comment when the socket is not currently blocked. */
18144
+ heartbeat() {
18145
+ if (!this.closed && !this.writing) this.writeFrame(": heartbeat\n\n");
18146
+ }
18147
+ /** Closes the writer and removes every socket listener exactly once. */
18148
+ close() {
18149
+ if (this.closed) return;
18150
+ this.closed = true;
18151
+ this.clearDrainTimer();
18152
+ if (this.terminalTimer !== void 0) clearTimeout(this.terminalTimer);
18153
+ this.terminalResolve?.();
18154
+ this.terminalResolve = void 0;
18155
+ this.terminalFinish = void 0;
18156
+ this.raw.off("close", this.closeListener).off("error", this.errorListener).off("drain", this.drainListener);
18157
+ this.frames.length = 0;
18158
+ this.queuedBytes = 0;
18159
+ try {
18160
+ this.raw.end();
18161
+ } catch {
18162
+ this.raw.destroy();
18163
+ }
18164
+ this.onClose?.();
18165
+ }
18166
+ /** Stops ordinary delivery and attempts one terminal control before ending. */
18167
+ closeWithControl(control, deadlineMs = 250) {
18168
+ if (this.closed) return Promise.resolve();
18169
+ if (this.terminal) return new Promise((resolve3) => {
18170
+ this.terminalResolve = resolve3;
17325
18171
  });
17326
18172
  this.terminal = true;
17327
18173
  this.frames.length = 0;
@@ -17388,449 +18234,265 @@ var ProjectRoomSseWriter = class {
17388
18234
  this.close();
17389
18235
  }
17390
18236
  }
17391
- armTerminalDeadline(deadlineMs, finish) {
17392
- this.terminalTimer = setTimeout(finish, deadlineMs);
17393
- this.terminalTimer.unref?.();
17394
- }
17395
- writeFrame(frame) {
17396
- if (this.closed) return;
17397
- try {
17398
- if (!this.raw.write(frame)) {
17399
- this.writing = true;
17400
- this.blockedBytes = Buffer.byteLength(frame, "utf8");
17401
- this.drainTimer = setTimeout(() => {
17402
- this.drainTimer = void 0;
17403
- this.failSlowConsumer();
17404
- }, this.drainTimeoutMs);
17405
- this.drainTimer.unref?.();
17406
- } else {
17407
- this.writing = false;
17408
- this.blockedBytes = 0;
17409
- this.flush();
17410
- }
17411
- } catch {
17412
- this.close();
17413
- }
17414
- }
17415
- clearDrainTimer() {
17416
- if (this.drainTimer !== void 0) clearTimeout(this.drainTimer);
17417
- this.drainTimer = void 0;
17418
- }
17419
- failSlowConsumer() {
17420
- if (this.closed) return;
17421
- this.frames.length = 0;
17422
- this.queuedBytes = 0;
17423
- if (!this.slowConsumerAttempted) {
17424
- this.slowConsumerAttempted = true;
17425
- try {
17426
- this.raw.write(serializeControl({ type: "resync", data: { reason: "SLOW_CONSUMER" } }));
17427
- } catch {
17428
- }
17429
- }
17430
- this.close();
17431
- }
17432
- };
17433
- function positive(value, name) {
17434
- if (!Number.isSafeInteger(value) || value <= 0) throw new RangeError(`${name} must be positive`);
17435
- return value;
17436
- }
17437
-
17438
- // src/services/collaboration/ProjectRoomRealtimeService.ts
17439
- var MAX_REPLAY_EVENTS = 1e4;
17440
- var MAX_NODE_TIMER_DELAY = 2147e6;
17441
- var ProjectRoomRealtimeService = class {
17442
- /** Creates a service using one process-local broker and read-only authorizer. */
17443
- constructor(deps) {
17444
- this.deps = deps;
17445
- this.connections = /* @__PURE__ */ new Set();
17446
- this.closed = false;
17447
- this.activeConnections = /* @__PURE__ */ new Map();
17448
- this.now = deps.now ?? Date.now;
17449
- this.authRecheckMs = deps.authRecheckMs ?? 15e3;
17450
- this.heartbeatMs = deps.heartbeatMs ?? 15e3;
17451
- }
17452
- /** Returns whether the actor's tenant/user/project stream quota has capacity. */
17453
- canConnect(actor2) {
17454
- if (this.closed) return false;
17455
- return (this.activeConnections.get(connectionKey(actor2)) ?? 0) < (this.deps.maxConnectionsPerUserProject ?? 5);
17456
- }
17457
- /** Starts a connection; authorization is assumed to have been performed by the route. */
17458
- connect(input) {
17459
- if (!this.canConnect(input.actor)) {
17460
- input.raw.end();
17461
- return;
17462
- }
17463
- const quotaKey = connectionKey(input.actor);
17464
- this.activeConnections.set(quotaKey, (this.activeConnections.get(quotaKey) ?? 0) + 1);
17465
- const writer = new ProjectRoomSseWriter(input.raw, { onClose: () => connection.close() });
17466
- let phase = "initializing";
17467
- let subscription;
17468
- let accessTimer;
17469
- let heartbeatTimer;
17470
- let expiryTimer;
17471
- const lifetimeAbort = new AbortController();
17472
- let accessAbort;
17473
- let closed = false;
17474
- const buffered = [];
17475
- const clearTimer = (timer) => {
17476
- if (timer !== void 0) clearTimeout(timer);
17477
- };
17478
- const cleanup = () => {
17479
- if (closed) return;
17480
- closed = true;
17481
- phase = "closed";
17482
- clearTimer(accessTimer);
17483
- clearTimer(heartbeatTimer);
17484
- clearTimer(expiryTimer);
17485
- lifetimeAbort.abort();
17486
- accessAbort?.abort();
17487
- subscription?.unsubscribe();
17488
- writer.close();
17489
- this.connections.delete(connection);
17490
- const remainingConnections = (this.activeConnections.get(quotaKey) ?? 1) - 1;
17491
- if (remainingConnections === 0) this.activeConnections.delete(quotaKey);
17492
- else this.activeConnections.set(quotaKey, remainingConnections);
17493
- };
17494
- const revoke = (reason) => {
17495
- if (closed) return;
17496
- void writer.closeWithControl({ type: "access.revoked", data: { reason } }).then(cleanup, cleanup);
17497
- };
17498
- const scheduleAccessCheck = () => {
17499
- if (closed) return;
17500
- accessTimer = setTimeout(() => {
17501
- accessTimer = void 0;
17502
- if (closed) return;
17503
- accessAbort = new AbortController();
17504
- const combined = combineSignals2(lifetimeAbort.signal, accessAbort.signal);
17505
- Promise.resolve().then(() => this.deps.requireReadAccess(input.actor, combined.signal)).then(() => {
17506
- combined.cleanup();
17507
- accessAbort = void 0;
17508
- scheduleAccessCheck();
17509
- }, (_error) => {
17510
- combined.cleanup();
17511
- accessAbort = void 0;
17512
- if (!closed) revoke("PROJECT_ACCESS_REVOKED");
17513
- });
17514
- }, this.authRecheckMs);
17515
- accessTimer.unref?.();
17516
- };
17517
- const connection = { close: cleanup };
17518
- this.connections.add(connection);
17519
- const scheduleHeartbeat = () => {
17520
- if (closed) return;
17521
- heartbeatTimer = setTimeout(() => {
17522
- heartbeatTimer = void 0;
17523
- if (closed) return;
17524
- writer.heartbeat();
17525
- scheduleHeartbeat();
17526
- }, this.heartbeatMs);
17527
- heartbeatTimer.unref?.();
17528
- };
17529
- scheduleHeartbeat();
17530
- const remaining = input.actor.tokenExpiresAt - this.now();
17531
- if (remaining <= 0) {
17532
- revoke("TOKEN_EXPIRED");
17533
- return;
17534
- }
17535
- const maxTimerDelay = this.deps.maxTimerDelay ?? MAX_NODE_TIMER_DELAY;
17536
- const scheduleExpiry = () => {
17537
- if (closed) return;
17538
- const delay2 = input.actor.tokenExpiresAt - this.now();
17539
- if (delay2 <= 0) {
17540
- revoke("TOKEN_EXPIRED");
17541
- return;
17542
- }
17543
- expiryTimer = setTimeout(() => {
17544
- expiryTimer = void 0;
17545
- scheduleExpiry();
17546
- }, Math.min(delay2, maxTimerDelay));
17547
- expiryTimer.unref?.();
17548
- };
17549
- scheduleExpiry();
17550
- try {
17551
- subscription = this.deps.broker.subscribe(
17552
- { tenantId: input.actor.tenantId, roomId: input.roomId, projectId: input.actor.projectId },
17553
- input.lastEventId,
17554
- (event) => {
17555
- if (phase === "initializing") buffered.push(event);
17556
- else if (phase === "direct") writer.enqueueBusiness(event);
17557
- }
17558
- );
17559
- if (subscription.replay.length > MAX_REPLAY_EVENTS) {
17560
- void writer.closeWithControl({ type: "resync", data: { reason: "CURSOR_EXPIRED" } }).then(cleanup, cleanup);
17561
- return;
17562
- }
17563
- let lastSequence = sequence(subscription.headEventId);
17564
- for (const event of subscription.replay) {
17565
- writer.enqueueBusiness(event);
17566
- lastSequence = sequence(event.id);
17567
- }
17568
- writer.enqueueControl({ type: "ready", data: { epoch: this.deps.broker.epoch, headEventId: subscription.headEventId } });
17569
- while (buffered.length > 0) {
17570
- for (const event of buffered.splice(0).sort((left, right) => sequence(left.id) - sequence(right.id))) {
17571
- if (sequence(event.id) > lastSequence) {
17572
- writer.enqueueBusiness(event);
17573
- lastSequence = sequence(event.id);
17574
- }
17575
- }
17576
- }
17577
- phase = "direct";
17578
- scheduleAccessCheck();
17579
- } catch (error) {
17580
- if (error instanceof ProjectRoomCursorError2) void writer.closeWithControl({ type: "resync", data: { reason: error.code } }).then(cleanup, cleanup);
17581
- else cleanup();
17582
- }
17583
- }
17584
- /** Closes every connection and prevents new connections. */
17585
- close() {
17586
- if (this.closed) return;
17587
- this.closed = true;
17588
- for (const connection of [...this.connections]) connection.close();
17589
- }
17590
- };
17591
- function sequence(id3) {
17592
- return id3 === null ? 0 : Number(id3.slice(id3.lastIndexOf(":") + 1));
17593
- }
17594
- function connectionKey(actor2) {
17595
- return JSON.stringify([actor2.tenantId, actor2.userId, actor2.projectId]);
17596
- }
17597
- function combineSignals2(first, second) {
17598
- const controller = new AbortController();
17599
- const abort = () => controller.abort();
17600
- if (first.aborted || second.aborted) abort();
17601
- else {
17602
- first.addEventListener("abort", abort, { once: true });
17603
- second.addEventListener("abort", abort, { once: true });
17604
- }
17605
- return { signal: controller.signal, cleanup: () => {
17606
- first.removeEventListener("abort", abort);
17607
- second.removeEventListener("abort", abort);
17608
- } };
17609
- }
17610
-
17611
- // src/services/collaboration/ProjectRoomTaskEventSubscriber.ts
17612
- import { isProjectLifecycleTask as isProjectLifecycleTask6 } from "@axiom-lattice/core";
17613
- import { snapshotExactRecord as snapshotExactRecord11 } from "@axiom-lattice/protocols";
17614
- var ProjectRoomTaskEventSubscriber = class {
17615
- /** Creates a bounded Project task lifecycle observer. */
17616
- constructor(deps) {
17617
- this.deps = deps;
17618
- this.queues = /* @__PURE__ */ new Map();
17619
- this.pendingCount = 0;
17620
- this.accepting = true;
17621
- this.closed = false;
17622
- this.accepted = /* @__PURE__ */ new Set();
17623
- this.maxPending = deps.maxPending ?? 1024;
17624
- if (!Number.isSafeInteger(this.maxPending) || this.maxPending < 1) throw new RangeError("maxPending must be a positive safe integer");
17625
- }
17626
- /** Admits one notification without awaiting any store operation. */
17627
- handle(value) {
17628
- const event = this.parse(value);
17629
- if (!event) {
17630
- this.warn("Project task realtime notification rejected", { code: "INVALID_TASK_REALTIME_EVENT" });
17631
- return Promise.resolve();
17632
- }
17633
- if (!this.accepting || this.closed) return Promise.resolve();
17634
- const scopeKey3 = JSON.stringify([event.tenantId, event.workspaceId, event.projectId, event.taskId]);
17635
- const eventKey = event.eventKey;
17636
- let queue = this.queues.get(scopeKey3);
17637
- if (!queue) {
17638
- if (this.pendingCount >= this.maxPending) return this.overflow(event.taskId);
17639
- queue = { events: [], keys: /* @__PURE__ */ new Set(), tail: Promise.resolve() };
17640
- this.queues.set(scopeKey3, queue);
17641
- }
17642
- if (queue.keys.has(eventKey)) return queue.tail;
17643
- if (this.pendingCount >= this.maxPending) return this.overflow(event.taskId);
17644
- queue.keys.add(eventKey);
17645
- queue.events.push(event);
17646
- this.pendingCount += 1;
17647
- const previousTail = queue.tail;
17648
- queue.tail = previousTail.then(() => this.processQueue(scopeKey3, queue)).catch((error) => {
17649
- this.warn("project-room:task-realtime-failed", { code: "TASK_REALTIME_NOTIFICATION_FAILED", error: error instanceof Error ? error.name : "UnknownError" });
17650
- });
17651
- const accepted = queue.tail;
17652
- this.accepted.add(accepted);
17653
- void accepted.finally(() => this.accepted.delete(accepted));
17654
- return accepted;
17655
- }
17656
- /** Closes admission without interrupting accepted work. */
17657
- closeAdmission() {
17658
- this.accepting = false;
17659
- }
17660
- /** Drains accepted work, closing permanently if the bound expires. */
17661
- async drain(timeoutMs = 5e3) {
17662
- const work = Promise.allSettled([...this.accepted]).then(() => void 0);
17663
- let timer;
17664
- const timeout = new Promise((resolve3) => {
17665
- timer = setTimeout(() => resolve3("timeout"), timeoutMs);
17666
- timer.unref?.();
17667
- });
17668
- const outcome = await Promise.race([work.then(() => "drained"), timeout]);
17669
- if (timer) clearTimeout(timer);
17670
- this.closed = true;
17671
- if (outcome === "timeout") this.queues.clear();
17672
- }
17673
- /** Closes admission and drains accepted work. */
17674
- async dispose() {
17675
- this.closeAdmission();
17676
- await this.drain();
17677
- this.closed = true;
17678
- }
17679
- async processQueue(scopeKey3, queue) {
17680
- while (queue.events.length > 0) {
17681
- const event = queue.events.shift();
17682
- try {
17683
- if (!this.closed) await this.publish(event);
17684
- } finally {
17685
- queue.keys.delete(event.eventKey);
17686
- this.pendingCount -= 1;
17687
- }
17688
- }
17689
- if (queue.events.length === 0 && this.queues.get(scopeKey3) === queue) this.queues.delete(scopeKey3);
17690
- }
17691
- async publish(event) {
17692
- try {
17693
- const taskValue = await this.deps.tasks.getById(event.tenantId, event.taskId);
17694
- const task = taskValue === null ? void 0 : snapshotTaskItem(taskValue);
17695
- if (this.closed) return;
17696
- if (!task || !isProjectLifecycleTask6(task) || task.tenantId !== event.tenantId || task.workspaceId !== event.workspaceId || task.projectId !== event.projectId || task.status !== event.status || task.updatedAt.toISOString() !== event.updatedAt || event.threadId !== void 0 && task.context?.thread_id !== event.threadId) {
17697
- this.warn("project-room:task-event-stale", { taskId: safeId3(event.taskId), eventKey: safeId3(event.eventKey) });
17698
- return;
17699
- }
17700
- const roomValue = await this.deps.rooms.getMainRoom(event.tenantId, event.projectId);
17701
- const room = snapshotProjectRoom(roomValue);
17702
- if (this.closed) return;
17703
- if (!room || room.tenantId !== event.tenantId || room.workspaceId !== event.workspaceId || room.projectId !== event.projectId) return;
17704
- const membershipValue = await this.deps.memberships.findByAssistant(event.tenantId, event.projectId, task.ownerId);
17705
- const membership = snapshotProjectBotMembership(membershipValue);
17706
- if (this.closed) return;
17707
- if (!membership || membership.tenantId !== event.tenantId || membership.workspaceId !== event.workspaceId || membership.projectId !== event.projectId || membership.roomId !== room.id || membership.assistantId !== task.ownerId) return;
17708
- this.deps.realtime.taskChanged({
17709
- tenantId: event.tenantId,
17710
- roomId: room.id,
17711
- projectId: event.projectId,
17712
- taskId: task.id,
17713
- status: task.status,
17714
- ownerMembershipId: membership.id,
17715
- updatedAt: task.updatedAt.toISOString(),
17716
- sourceKey: `task:${task.id}:${event.eventKey}`
17717
- });
17718
- } catch (error) {
17719
- this.warn("project-room:task-realtime-failed", { code: "TASK_REALTIME_NOTIFICATION_FAILED", taskId: safeId3(event.taskId), error: error instanceof Error ? error.name : "UnknownError" });
17720
- }
17721
- }
17722
- parse(value) {
17723
- const row = snapshotExactRecord11(value, ["tenantId", "workspaceId", "projectId", "taskId", "status", "action", "eventKey", "updatedAt"], ["threadId"]);
17724
- const actions = ["in_progress", "interrupted", "failed", "completed", "cancelled", "reassigned"];
17725
- const statuses = ["pending", "in_progress", "review", "failed", "interrupted", "completed", "cancelled"];
17726
- if (!row || !actions.includes(String(row.action)) || !statuses.includes(String(row.status)) || !["tenantId", "workspaceId", "projectId", "taskId", "eventKey", "updatedAt"].every((key) => typeof row[key] === "string" && row[key].length > 0) || !Number.isFinite(Date.parse(row.updatedAt)) || row.threadId !== void 0 && typeof row.threadId !== "string") return void 0;
17727
- return row;
18237
+ armTerminalDeadline(deadlineMs, finish) {
18238
+ this.terminalTimer = setTimeout(finish, deadlineMs);
18239
+ this.terminalTimer.unref?.();
17728
18240
  }
17729
- warn(message, context) {
18241
+ writeFrame(frame) {
18242
+ if (this.closed) return;
17730
18243
  try {
17731
- this.deps.log.warn(message, context);
18244
+ if (!this.raw.write(frame)) {
18245
+ this.writing = true;
18246
+ this.blockedBytes = Buffer.byteLength(frame, "utf8");
18247
+ this.drainTimer = setTimeout(() => {
18248
+ this.drainTimer = void 0;
18249
+ this.failSlowConsumer();
18250
+ }, this.drainTimeoutMs);
18251
+ this.drainTimer.unref?.();
18252
+ } else {
18253
+ this.writing = false;
18254
+ this.blockedBytes = 0;
18255
+ this.flush();
18256
+ }
17732
18257
  } catch {
18258
+ this.close();
17733
18259
  }
17734
18260
  }
17735
- overflow(taskId) {
17736
- this.warn("project-room:task-realtime-overflow", { code: "TASK_REALTIME_QUEUE_FULL", taskId });
17737
- return Promise.resolve();
18261
+ clearDrainTimer() {
18262
+ if (this.drainTimer !== void 0) clearTimeout(this.drainTimer);
18263
+ this.drainTimer = void 0;
18264
+ }
18265
+ failSlowConsumer() {
18266
+ if (this.closed) return;
18267
+ this.frames.length = 0;
18268
+ this.queuedBytes = 0;
18269
+ if (!this.slowConsumerAttempted) {
18270
+ this.slowConsumerAttempted = true;
18271
+ try {
18272
+ this.raw.write(serializeControl({ type: "resync", data: { reason: "SLOW_CONSUMER" } }));
18273
+ } catch {
18274
+ }
18275
+ }
18276
+ this.close();
17738
18277
  }
17739
18278
  };
17740
- function safeId3(value) {
17741
- return typeof value === "string" && value.length > 0 ? value : void 0;
18279
+ function positive(value, name) {
18280
+ if (!Number.isSafeInteger(value) || value <= 0) throw new RangeError(`${name} must be positive`);
18281
+ return value;
17742
18282
  }
17743
18283
 
17744
- // src/services/collaboration/ProjectRoomRealtimeRuntime.ts
17745
- var ProjectRoomRealtimeRuntime = class {
18284
+ // src/services/collaboration/WorkspaceRoomEventsService.ts
18285
+ var MAX_NODE_TIMER_DELAY = 2147e6;
18286
+ var WorkspaceRoomEventsService = class {
18287
+ /** Creates a service over the shared process-local broker. */
17746
18288
  constructor(deps) {
17747
18289
  this.deps = deps;
17748
- this.accepted = /* @__PURE__ */ new Set();
17749
- this.broker = deps.broker;
17750
- this.publisher = deps.publisher;
17751
- this.service = deps.service;
17752
- this.shutdownTimeoutMs = deps.shutdownTimeoutMs ?? 5e3;
17753
- this.unsubscribe = deps.subscribe(((event) => {
17754
- let work;
17755
- try {
17756
- work = Promise.resolve(deps.subscriber.handle(event));
17757
- } catch (error) {
17758
- work = Promise.reject(error);
17759
- }
17760
- const accepted = work.catch((error) => {
17761
- deps.log.warn("project-room:task-subscriber-failed", { error: error instanceof Error ? error.name : "UnknownError" });
17762
- });
17763
- this.accepted.add(accepted);
17764
- void accepted.finally(() => this.accepted.delete(accepted));
17765
- }));
18290
+ this.connections = /* @__PURE__ */ new Map();
18291
+ this.closed = false;
18292
+ this.now = deps.now ?? Date.now;
18293
+ this.heartbeatMs = deps.heartbeatMs ?? 15e3;
18294
+ this.authRecheckMs = deps.authRecheckMs ?? 15e3;
18295
+ this.maxConnectionsPerUser = deps.maxConnectionsPerUser ?? 2;
18296
+ this.maxTimerDelay = deps.maxTimerDelay ?? MAX_NODE_TIMER_DELAY;
17766
18297
  }
17767
- /** Stops admission, drains accepted work, and closes transport resources exactly once. */
18298
+ /** Starts a live-only connection; the route performs authentication beforehand. */
18299
+ connect(input) {
18300
+ if (this.closed) {
18301
+ input.raw.end();
18302
+ return;
18303
+ }
18304
+ const userKey = JSON.stringify([input.actor.tenantId, input.actor.userId]);
18305
+ const active = this.connections.get(userKey) ?? /* @__PURE__ */ new Set();
18306
+ if (active.size >= this.maxConnectionsPerUser) {
18307
+ const oldest = [...active].sort((left, right) => left.startedAt - right.startedAt)[0];
18308
+ oldest?.supersede();
18309
+ }
18310
+ const connection = this.buildConnection(input.actor, input.workspaceId, input.raw);
18311
+ active.add(connection);
18312
+ this.connections.set(userKey, active);
18313
+ }
18314
+ /** Closes every connection and stops admitting new ones. */
17768
18315
  close() {
17769
- this.closing ?? (this.closing = this.dispose());
17770
- return this.closing;
18316
+ if (this.closed) return;
18317
+ this.closed = true;
18318
+ for (const active of [...this.connections.values()]) for (const connection of [...active]) connection.close();
18319
+ this.connections.clear();
17771
18320
  }
17772
- async dispose() {
17773
- this.unsubscribe();
17774
- this.deps.subscriber.closeAdmission();
17775
- const accepted = [...this.accepted];
17776
- const drained = await boundedAllSettled(accepted, this.shutdownTimeoutMs);
17777
- if (!drained) this.deps.log.warn("project-room:runtime-drain-timeout", {
17778
- timeoutMs: this.shutdownTimeoutMs,
17779
- pending: accepted.length
18321
+ buildConnection(actor2, workspaceId, raw) {
18322
+ let phase = "initializing";
18323
+ const subscriptions = /* @__PURE__ */ new Map();
18324
+ let heartbeatTimer;
18325
+ let accessTimer;
18326
+ let expiryTimer;
18327
+ let closed = false;
18328
+ const recordRef = {};
18329
+ let rebuildTail = Promise.resolve(true);
18330
+ const lifetimeAbort = new AbortController();
18331
+ const clear = (timer) => {
18332
+ if (timer !== void 0) clearTimeout(timer);
18333
+ };
18334
+ const userScope = projectRoomUserEventScope2(actor2.tenantId, actor2.userId);
18335
+ const userScopeKey = JSON.stringify([userScope.tenantId, userScope.roomId, userScope.projectId]);
18336
+ const roomScopeKey = (scope) => JSON.stringify([scope.tenantId, scope.roomId, scope.projectId]);
18337
+ const serializeScoped = (scope, event) => scope === null ? `id: ${event.id}
18338
+ event: ${event.type}
18339
+ data: ${JSON.stringify(event)}
18340
+
18341
+ ` : `id: ${event.id}
18342
+ event: ${event.type}
18343
+ data: ${JSON.stringify({ ...event, scope })}
18344
+
18345
+ `;
18346
+ const writer = new ProjectRoomSseWriter(raw, { onClose: () => cleanup() });
18347
+ const cleanup = () => {
18348
+ if (closed) return;
18349
+ closed = true;
18350
+ phase = "closed";
18351
+ clear(heartbeatTimer);
18352
+ clear(accessTimer);
18353
+ clear(expiryTimer);
18354
+ lifetimeAbort.abort();
18355
+ for (const entry of subscriptions.values()) entry.unsubscribe();
18356
+ subscriptions.clear();
18357
+ writer.close();
18358
+ const userKey = JSON.stringify([actor2.tenantId, actor2.userId]);
18359
+ const active = this.connections.get(userKey);
18360
+ if (active && recordRef.current !== void 0) {
18361
+ active.delete(recordRef.current);
18362
+ if (active.size === 0) this.connections.delete(userKey);
18363
+ }
18364
+ };
18365
+ const revoke = (reason) => {
18366
+ if (closed) return;
18367
+ void writer.closeWithControl({ type: "access.revoked", data: { reason } }).then(cleanup, cleanup);
18368
+ };
18369
+ const record = {
18370
+ startedAt: this.now(),
18371
+ supersede: () => revoke("CONNECTION_SUPERSEDED"),
18372
+ close: cleanup
18373
+ };
18374
+ recordRef.current = record;
18375
+ const rebuildSubscriptions = async () => {
18376
+ try {
18377
+ const rooms = await this.deps.listMemberRooms({ tenantId: actor2.tenantId, userId: actor2.userId, workspaceId });
18378
+ if (closed) return true;
18379
+ const wanted = /* @__PURE__ */ new Map();
18380
+ for (const room of rooms) {
18381
+ const scope = { tenantId: actor2.tenantId, roomId: room.roomId, projectId: room.projectId };
18382
+ wanted.set(roomScopeKey(scope), scope);
18383
+ }
18384
+ for (const [key, entry] of [...subscriptions]) {
18385
+ if (key === userScopeKey || wanted.has(key)) continue;
18386
+ entry.unsubscribe();
18387
+ subscriptions.delete(key);
18388
+ }
18389
+ for (const [key, scope] of wanted) {
18390
+ if (subscriptions.has(key)) continue;
18391
+ const subscription = this.deps.broker.subscribe(scope, void 0, roomListener(scope));
18392
+ subscriptions.set(key, { scope, unsubscribe: subscription.unsubscribe });
18393
+ }
18394
+ if (!subscriptions.has(userScopeKey)) {
18395
+ const subscription = this.deps.broker.subscribe(userScope, void 0, userListener);
18396
+ subscriptions.set(userScopeKey, { scope: userScope, unsubscribe: subscription.unsubscribe });
18397
+ }
18398
+ return true;
18399
+ } catch (error) {
18400
+ this.deps.log.warn("workspace-room-events:resubscribe-failed", {
18401
+ error: error instanceof Error ? error.message : String(error)
18402
+ });
18403
+ return false;
18404
+ }
18405
+ };
18406
+ const enqueueRebuild = () => {
18407
+ rebuildTail = rebuildTail.then(rebuildSubscriptions, rebuildSubscriptions);
18408
+ };
18409
+ const userListener = (event) => {
18410
+ if (phase === "live") writer.enqueueRaw(serializeScoped(null, event));
18411
+ if (event.type === "membership.affected") enqueueRebuild();
18412
+ };
18413
+ const roomListener = (scope) => (event) => {
18414
+ if (phase === "live") writer.enqueueRaw(serializeScoped(scope, event));
18415
+ };
18416
+ const scheduleExpiry = () => {
18417
+ if (closed) return;
18418
+ const delay2 = actor2.tokenExpiresAt - this.now();
18419
+ if (delay2 <= 0) {
18420
+ revoke("TOKEN_EXPIRED");
18421
+ return;
18422
+ }
18423
+ expiryTimer = setTimeout(() => {
18424
+ expiryTimer = void 0;
18425
+ scheduleExpiry();
18426
+ }, Math.min(delay2, this.maxTimerDelay));
18427
+ expiryTimer.unref?.();
18428
+ };
18429
+ const scheduleHeartbeat = () => {
18430
+ if (closed) return;
18431
+ heartbeatTimer = setTimeout(() => {
18432
+ heartbeatTimer = void 0;
18433
+ if (closed) return;
18434
+ writer.heartbeat();
18435
+ scheduleHeartbeat();
18436
+ }, this.heartbeatMs);
18437
+ heartbeatTimer.unref?.();
18438
+ };
18439
+ const scheduleAccessCheck = () => {
18440
+ if (closed) return;
18441
+ accessTimer = setTimeout(() => {
18442
+ accessTimer = void 0;
18443
+ if (closed) return;
18444
+ const projectIds = [...subscriptions.values()].map((entry) => entry.scope.projectId).filter((projectId) => projectId !== PROJECT_ROOM_USER_CHANNEL_PROJECT);
18445
+ Promise.all(projectIds.map((projectId) => Promise.resolve().then(() => this.deps.requireReadAccess({ tenantId: actor2.tenantId, userId: actor2.userId, projectId })))).then(() => {
18446
+ if (!closed) scheduleAccessCheck();
18447
+ }, () => {
18448
+ if (!closed) revoke("PROJECT_ACCESS_REVOKED");
18449
+ });
18450
+ }, this.authRecheckMs);
18451
+ accessTimer.unref?.();
18452
+ };
18453
+ scheduleHeartbeat();
18454
+ enqueueRebuild();
18455
+ const initialRebuild = rebuildTail;
18456
+ void initialRebuild.then((ok) => {
18457
+ if (closed) return;
18458
+ if (!ok) {
18459
+ cleanup();
18460
+ return;
18461
+ }
18462
+ writer.enqueueControl({ type: "ready", data: { epoch: this.deps.broker.epoch, headEventId: null } });
18463
+ phase = "live";
18464
+ scheduleExpiry();
18465
+ scheduleAccessCheck();
17780
18466
  });
17781
- await this.deps.subscriber.drain(drained ? this.shutdownTimeoutMs : 0);
17782
- this.service.close();
17783
- this.broker.close();
18467
+ return record;
17784
18468
  }
17785
18469
  };
17786
- function createProjectRoomRealtimeRuntime(deps) {
17787
- const broker = new ProjectRoomEventBroker({ log: deps.log });
17788
- const publisher = new BrokerProjectRoomRealtimePublisher({ broker, log: deps.log });
17789
- const service2 = new ProjectRoomRealtimeService({ broker, log: deps.log, requireReadAccess: deps.requireReadAccess });
17790
- const subscriber = new ProjectRoomTaskEventSubscriber({
17791
- tasks: deps.tasks,
17792
- rooms: deps.rooms,
17793
- memberships: deps.memberships,
17794
- realtime: publisher,
17795
- log: deps.log
17796
- });
17797
- return new ProjectRoomRealtimeRuntime({
17798
- broker,
17799
- publisher,
17800
- service: service2,
17801
- subscriber,
17802
- subscribe: (listener) => taskLifecycleNotifier.subscribe(listener),
17803
- log: deps.log,
17804
- shutdownTimeoutMs: deps.shutdownTimeoutMs
17805
- });
17806
- }
17807
- async function boundedAllSettled(promises, timeoutMs) {
17808
- if (promises.length === 0) return true;
17809
- let timer;
17810
- const timeout = new Promise((resolve3) => {
17811
- timer = setTimeout(() => resolve3(false), timeoutMs);
17812
- timer.unref?.();
17813
- });
17814
- const result = await Promise.race([Promise.allSettled(promises).then(() => true), timeout]);
17815
- if (timer) clearTimeout(timer);
17816
- return result;
18470
+
18471
+ // src/services/collaboration/WorkspaceMemberRoomLister.ts
18472
+ function createWorkspaceMemberRoomLister(deps) {
18473
+ return async (input) => {
18474
+ const projects = await deps.projects.getProjectsByWorkspace(input.tenantId, input.workspaceId);
18475
+ const memberRooms = [];
18476
+ for (const project of projects) {
18477
+ const membership = await deps.memberships.findByUser(input.tenantId, project.id, input.userId);
18478
+ if (!membership || membership.status !== "active") continue;
18479
+ const room = await deps.rooms.getMainRoom(input.tenantId, project.id);
18480
+ if (room) memberRooms.push({ projectId: project.id, roomId: room.id });
18481
+ }
18482
+ return memberRooms;
18483
+ };
17817
18484
  }
17818
18485
 
17819
- // src/routes/project-room-events.ts
17820
- import { isProjectRoomEventId, snapshotExactRecord as snapshotExactRecord12 } from "@axiom-lattice/protocols";
17821
- function registerProjectRoomEventRoutes(app2, deps) {
17822
- app2.get("/api/projects/:projectId/room/events", async (request, reply) => {
18486
+ // src/routes/workspace-room-events.ts
18487
+ import { snapshotExactRecord as snapshotExactRecord12 } from "@axiom-lattice/protocols";
18488
+ function registerWorkspaceRoomEventRoutes(app2, deps) {
18489
+ app2.get("/api/workspaces/:workspaceId/room-events", async (request, reply) => {
17823
18490
  try {
17824
- const projectId = exactProjectId(request.params);
17825
- const headers = strictHeaders(request, true);
18491
+ const params = exactParams(request.params);
18492
+ const headers = strictHeaders(request);
17826
18493
  if (request.body !== void 0 || Object.keys(request.query).length !== 0) return invalid(reply);
17827
18494
  const session = verifyConsoleSessionAuthHeader(headers.authorization, deps.tokenSecret);
17828
18495
  if (!session?.tenantId) return unauthorized(reply);
17829
- await deps.access.requireExistingProjectAccess({ tenantId: session.tenantId, userId: session.id, projectId, capability: "read" });
17830
- const room = exactRoom(await deps.rooms.getMainRoom(session.tenantId, projectId), session.tenantId, projectId);
17831
- if (!room) return reply.code(404).send({ success: false, error: { code: "PROJECT_ROOM_NOT_FOUND", message: "Project room not found", retryable: false } });
17832
- const actor2 = { tenantId: session.tenantId, userId: session.id, projectId, tokenExpiresAt: session.expiresAt };
17833
- if (!deps.realtime.canConnect(actor2)) return reply.code(429).send({ success: false, error: { code: "PROJECT_ROOM_STREAM_LIMIT", message: "Project room stream limit reached", retryable: true } });
17834
18496
  reply.hijack();
17835
18497
  reply.raw.writeHead(200, {
17836
18498
  "Content-Type": "text/event-stream",
@@ -17839,53 +18501,35 @@ function registerProjectRoomEventRoutes(app2, deps) {
17839
18501
  "X-Accel-Buffering": "no",
17840
18502
  "Access-Control-Allow-Origin": "*"
17841
18503
  });
17842
- deps.realtime.connect({ actor: actor2, roomId: room.id, ...headers.lastEventId ? { lastEventId: headers.lastEventId } : {}, raw: reply.raw });
17843
- } catch (error) {
17844
- return routeError(reply, error);
17845
- }
17846
- });
17847
- app2.get("/api/projects/:projectId/room/realtime-mode", async (request, reply) => {
17848
- try {
17849
- const projectId = exactProjectId(request.params);
17850
- const headers = strictHeaders(request, false);
17851
- if (request.body !== void 0 || Object.keys(request.query).length !== 0) return invalid(reply);
17852
- const session = verifyConsoleSessionAuthHeader(headers.authorization, deps.tokenSecret);
17853
- if (!session?.tenantId) return unauthorized(reply);
17854
- await deps.access.requireExistingProjectAccess({ tenantId: session.tenantId, userId: session.id, projectId, capability: "read" });
17855
- return reply.send({ success: true, data: { mode: "single-gateway", supportedGatewayProcesses: 1, durableReplay: false, epoch: deps.broker.epoch } });
18504
+ deps.service.connect({
18505
+ actor: { tenantId: session.tenantId, userId: session.id, tokenExpiresAt: session.expiresAt },
18506
+ workspaceId: params.workspaceId,
18507
+ raw: reply.raw
18508
+ });
17856
18509
  } catch (error) {
17857
18510
  return routeError(reply, error);
17858
18511
  }
17859
18512
  });
17860
18513
  }
17861
- function strictHeaders(request, requireSse) {
18514
+ function exactParams(params) {
18515
+ const value = snapshotExactRecord12(params, ["workspaceId"]);
18516
+ if (!value || typeof value.workspaceId !== "string" || !value.workspaceId.trim()) throw new InvalidRealtimeRequestError();
18517
+ return { workspaceId: value.workspaceId };
18518
+ }
18519
+ function strictHeaders(request) {
17862
18520
  const raw = request.raw.rawHeaders;
17863
18521
  const values = (name) => raw.flatMap((value, index) => index % 2 === 0 && value.toLowerCase() === name ? [raw[index + 1]] : []);
17864
18522
  const authorization = values("authorization");
17865
18523
  const accept = values("accept");
17866
18524
  const cursor = values("last-event-id");
17867
- if (authorization.length !== 1 || authorization[0].includes(",") || cursor.length > 1 || cursor.some((value) => value.includes(",")) || requireSse && (accept.length !== 1 || !isSseAccept(accept[0]))) {
17868
- throw new InvalidRealtimeRequestError();
17869
- }
17870
- const lastEventId = cursor[0]?.trim();
17871
- if (lastEventId !== void 0 && (!lastEventId || !isProjectRoomEventId(lastEventId))) throw new InvalidRealtimeRequestError();
17872
- return { authorization: authorization[0], ...lastEventId ? { lastEventId } : {} };
18525
+ if (authorization.length !== 1 || authorization[0].includes(",") || cursor.length > 0 || accept.length !== 1 || !isSseAccept(accept[0])) throw new InvalidRealtimeRequestError();
18526
+ return { authorization: authorization[0] };
17873
18527
  }
17874
18528
  function isSseAccept(value) {
17875
18529
  if (value.includes(",")) return false;
17876
18530
  const [mediaType, ...parameters] = value.split(";");
17877
18531
  return mediaType.trim() === "text/event-stream" && parameters.every((parameter) => /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\s*=\s*(?:[!#$%&'*+.^_`|~0-9A-Za-z-]+|"[^"]*")$/.test(parameter.trim()));
17878
18532
  }
17879
- function exactProjectId(params) {
17880
- const value = snapshotExactRecord12(params, ["projectId"]);
17881
- if (!value || typeof value.projectId !== "string" || !value.projectId.trim()) throw new InvalidRealtimeRequestError();
17882
- return value.projectId;
17883
- }
17884
- function exactRoom(value, tenantId, projectId) {
17885
- if (!value || typeof value !== "object") return void 0;
17886
- const room = value;
17887
- return typeof room.id === "string" && room.id && room.tenantId === tenantId && room.projectId === projectId ? { id: room.id } : void 0;
17888
- }
17889
18533
  var InvalidRealtimeRequestError = class extends Error {
17890
18534
  };
17891
18535
  function invalid(reply) {
@@ -17896,7 +18540,6 @@ function unauthorized(reply) {
17896
18540
  }
17897
18541
  function routeError(reply, error) {
17898
18542
  if (error instanceof InvalidRealtimeRequestError) return invalid(reply);
17899
- if (error instanceof ProjectCollaborationError) return reply.code(error.statusCode).send({ success: false, error: { code: error.code, message: error.message, retryable: false } });
17900
18543
  return reply.code(500).send({ success: false, error: { code: "INTERNAL_ERROR", message: "Internal server error", retryable: false } });
17901
18544
  }
17902
18545
 
@@ -18035,6 +18678,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18035
18678
  const projectRoomStore = getStoreLattice16("default", "projectRoom").store;
18036
18679
  const projectBotMembershipStore = getStoreLattice16("default", "projectBotMembership").store;
18037
18680
  const projectRoomMessageStore = getStoreLattice16("default", "projectRoomMessage").store;
18681
+ const projectRoomReadStateStore = getStoreLattice16("default", "projectRoomReadState").store;
18038
18682
  const threadStore = getStoreLattice16("default", "thread").store;
18039
18683
  const taskStore = getStoreLattice16("default", "task").store;
18040
18684
  const taskWorkItemStore = getStoreLattice16("default", "taskWorkItem").store;
@@ -18046,23 +18690,30 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18046
18690
  tasks: taskStore,
18047
18691
  rooms: projectRoomStore,
18048
18692
  memberships: projectBotMembershipStore,
18049
- log: realtimeLog,
18050
- requireReadAccess: async (actor2) => {
18051
- await accessService.requireExistingProjectAccess({
18052
- tenantId: actor2.tenantId,
18053
- userId: actor2.userId,
18054
- projectId: actor2.projectId,
18055
- capability: "read"
18056
- });
18057
- }
18693
+ log: realtimeLog
18058
18694
  }) : void 0;
18059
18695
  if (projectRoomRealtimeRuntime) {
18060
18696
  app2.addHook("onClose", async () => projectRoomRealtimeRuntime?.close());
18061
- registerProjectRoomEventRoutes(app2, {
18062
- access: accessService,
18063
- rooms: projectRoomStore,
18064
- realtime: projectRoomRealtimeRuntime.service,
18697
+ const workspaceRoomEventsService = new WorkspaceRoomEventsService({
18065
18698
  broker: projectRoomRealtimeRuntime.broker,
18699
+ listMemberRooms: createWorkspaceMemberRoomLister({
18700
+ projects: projectStore,
18701
+ memberships: projectMembershipStore,
18702
+ rooms: projectRoomStore
18703
+ }),
18704
+ requireReadAccess: async (input) => {
18705
+ await accessService.requireExistingProjectAccess({
18706
+ tenantId: input.tenantId,
18707
+ userId: input.userId,
18708
+ projectId: input.projectId,
18709
+ capability: "read"
18710
+ });
18711
+ },
18712
+ log: realtimeLog
18713
+ });
18714
+ app2.addHook("onClose", async () => workspaceRoomEventsService.close());
18715
+ registerWorkspaceRoomEventRoutes(app2, {
18716
+ service: workspaceRoomEventsService,
18066
18717
  tokenSecret: resolveConsoleTokenSecret(process.env.AUTH_REQUIRED === "true")
18067
18718
  });
18068
18719
  }
@@ -18144,7 +18795,24 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18144
18795
  saveBot: projectBotMembershipStore.save.bind(projectBotMembershipStore),
18145
18796
  ensureCoordinator: (tenantId) => coordinatorProvisioner.ensure(tenantId)
18146
18797
  });
18147
- registerProjectRoomRoutes(app2, { roomService, membershipService, messageService });
18798
+ const readStateService = {
18799
+ mark: async (actorRef) => {
18800
+ await accessService.requireExistingProjectAccess({ ...actorRef, capability: "read" });
18801
+ const room = await projectRoomStore.getMainRoom(actorRef.tenantId, actorRef.projectId);
18802
+ if (!room) return;
18803
+ const lastReadAt = /* @__PURE__ */ new Date();
18804
+ await projectRoomReadStateStore.markRead({ tenantId: actorRef.tenantId, roomId: room.id, userId: actorRef.userId, lastReadAt });
18805
+ projectRoomRealtimeRuntime?.publisher.readChanged({
18806
+ tenantId: actorRef.tenantId,
18807
+ userId: actorRef.userId,
18808
+ projectId: actorRef.projectId,
18809
+ roomId: room.id,
18810
+ lastReadAt: lastReadAt.toISOString(),
18811
+ sourceKey: `read:${actorRef.userId}:${room.id}:${lastReadAt.getTime()}`
18812
+ });
18813
+ }
18814
+ };
18815
+ registerProjectRoomRoutes(app2, { roomService, membershipService, messageService, readStateService });
18148
18816
  registerProjectRosterRoutes(app2, { service: rosterService });
18149
18817
  registerCoSpaceRoutes(app2, {
18150
18818
  projectStore: {
@@ -18166,7 +18834,11 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18166
18834
  },
18167
18835
  messageStore: {
18168
18836
  list: projectRoomMessageStore.list.bind(projectRoomMessageStore),
18169
- create: projectRoomMessageStore.create.bind(projectRoomMessageStore)
18837
+ create: projectRoomMessageStore.create.bind(projectRoomMessageStore),
18838
+ countAfter: projectRoomMessageStore.countAfter.bind(projectRoomMessageStore)
18839
+ },
18840
+ readStateStore: {
18841
+ get: projectRoomReadStateStore.get.bind(projectRoomReadStateStore)
18170
18842
  },
18171
18843
  userTenantLinkStore: {
18172
18844
  getUsersByTenant: userTenantLinkStore.getUsersByTenant.bind(userTenantLinkStore)
@@ -18209,6 +18881,46 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18209
18881
  })
18210
18882
  });
18211
18883
  registerAgentWebAppRuntimeRoutes(app2, {
18884
+ workspaceController: new WorkspaceController(createProjectCollaborationInitializer({
18885
+ membershipStore: projectMembershipStore,
18886
+ roomStore: projectRoomStore,
18887
+ userTenantLinkStore
18888
+ })),
18889
+ taskController: createTaskController({
18890
+ access: {
18891
+ requireProjectAccess: async (input) => {
18892
+ const apps = await webAppStore.list(input.tenantId);
18893
+ const allowed = apps.some((app3) => app3.status === "active" && app3.scope.allowedProjectIds.includes(input.projectId));
18894
+ if (!allowed) throw new ProjectCollaborationError("PROJECT_ACCESS_DENIED", 403, "Project is not exposed through this web app");
18895
+ const project = await projectStore.getProjectById(input.tenantId, input.projectId);
18896
+ if (!project) throw new ProjectCollaborationError("PROJECT_NOT_FOUND", 404, "Project not found");
18897
+ return {
18898
+ project,
18899
+ membership: {
18900
+ id: `webapp_guest_${input.projectId}_${input.userId}`,
18901
+ tenantId: input.tenantId,
18902
+ projectId: input.projectId,
18903
+ userId: input.userId,
18904
+ role: "member",
18905
+ status: "active",
18906
+ joinedAt: /* @__PURE__ */ new Date(),
18907
+ updatedAt: /* @__PURE__ */ new Date()
18908
+ }
18909
+ };
18910
+ }
18911
+ },
18912
+ tasks: taskStore,
18913
+ workItems: taskWorkItemStore,
18914
+ bots: projectBotMembershipStore,
18915
+ rooms: projectRoomStore,
18916
+ threadService: taskThreadService,
18917
+ reassignmentAuthorizer,
18918
+ lifecycle: taskLifecycle,
18919
+ projectMutationMutex: projectMutationMutex2,
18920
+ executionMutex: projectTaskComposition?.mutex ?? {
18921
+ runExclusive: (_scope, operation) => operation()
18922
+ }
18923
+ }),
18212
18924
  service: new AgentWebAppRuntimeService({
18213
18925
  webAppStore,
18214
18926
  threadStore: getStoreLattice16("default", "thread").store,
@@ -18216,7 +18928,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18216
18928
  assistantResolver: {
18217
18929
  resolve: async (tenantId, assistantId) => {
18218
18930
  const stored = await assistantStore.getAssistantById(tenantId, assistantId);
18219
- if (stored) return stored;
18931
+ if (stored) return { id: stored.id, name: stored.name, description: stored.description };
18220
18932
  await agentLatticeManager4.initializeStoredAssistantsForTenant(tenantId);
18221
18933
  const config = agentLatticeManager4.getAgentConfigWithTenant(tenantId, assistantId);
18222
18934
  return config ? { id: assistantId, name: config.name, description: config.description } : null;
@@ -18259,6 +18971,7 @@ var registerLatticeRoutes = (app2, channelDeps, options = {}) => {
18259
18971
  }
18260
18972
  })
18261
18973
  });
18974
+ registerAgentWebAppEmbedRoutes(app2, {});
18262
18975
  registerA2ABridgeRoutes(app2);
18263
18976
  registerSTTRoutes(app2);
18264
18977
  app2.get("/api/local-a2a", getLocalA2AStatus);
@@ -20980,9 +21693,9 @@ var MessageRouter = class {
20980
21693
  };
20981
21694
 
20982
21695
  // src/channels/room/RoomChannelAdapter.ts
20983
- import { z as z9 } from "zod";
21696
+ import { z as z10 } from "zod";
20984
21697
  import { snapshotExactRecord as snapshotExactRecord15 } from "@axiom-lattice/protocols";
20985
- var roomConfigSchema = z9.object({}).strict();
21698
+ var roomConfigSchema = z10.object({}).strict();
20986
21699
  function createRoomChannelAdapter(writer) {
20987
21700
  return {
20988
21701
  channel: "room",
@@ -21162,7 +21875,7 @@ app.register(multipart, {
21162
21875
  });
21163
21876
  app.register(websocket);
21164
21877
  app.register(staticPlugin, {
21165
- root: typeof __dirname === "string" ? path3.join(__dirname, "../public") : path3.resolve(process.cwd(), "public"),
21878
+ root: typeof __dirname === "string" ? path4.join(__dirname, "../public") : path4.resolve(process.cwd(), "public"),
21166
21879
  prefix: "/"
21167
21880
  });
21168
21881
  app.setErrorHandler((error, request, reply) => {
@@ -21213,7 +21926,7 @@ async function restoreMcpConnections() {
21213
21926
  const connectedConfigs = configs.filter((c2) => c2.status === "connected");
21214
21927
  if (connectedConfigs.length === 0) return;
21215
21928
  logger5.info(`Restoring ${connectedConfigs.length} MCP server connections...`);
21216
- const { convertToConnection } = await import("./mcp-configs-SHRMQHIL.mjs");
21929
+ const { convertToConnection } = await import("./mcp-configs-IIKQM5GM.mjs");
21217
21930
  for (const config of connectedConfigs) {
21218
21931
  try {
21219
21932
  const connection = convertToConnection(config.config);
@@ -21252,26 +21965,11 @@ var start = async (config) => {
21252
21965
  const projectRoomRealtimeMode = resolveProjectRoomRealtimeMode();
21253
21966
  let projectRoomRealtimeRuntime;
21254
21967
  if (projectRoomRealtimeMode === "single-gateway") {
21255
- const projectStore = getStoreLattice27("default", "project").store;
21256
- const membershipStore = getStoreLattice27("default", "projectMembership").store;
21257
- const access = new ProjectAccessService({
21258
- projectStore,
21259
- membershipStore,
21260
- userTenantLinkStore: getStoreLattice27("default", "userTenantLink").store
21261
- });
21262
21968
  projectRoomRealtimeRuntime = createProjectRoomRealtimeRuntime({
21263
21969
  tasks: getStoreLattice27("default", "task").store,
21264
21970
  rooms: getStoreLattice27("default", "projectRoom").store,
21265
21971
  memberships: getStoreLattice27("default", "projectBotMembership").store,
21266
- log: { warn: (message, context) => logger5.warn(message, context) },
21267
- requireReadAccess: async (actor2) => {
21268
- await access.requireExistingProjectAccess({
21269
- tenantId: actor2.tenantId,
21270
- userId: actor2.userId,
21271
- projectId: actor2.projectId,
21272
- capability: "read"
21273
- });
21274
- }
21972
+ log: { warn: (message, context) => logger5.warn(message, context) }
21275
21973
  });
21276
21974
  }
21277
21975
  let channelDeps;
@@ -21329,7 +22027,7 @@ var start = async (config) => {
21329
22027
  });
21330
22028
  try {
21331
22029
  const { A2AAuthService, parseEnvKeys } = await import("./A2AAuthService-DK5X6VIL.mjs");
21332
- const { registerA2AStandardRoutes } = await import("./a2a-standard-G3J5ZHQ7.mjs");
22030
+ const { registerA2AStandardRoutes } = await import("./a2a-standard-WC2BSOFV.mjs");
21333
22031
  const a2a = await import("./a2a-7N3WDAOP.mjs");
21334
22032
  const a2aKeyStore = getStoreLattice27("default", "a2aApiKey").store;
21335
22033
  const assistantStore = getStoreLattice27("default", "assistant").store;
@@ -21358,6 +22056,15 @@ var start = async (config) => {
21358
22056
  error: err instanceof Error ? err.message : String(err)
21359
22057
  });
21360
22058
  }
22059
+ try {
22060
+ const { registerOpenRoutes } = await import("./open-DCAOL5CG.mjs");
22061
+ registerOpenRoutes(app);
22062
+ logger5.info("Open MCP spike routes registered");
22063
+ } catch (err) {
22064
+ logger5.warn("Open MCP spike routes unavailable", {
22065
+ error: err instanceof Error ? err.message : String(err)
22066
+ });
22067
+ }
21361
22068
  if (!sandboxLatticeManager2.hasLattice("default")) {
21362
22069
  sandboxLatticeManager2.registerLattice("default", getConfiguredSandboxProvider());
21363
22070
  logger5.info("Registered sandbox manager from env configuration");