collabmd 0.1.48 → 0.1.51

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 (482) hide show
  1. package/README.md +15 -608
  2. package/bin/collabmd.js +39 -20
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-Crf9Y3Q6.js +1 -0
  4. package/dist/client/assets/abnfDiagram-VCTEODGH-PuinKbSQ.js +1 -0
  5. package/dist/client/assets/ar-SA-5WIASEJP-Di7OimCN.js +10 -0
  6. package/dist/client/assets/{architectureDiagram-5GKGNRK7-I39sYjHI.js → architectureDiagram-5GKGNRK7-46hPkrZv.js} +3 -3
  7. package/dist/client/assets/az-AZ-V5EUQD6C-C19OGTT_.js +1 -0
  8. package/dist/client/assets/bg-BG-EXASCMTR-BIt0xWyb.js +5 -0
  9. package/dist/client/assets/{blockDiagram-NRAW4CY4-C6DtJy5Y.js → blockDiagram-I7D4REHJ-C1S5Bzf8.js} +4 -4
  10. package/dist/client/assets/bn-BD-U4SYNFCO-CdNaPy4Q.js +3 -0
  11. package/dist/client/assets/bn-IN-HKDJIITE-CdNaPy4Q.js +3 -0
  12. package/dist/client/assets/{browser-BKLM0ThC-IxjwuOIz-BBqQnUEb.js → browser-BKLM0ThC-IxjwuOIz-DyJcVMFR.js} +1 -1
  13. package/dist/client/assets/browser-utils-DbXSMI-6.js +1 -0
  14. package/dist/client/assets/{c4Diagram-UCG6FXSJ-CtWtxS9_.js → c4Diagram-7LVT6UL2-VAk1HPmz.js} +1 -1
  15. package/dist/client/assets/ca-ES-2KGUU5XB-C9t-c0cH.js +8 -0
  16. package/dist/client/assets/channel-jwdhnPiV.js +1 -0
  17. package/dist/client/assets/chunk-2E4U76K2-Ba8Wf22k.js +1 -0
  18. package/dist/client/assets/{chunk-TEH6E4GO-DVayPj-q.js → chunk-4HAMMTFA-Ht-73lsT.js} +20 -20
  19. package/dist/client/assets/chunk-5XKZK2GL-D4UAZSOJ.js +1 -0
  20. package/dist/client/assets/{chunk-75Z2AOVW-CdFSaPjz.js → chunk-75Z2AOVW-B2cZexqK.js} +1 -1
  21. package/dist/client/assets/{chunk-CLGD4ZFX-DQLgbQrv.js → chunk-CLGD4ZFX-Cmtx89ht.js} +1 -1
  22. package/dist/client/assets/chunk-DU6HZSFF-C6d6PJfE.js +127 -0
  23. package/dist/client/assets/{chunk-F27PBJKO-CNHIFhjo.js → chunk-F27PBJKO-Dg3H6KLL.js} +1 -1
  24. package/dist/client/assets/{chunk-GMAD6QVW-CbcBqPM5.js → chunk-GMAD6QVW-DUfjx_d5.js} +1 -1
  25. package/dist/client/assets/{chunk-OBVCFTLP-BJR7u1jh.js → chunk-GVQU2GXP-D1l7oRGR.js} +1 -1
  26. package/dist/client/assets/{chunk-G27WJ6UU-D9-eg537.js → chunk-IMKFNOWR-3F6NhHUP.js} +2 -2
  27. package/dist/client/assets/{chunk-JQ64N6SF-DSFNH4bh.js → chunk-L3NEJ4N5-BmCVn4y-.js} +1 -1
  28. package/dist/client/assets/chunk-OSK3NFVY-CWHXAmfx.js +10 -0
  29. package/dist/client/assets/{chunk-P2QGCYS3-BRpqY32H.js → chunk-P2QGCYS3-Du8EtwOa.js} +1 -1
  30. package/dist/client/assets/{chunk-POPQ4Y6H-Cb4SlVZF.js → chunk-POPQ4Y6H-B5yJIrZE.js} +1 -1
  31. package/dist/client/assets/{chunk-PWAF6VOD-Cz8IwBB5.js → chunk-PWAF6VOD-B3gML4ps.js} +1 -1
  32. package/dist/client/assets/{chunk-RHFEMEQ7-CWY8cf4H.js → chunk-SHT3W25Y-BKaI8jZO.js} +5 -5
  33. package/dist/client/assets/{chunk-SVP7TREG-CyHOmcac.js → chunk-SVP7TREG-XlsB_ZMZ.js} +1 -1
  34. package/dist/client/assets/{chunk-LCL6LL3I-DmDkVukh.js → chunk-TICWLB2K-Cpp2z8yK.js} +4 -4
  35. package/dist/client/assets/chunk-TLUHSLCS-Yl7B0Vrz.js +1 -0
  36. package/dist/client/assets/chunk-ZNVOA63L-BmCQjhx-.js +40 -0
  37. package/dist/client/assets/{chunk-FLYJHZSQ-Be7lKF17.js → chunk-ZPMXAHWN-Dt0TxJa6.js} +2 -2
  38. package/dist/client/assets/classDiagram-ZZMXUADV-BRw9vo8U.js +1 -0
  39. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BRw9vo8U.js +1 -0
  40. package/dist/client/assets/comment-markdown-renderer-B9_vPc3F.js +1 -0
  41. package/dist/client/assets/comment-thread-store-NNHqRVsX.js +1 -0
  42. package/dist/client/assets/comment-threads-nJhK1yfc.js +4 -0
  43. package/dist/client/assets/cs-CZ-VUCGPRML-BfCoYAgj.js +7 -0
  44. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CdTPi2yO.js → cynefinDiagram-5FMLGOSQ-BRoCEoZM.js} +1 -1
  45. package/dist/client/assets/da-DK-NNDP2IVP-DBw9ZNTR.js +2 -0
  46. package/dist/client/assets/{dagre-3AP2YEHR-5gtJtd0O.js → dagre-GXQ25YYZ-BSfKCfy7.js} +2 -2
  47. package/dist/client/assets/de-CH-I7RAVIZN-DYW18Vsr.js +11 -0
  48. package/dist/client/assets/de-DE-WBQ3DQLR-DYW18Vsr.js +11 -0
  49. package/dist/client/assets/deferred-collab-rBe4nuQ2.css +1 -0
  50. package/dist/client/assets/deferred-git-BHKtkFYi.css +1 -0
  51. package/dist/client/assets/deferred-preview-pe7Iwwx3.css +1 -0
  52. package/dist/client/assets/{diagram-S7CK7UJ4-BudWz9WU.js → diagram-S7CK7UJ4-D7KaM9yj.js} +2 -2
  53. package/dist/client/assets/{diagram-UQ7AKVKN-3v4rbH-s.js → diagram-UQ7AKVKN-JevUZuYi.js} +1 -1
  54. package/dist/client/assets/diagram-VSXAHHWV-B3-U-Q2E.js +3 -0
  55. package/dist/client/assets/{diagram-VX7I27RA-C_-rj0sw.js → diagram-VX7I27RA-pSD4HMh1.js} +1 -1
  56. package/dist/client/assets/{diagram-Z3DM3KII-B4yxavgj.js → diagram-Z3DM3KII-D8r1_CIb.js} +1 -1
  57. package/dist/client/assets/{direct-engine-DdrQKpgq-CtKfQzCt.js → direct-engine-DdrQKpgq-B5zIoeQw.js} +1 -1
  58. package/dist/client/assets/dist-B3HdUPsK.js +1 -0
  59. package/dist/client/assets/{dist-Tw-Fxpeb.js → dist-B7XMN9AT.js} +1 -1
  60. package/dist/client/assets/dist-BIRygGYH.js +1 -0
  61. package/dist/client/assets/dist-BPyOlNLY.js +2 -0
  62. package/dist/client/assets/{dist-D5wCC32z.js → dist-BR81yxMt.js} +1 -1
  63. package/dist/client/assets/{dist-Bw3VIE_v.js → dist-B_B4XLmq.js} +1 -1
  64. package/dist/client/assets/dist-Bdy9ZRzd.js +9 -0
  65. package/dist/client/assets/{dist-netZOQtD.js → dist-Bfxzlnrf.js} +1 -1
  66. package/dist/client/assets/{dist-CietwTVS.js → dist-Bx3QkS-3.js} +1 -1
  67. package/dist/client/assets/{dist-mj2Ht75J.js → dist-By7ieqAf.js} +1 -1
  68. package/dist/client/assets/dist-ByhQbe-x.js +1 -0
  69. package/dist/client/assets/{dist-CdmKGRGr.js → dist-BzFSJM0U.js} +1 -1
  70. package/dist/client/assets/dist-C5NkYKAa.js +1 -0
  71. package/dist/client/assets/{dist-D3fehAZ2.js → dist-CELhfKzh.js} +1 -1
  72. package/dist/client/assets/dist-CEirJSxk.js +1 -0
  73. package/dist/client/assets/dist-CO0-4CuV.js +39 -0
  74. package/dist/client/assets/dist-CRnJ0D9h.js +1 -0
  75. package/dist/client/assets/{dist-DDUn5zTz.js → dist-CbDyXgCo.js} +1 -1
  76. package/dist/client/assets/{dist-BeajGMhO.js → dist-CqXVyYoH.js} +1 -1
  77. package/dist/client/assets/{dist-LQ4kDCKz.js → dist-CrWzIWEE.js} +1 -1
  78. package/dist/client/assets/dist-CyNrloSI.js +1 -0
  79. package/dist/client/assets/dist-D60_kdpQ.js +1 -0
  80. package/dist/client/assets/{dist-DuH3ZrHo.js → dist-DCpIH3-_.js} +1 -1
  81. package/dist/client/assets/{dist-BPHLJ09L.js → dist-DJAMplZI.js} +2 -2
  82. package/dist/client/assets/{dist-DGEbEfw4.js → dist-DVXzbeDx.js} +1 -1
  83. package/dist/client/assets/{dist-C5NgpdG5.js → dist-Drv_wZYC.js} +1 -1
  84. package/dist/client/assets/{dist-DVy5woUy.js → dist-EWJYvBK1.js} +1 -1
  85. package/dist/client/assets/dist-Hdhj3L3t.js +1 -0
  86. package/dist/client/assets/{dist-B_yQaEv_.js → dist-gRRhmB-2.js} +3 -3
  87. package/dist/client/assets/dist-kWb2d1CH.js +1 -0
  88. package/dist/client/assets/dist-kiD2GIsD.js +13 -0
  89. package/dist/client/assets/dist-l-56SowH.js +19 -0
  90. package/dist/client/assets/{dist-BK9QvQrc.js → dist-nxQErAaK.js} +2 -2
  91. package/dist/client/assets/dist-sLzRQQk7.js +1 -0
  92. package/dist/client/assets/{document-formatter-Dxl_a8XO.js → document-formatter-Qdiq9uJs.js} +1 -2
  93. package/dist/client/assets/drawioEditor-CHf1vtdQ.js +9 -0
  94. package/dist/client/assets/ebnfDiagram-PWID7BFC-UJ0Fz5ci.js +1 -0
  95. package/dist/client/assets/editor-session-4Bn81iWm.js +14 -0
  96. package/dist/client/assets/el-GR-TYQHVGXW-Dx82YYAS.js +7 -0
  97. package/dist/client/assets/embedded-editor-base-jK221GC8.css +1 -0
  98. package/dist/client/assets/{embedpdf-DA4bA119-BPqZxwjc.js → embedpdf-DA4bA119-E8wZ11J2.js} +2 -3
  99. package/dist/client/assets/{embedpdf-BmE13ZZ0.js → embedpdf-LUXDBD3-.js} +1 -1
  100. package/dist/client/assets/{en-SJ2YIMFF-CJBL3nkq.js → en-2RFA324Y-BsuNJTcL.js} +1 -1
  101. package/dist/client/assets/{erDiagram-SSCWMZ5O-C-iy6VkX.js → erDiagram-RLTQ6QDP-CWrH1UJ9.js} +2 -2
  102. package/dist/client/assets/es-ES-JEUOREKJ-Rx0NUQDl.js +12 -0
  103. package/dist/client/assets/eu-ES-SO5DEEAN-CDYm-BcK.js +8 -0
  104. package/dist/client/assets/excalidraw-element-link-iA6zo0_f.js +7 -0
  105. package/dist/client/assets/{excalidraw-scene-BOben2gr.js → excalidraw-scene-6uROebca.js} +1 -1
  106. package/dist/client/assets/{excalidraw-editor-BbSbI80a.css → excalidrawEditor-DDE0n1Pk.css} +1 -1
  107. package/dist/client/assets/excalidrawEditor-WIuguTz7.js +9 -0
  108. package/dist/client/assets/export-page-AN-wI5p4.js +56 -0
  109. package/dist/client/assets/exportDocument-B7IagJhQ.css +1 -0
  110. package/dist/client/assets/exportDocument-B9xNKpQe.js +2 -0
  111. package/dist/client/assets/fa-IR-FIYUE2GQ-C865Nx3X.js +9 -0
  112. package/dist/client/assets/fi-FI-REAEF6HQ-BIpjJqIb.js +6 -0
  113. package/dist/client/assets/flowDiagram-HODETNUW-kb1lUSBo.js +1 -0
  114. package/dist/client/assets/fr-FR-SUCL7J6B-DGAKE8jH.js +12 -0
  115. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DtKHAbez.js → ganttDiagram-EL5Y4UJY-BBNzDfaV.js} +1 -1
  116. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-oue8fQ5o.js → gitGraphDiagram-WWUBYQGX-Csf0Dm_1.js} +1 -1
  117. package/dist/client/assets/gl-ES-KHCSOGVH-DWKh0CMu.js +6 -0
  118. package/dist/client/assets/he-IL-JYXVXV2Q-zqbcM-4g.js +9 -0
  119. package/dist/client/assets/hi-IN-BU52H3BO-CY8v6eG9.js +3 -0
  120. package/dist/client/assets/highlight-theme-CzNkO-IJ.js +1 -0
  121. package/dist/client/assets/hu-HU-OWADXDQ3-CEl6Udfh.js +3 -0
  122. package/dist/client/assets/id-ID-EOMR5R3I-CGQwUjoL.js +8 -0
  123. package/dist/client/assets/image-2QKV3NAF-BUbX0y5Y.js +1 -0
  124. package/dist/client/assets/index-BAmZnTFV.css +1 -0
  125. package/dist/client/assets/index-mWiw418b.js +1111 -0
  126. package/dist/client/assets/{infoDiagram-RXCK75RN-BMzo6KIn.js → infoDiagram-27XIBGKW-Bzy6kCbb.js} +1 -1
  127. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BIM3h287.js → ishikawaDiagram-5VMMS53U-CRy9vIS5.js} +1 -1
  128. package/dist/client/assets/it-IT-FC2VTM3L-KTijNcUe.js +12 -0
  129. package/dist/client/assets/ja-JP-JBNTKYP4-BflWlGhw.js +12 -0
  130. package/dist/client/assets/{journeyDiagram-EYS64GPL-mF6Lh8O-.js → journeyDiagram-3NMN7TZE-D4ZR_s9J.js} +2 -2
  131. package/dist/client/assets/kaa-TC3VIB7V-B-xtZfy0.js +1 -0
  132. package/dist/client/assets/kab-KAB-UOUDSQKM-BmO0O4Y4.js +4 -0
  133. package/dist/client/assets/{kanban-definition-3QL26DDD-DLN2NyoR.js → kanban-definition-UXKFOSKX-CIDTmu5g.js} +4 -4
  134. package/dist/client/assets/kk-KZ-P5H2X7YS-CSQFB8IN.js +1 -0
  135. package/dist/client/assets/{km-KH-PCWDKPHP-DSmy5shj.js → km-KH-IHMV2US7-BxrjuEzr.js} +4 -4
  136. package/dist/client/assets/ko-KR-ZTMANIDF-BnNRXd5J.js +5 -0
  137. package/dist/client/assets/ku-TR-GPJTRB5G-BZM7f2aT.js +6 -0
  138. package/dist/client/assets/{line-BfTWJmgf.js → line-DSWLHgpx.js} +1 -1
  139. package/dist/client/assets/lobby-presence-Rdjnc0_0.js +1 -0
  140. package/dist/client/assets/lt-LT-V3XDOK3P-MVQBOHmF.js +3 -0
  141. package/dist/client/assets/lv-LV-DVQ3FADO-CrenwAhS.js +4 -0
  142. package/dist/client/assets/markdown-it-CocJWnjv.js +13 -0
  143. package/dist/client/assets/mermaid-parser.core-DrdLA3p0.js +3 -0
  144. package/dist/client/assets/mermaid.core-C_FK-7n4.js +1 -0
  145. package/dist/client/assets/mermaid.core-D0cMM4Rl.js +10 -0
  146. package/dist/client/assets/{mindmap-definition-FBJOCRG2-CRyHaHTk.js → mindmap-definition-YA3MSWOX-DO8NB9VH.js} +8 -8
  147. package/dist/client/assets/mr-IN-VZ6HH5FE-B-PHPglH.js +9 -0
  148. package/dist/client/assets/my-MM-XYKWHRK6-Be5sYp5q.js +1 -0
  149. package/dist/client/assets/nb-NO-UNO2GGZJ-BvSKGdja.js +8 -0
  150. package/dist/client/assets/nl-NL-76EFHT4P-C2yNx1Cj.js +13 -0
  151. package/dist/client/assets/nn-NO-CFKD7ABE-4NsqlDRP.js +4 -0
  152. package/dist/client/assets/oc-FR-YBJTCJ3J-B4OTQsWW.js +4 -0
  153. package/dist/client/assets/pa-IN-SNOXSMRV-CKj_sOG7.js +4 -0
  154. package/dist/client/assets/pegDiagram-XKGWAZYB-DS6Ab21R.js +1 -0
  155. package/dist/client/assets/percentages-Q7USCRWZ-DWE6uvTs.js +1 -0
  156. package/dist/client/assets/{pieDiagram-E7YTZNPT-B5OZPb88.js → pieDiagram-E7YTZNPT-BbFe6Tgs.js} +1 -1
  157. package/dist/client/assets/pl-PL-BSY6YFZ3-CFuzA6L0.js +12 -0
  158. package/dist/client/assets/preload-helper-CtT0-S4g.js +1 -0
  159. package/dist/client/assets/preview-render-compiler-C_7J7eia.js +43 -0
  160. package/dist/client/assets/preview-render-compiler-DzJ1KR_M.js +1 -0
  161. package/dist/client/assets/preview-render-worker-1DoIDllV.js +59 -0
  162. package/dist/client/assets/prod-D5TxmmoB.js +1 -0
  163. package/dist/client/assets/prod-pbFU4TaM.js +145 -0
  164. package/dist/client/assets/pt-BR-CZDV62R3-CkPMtyNx.js +10 -0
  165. package/dist/client/assets/pt-PT-JO57XJJW-CBSnfGtF.js +12 -0
  166. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Drrw14YH.js → quadrantDiagram-AXDQQJYC-fJE7iAxt.js} +1 -1
  167. package/dist/client/assets/quick-switcher-De4PjZFC.css +1 -0
  168. package/dist/client/assets/quick-switcher-controller-CUajuy78.js +1 -0
  169. package/dist/client/assets/railroadDiagram-O6MQD6OU-CUQKqbCK.js +1 -0
  170. package/dist/client/assets/{requirementDiagram-EFPCY7ZU-CRZG6mRB.js → requirementDiagram-BXWQKSXE-Balm0WW8.js} +2 -2
  171. package/dist/client/assets/ro-RO-UZ5ICYYN-BOuntc_r.js +12 -0
  172. package/dist/client/assets/room-DX7lIfnu.js +1 -0
  173. package/dist/client/assets/ru-RU-AN7JPREC-D-ow3SNR.js +10 -0
  174. package/dist/client/assets/runtime-config-BFVdhnJu.js +1 -0
  175. package/dist/client/assets/runtime-paths-Cn0snt_9.js +1 -0
  176. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-DvarEJpo.js → sankeyDiagram-P5KCCOFB-CcbMqrlQ.js} +1 -1
  177. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-B4oWlb-w.js → sequenceDiagram-WJ2MYXX4-BL1j3Sn-.js} +6 -6
  178. package/dist/client/assets/si-LK-7CBLD6QQ-c91EepX0.js +1 -0
  179. package/dist/client/assets/sk-SK-SWR6DKBI-D5vFMIL6.js +7 -0
  180. package/dist/client/assets/sl-SI-JRML4FIH-D53L_0S2.js +6 -0
  181. package/dist/client/assets/{stateDiagram-HBIQ2CUA-qbHIIqRZ.js → stateDiagram-D77RDMKH-DNi924hh.js} +1 -1
  182. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-C62JEwak.js +1 -0
  183. package/dist/client/assets/sv-SE-4ZPKFFXF-DT-G7RCI.js +12 -0
  184. package/dist/client/assets/{swimlanes-XN3QIQJK-xB6CtUGj.js → swimlanes-42K2YHIH-ColgjSH4.js} +1 -1
  185. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-B9UZhEj4.js +8 -0
  186. package/dist/client/assets/ta-IN-V6NHHU6Z-D5jy7_AE.js +6 -0
  187. package/dist/client/assets/th-TH-P7CTMGDK-6sy0NO7K.js +1 -0
  188. package/dist/client/assets/{timeline-definition-24CTP7MA-Lj_yTNlY.js → timeline-definition-24CTP7MA-7pch5JAr.js} +1 -1
  189. package/dist/client/assets/tr-TR-GUFYG22B-ClVaf8h1.js +4 -0
  190. package/dist/client/assets/uk-UA-K6SV5NFQ-BLTTtyNB.js +6 -0
  191. package/dist/client/assets/uz-UZ-TVKTZO2G-Bm02Eg3D.js +1 -0
  192. package/dist/client/assets/vault-api-client-QjZ_T03l.js +7 -0
  193. package/dist/client/assets/vault-utils-Bct69Xw2.js +1 -0
  194. package/dist/client/assets/{vennDiagram-4TSXK5OY-BekRp5Y0.js → vennDiagram-4TSXK5OY-C5taziCX.js} +1 -1
  195. package/dist/client/assets/vi-VN-7FKFXJNO-CL3WPhmG.js +7 -0
  196. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-kdnV_Hdm.js → wardleyDiagram-VM6X3IG4-BbSlUwuM.js} +1 -1
  197. package/dist/client/assets/wiki-link-resolver-C2P_WmTV.js +1 -0
  198. package/dist/client/assets/{worker-engine-m0rlHn8R-S8mpn_O0.js → worker-engine-m0rlHn8R-eSDcDGEI.js} +1 -1
  199. package/dist/client/assets/workspace-change-CVA9dVmy.js +1 -0
  200. package/dist/client/assets/workspace-sync-client-D4nblH_2.js +1 -0
  201. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DufGwNSB.js → xychartDiagram-S5SC5T6Z-D06X1arY.js} +1 -1
  202. package/dist/client/assets/yjs-B41tM6Sz.js +4 -0
  203. package/dist/client/assets/yjs-provider-reset-guard-R43MnLNc.js +1 -0
  204. package/dist/client/assets/zh-CN-AOKVLNNK-DGidDH2b.js +11 -0
  205. package/dist/client/assets/zh-HK-CDKPF5DC-CRcNR3rk.js +1 -0
  206. package/dist/client/assets/zh-TW-ZVGYESGW-C7Qji1y6.js +13 -0
  207. package/dist/client/drawio-editor.html +12 -5
  208. package/dist/client/excalidraw-editor.html +46 -5
  209. package/dist/client/export-document.html +6 -8
  210. package/dist/client/index.html +79 -43
  211. package/package.json +39 -36
  212. package/src/client/app/drawio-editor.html +3 -3
  213. package/src/client/app/excalidraw-editor.html +3 -3
  214. package/src/client/app/export-document.html +2 -2
  215. package/src/client/app/index.html +77 -37
  216. package/src/client/app/main-entry.js +13 -17
  217. package/src/client/application/app-shell/chat-feature.js +7 -22
  218. package/src/client/application/app-shell/comments-feature.js +6 -0
  219. package/src/client/application/app-shell/git-feature.js +23 -5
  220. package/src/client/application/app-shell/presence-feature.js +8 -25
  221. package/src/client/application/app-shell/ui-feature-shell.js +172 -149
  222. package/src/client/application/app-shell/ui-feature-sidebar.js +43 -7
  223. package/src/client/application/app-shell/ui-feature-tab-activity.js +27 -9
  224. package/src/client/application/app-shell/ui-feature-toolbar.js +16 -129
  225. package/src/client/application/app-shell-elements.js +9 -0
  226. package/src/client/application/highlight-theme.js +16 -0
  227. package/src/client/application/preview-render-compiler.js +44 -107
  228. package/src/client/application/preview-render-executor.js +0 -26
  229. package/src/client/application/preview-render-scheduler.js +8 -24
  230. package/src/client/application/preview-renderer.js +26 -9
  231. package/src/client/application/webmcp-diagram-renderer.js +47 -0
  232. package/src/client/application/workspace-coordinator.js +23 -22
  233. package/src/client/application/workspace-route-controller.js +7 -0
  234. package/src/client/bootstrap/collabmd-app-shell.js +148 -35
  235. package/src/client/bootstrap/lazy-collab-clients.js +90 -0
  236. package/src/client/domain/excalidraw-element-link.js +73 -0
  237. package/src/client/domain/excalidraw-scene-reconcile.js +5 -2
  238. package/src/client/domain/excalidraw-scene.js +21 -0
  239. package/src/client/domain/hash-routes.js +13 -0
  240. package/src/client/domain/highlight-runtime.js +47 -0
  241. package/src/client/domain/lobby-chat.js +2 -0
  242. package/src/client/domain/room.js +1 -5
  243. package/src/client/domain/runtime-paths.js +61 -7
  244. package/src/client/domain/vault-utils.js +11 -0
  245. package/src/client/excalidraw-editor.js +155 -14
  246. package/src/client/export/export-host.js +3 -1
  247. package/src/client/export/export-pipeline.js +4 -17
  248. package/src/client/infrastructure/agent-connection-api-client.js +23 -0
  249. package/src/client/infrastructure/auth-client.js +4 -15
  250. package/src/client/infrastructure/browser-preferences-port.js +16 -0
  251. package/src/client/infrastructure/editor-session.js +11 -0
  252. package/src/client/infrastructure/editor-view-adapter.js +56 -8
  253. package/src/client/infrastructure/excalidraw-room-client.js +89 -2
  254. package/src/client/infrastructure/git-api-client.js +39 -33
  255. package/src/client/infrastructure/hosted-api-client.js +60 -0
  256. package/src/client/infrastructure/lobby-presence.js +4 -7
  257. package/src/client/infrastructure/runtime-config.js +14 -2
  258. package/src/client/infrastructure/tab-activity-lock.js +2 -5
  259. package/src/client/infrastructure/vault-api-client.js +33 -26
  260. package/src/client/infrastructure/webmcp-tool-registry.js +297 -0
  261. package/src/client/infrastructure/workspace-sync-client.js +6 -4
  262. package/src/client/presentation/agent-connection-controller.js +255 -0
  263. package/src/client/presentation/backlinks-panel.js +3 -0
  264. package/src/client/presentation/bases-preview-controller.js +27 -18
  265. package/src/client/presentation/comment-markdown-renderer.js +2 -14
  266. package/src/client/presentation/comment-overview-controller.js +1 -2
  267. package/src/client/presentation/comment-ui/comment-ui-card.js +4 -2
  268. package/src/client/presentation/comment-ui/comment-ui-shared.js +5 -2
  269. package/src/client/presentation/create-menu-presenter.js +19 -16
  270. package/src/client/presentation/excalidraw-embed-controller.js +164 -4
  271. package/src/client/presentation/file-explorer-controller.js +3 -0
  272. package/src/client/presentation/file-explorer-view.js +338 -182
  273. package/src/client/presentation/file-history-view-controller.js +13 -11
  274. package/src/client/presentation/git-diff-view-controller.js +35 -43
  275. package/src/client/presentation/git-panel-controller.js +78 -28
  276. package/src/client/presentation/hosted-workspace-gate-controller.js +180 -0
  277. package/src/client/presentation/image-lightbox-controller.js +20 -16
  278. package/src/client/presentation/layout-controller.js +13 -2
  279. package/src/client/presentation/quick-switcher-controller.js +20 -78
  280. package/src/client/presentation/quick-switcher-text-search.js +10 -14
  281. package/src/client/presentation/team-settings-controller.js +228 -0
  282. package/src/client/styles/components/navigation.css +1 -2
  283. package/src/client/styles/deferred-collab.css +5 -0
  284. package/src/client/styles/deferred-git.css +7 -0
  285. package/src/client/styles/deferred-preview.css +6 -0
  286. package/src/client/styles/features/agent-connection.css +202 -0
  287. package/src/client/styles/features/collaboration-chat.css +8 -1
  288. package/src/client/styles/features/collaboration-dialogs.css +16 -1
  289. package/src/client/styles/features/collaboration-presence.css +17 -4
  290. package/src/client/styles/features/diagram-preview.css +0 -15
  291. package/src/client/styles/features/diff-toolbar.css +1 -1
  292. package/src/client/styles/features/media-lightbox.css +12 -3
  293. package/src/client/styles/features/outline.css +4 -2
  294. package/src/client/styles/features/preview-markdown.css +25 -11
  295. package/src/client/styles/features/quick-switcher.css +20 -11
  296. package/src/client/styles/features/team-settings.css +162 -0
  297. package/src/client/styles/foundation/themes.css +2 -0
  298. package/src/client/styles/foundation/tokens.css +2 -2
  299. package/src/client/styles/layout/editor-page.css +25 -24
  300. package/src/client/styles/layout/overlays.css +16 -0
  301. package/src/client/styles/layout/responsive.css +7 -25
  302. package/src/client/styles/layout/shell.css +21 -1
  303. package/src/client/styles/layout/sidebar.css +99 -7
  304. package/src/client/styles/primitives/controls.css +21 -54
  305. package/src/client/styles/style.css +4 -19
  306. package/src/domain/agent-tool-definitions.js +872 -0
  307. package/src/domain/collabmd-content-capabilities.js +149 -0
  308. package/src/domain/collaboration-protocol.js +2 -0
  309. package/src/domain/comment-threads.js +3 -5
  310. package/src/domain/diagram-source.js +50 -0
  311. package/src/domain/editable-content-revision.js +10 -0
  312. package/src/domain/editable-text.js +3 -0
  313. package/src/domain/exact-text-edits.js +69 -0
  314. package/src/domain/excalidraw-agent-scene.js +624 -0
  315. package/src/domain/excalidraw-agent-verification.js +554 -0
  316. package/src/domain/excalidraw-room-codec.js +13 -6
  317. package/src/domain/literal-text-search.js +13 -0
  318. package/src/domain/video-embed.js +76 -0
  319. package/src/server/application/agent-connection-service.js +178 -0
  320. package/src/server/application/agent-content-service.js +841 -0
  321. package/src/server/application/workspace-reconciliation.js +5 -7
  322. package/src/server/config/env.js +147 -6
  323. package/src/server/create-app-server.js +47 -141
  324. package/src/server/domain/bases/base-query-service.js +1 -5
  325. package/src/server/domain/collaboration/collaboration-room.js +121 -25
  326. package/src/server/domain/collaboration/protocol.js +4 -0
  327. package/src/server/domain/hosted-workspace.js +31 -1
  328. package/src/server/domain/markdown-reference-extractor.js +15 -1
  329. package/src/server/domain/ripgrep-search-service.js +68 -21
  330. package/src/server/infrastructure/git/git-service.js +19 -1
  331. package/src/server/infrastructure/git/history-service.js +1 -1
  332. package/src/server/infrastructure/git/local-exclude.js +37 -0
  333. package/src/server/infrastructure/git/parsers.js +19 -17
  334. package/src/server/infrastructure/git/path-utils.js +0 -16
  335. package/src/server/infrastructure/git/status-service.js +1 -1
  336. package/src/server/infrastructure/git/untracked-files.js +12 -21
  337. package/src/server/infrastructure/http/create-agent-api-handler.js +171 -0
  338. package/src/server/infrastructure/http/create-git-api-command-handler.js +32 -0
  339. package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -0
  340. package/src/server/infrastructure/http/create-request-handler.js +123 -26
  341. package/src/server/infrastructure/http/create-static-handler.js +9 -0
  342. package/src/server/infrastructure/http/create-vault-api-query-handler.js +15 -2
  343. package/src/server/infrastructure/mcp/create-agent-mcp-handler.js +200 -0
  344. package/src/server/infrastructure/persistence/agent-connection-store.js +120 -0
  345. package/src/server/infrastructure/persistence/pull-backup-store.js +2 -27
  346. package/src/server/infrastructure/persistence/sidecar-store.js +12 -5
  347. package/src/server/infrastructure/persistence/vault-file-store.js +11 -5
  348. package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +48 -22
  349. package/src/server/shared/agent-tool-image.js +22 -0
  350. package/src/server/shared/agent-tool-rate-limiter.js +27 -0
  351. package/src/server/startup/git-remote-bootstrap.js +58 -79
  352. package/src/server/vault-registry.js +251 -0
  353. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js +0 -1
  354. package/dist/client/assets/abnfDiagram-VCTEODGH-BNDLzJ7L.js +0 -1
  355. package/dist/client/assets/ar-SA-PQUY64WN-xjXgbW6d.js +0 -10
  356. package/dist/client/assets/az-AZ-OXJXL76K-4JkO4Pca.js +0 -1
  357. package/dist/client/assets/base-CaIEJUF9.css +0 -1
  358. package/dist/client/assets/bg-BG-W2GKIJDF-DnkH_o81.js +0 -5
  359. package/dist/client/assets/bn-BD-TGL7M4PJ-CG4JkmtP.js +0 -3
  360. package/dist/client/assets/bn-IN-BKETKYEH-CG4JkmtP.js +0 -3
  361. package/dist/client/assets/browser-utils--H_DkyEF.js +0 -1
  362. package/dist/client/assets/ca-ES-LD5SCRVV-U6_TVMX9.js +0 -8
  363. package/dist/client/assets/channel-CaoKA_We.js +0 -1
  364. package/dist/client/assets/chunk-7XWMRXBY-CfMzEq80.js +0 -1
  365. package/dist/client/assets/chunk-CKBBP62Z-DG26UiBv.js +0 -2
  366. package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +0 -2
  367. package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +0 -127
  368. package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +0 -10
  369. package/dist/client/assets/chunk-RM4UPSZO-CWRwxNWJ.js +0 -41
  370. package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +0 -1
  371. package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +0 -1
  372. package/dist/client/assets/comment-thread-store-CdcwrObc.js +0 -1
  373. package/dist/client/assets/comment-threads-9J6Em-_y.js +0 -4
  374. package/dist/client/assets/comment-ui-shared-DuoyznXW.js +0 -7
  375. package/dist/client/assets/cs-CZ-OFPU5DBV-BmFAIhqX.js +0 -7
  376. package/dist/client/assets/da-DK-FRDJFYWF-H387Jw8B.js +0 -2
  377. package/dist/client/assets/de-CH-ZG7H3QK3-C_groygo.js +0 -11
  378. package/dist/client/assets/de-DE-SIJYH4IH-C_groygo.js +0 -11
  379. package/dist/client/assets/diagram-VSXAHHWV-CQRVEZR7.js +0 -3
  380. package/dist/client/assets/dist-73RPdcyU.js +0 -1
  381. package/dist/client/assets/dist-BJ1bJs33.js +0 -1
  382. package/dist/client/assets/dist-ByrG2qBA.js +0 -1
  383. package/dist/client/assets/dist-CH-sQu3r.js +0 -1
  384. package/dist/client/assets/dist-CKS_-are.js +0 -1
  385. package/dist/client/assets/dist-D37Hyu3h.js +0 -9
  386. package/dist/client/assets/dist-DZAAWTG-.js +0 -1
  387. package/dist/client/assets/dist-Dir5dDKZ.js +0 -1
  388. package/dist/client/assets/dist-Dl_tpDSr.js +0 -1
  389. package/dist/client/assets/dist-DutPuFmC.js +0 -1
  390. package/dist/client/assets/dist-RKBTaQMb.js +0 -13
  391. package/dist/client/assets/dist-eBx8q6Sy.js +0 -1
  392. package/dist/client/assets/drawio-editor-BVaNNtYp.js +0 -9
  393. package/dist/client/assets/drawioEditor-BkIBlXx0.js +0 -2
  394. package/dist/client/assets/ebnfDiagram-PWID7BFC-OXa8VEp1.js +0 -1
  395. package/dist/client/assets/editor-session-DMyVdHLj.js +0 -54
  396. package/dist/client/assets/el-GR-IEE2CGI2-BkT6YT54.js +0 -7
  397. package/dist/client/assets/embedded-editor-base-B3l6Xy65.css +0 -1
  398. package/dist/client/assets/es-ES-TVVPWKV5-CpPKJXTM.js +0 -12
  399. package/dist/client/assets/eu-ES-CGBMFQDT-Bu3N2493.js +0 -8
  400. package/dist/client/assets/excalidraw-editor-BjYaNEMY.js +0 -9
  401. package/dist/client/assets/excalidraw-mermaid-stub-BNckbX2n.js +0 -1
  402. package/dist/client/assets/excalidraw-mermaid-stub-DE5FTiZB.js +0 -1
  403. package/dist/client/assets/excalidrawEditor-ChqF_d82.js +0 -2
  404. package/dist/client/assets/export-page-Dyu0XCbu.js +0 -57
  405. package/dist/client/assets/exportDocument-CJBx4Xjx.css +0 -1
  406. package/dist/client/assets/exportDocument-Dgvfa2Sd.js +0 -2
  407. package/dist/client/assets/fa-IR-IE6XAPR4-BEvLCORD.js +0 -9
  408. package/dist/client/assets/fi-FI-P7TKNHRM-DI0q8iSX.js +0 -6
  409. package/dist/client/assets/file-icon-svg-Y_kpF957.js +0 -1
  410. package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +0 -1
  411. package/dist/client/assets/fr-FR-QI2XZNT7-y8kXd8LA.js +0 -12
  412. package/dist/client/assets/gl-ES-TLYCNOZZ-Br-Fhff-.js +0 -6
  413. package/dist/client/assets/he-IL-ZX43XLGP-qKQq6V9X.js +0 -9
  414. package/dist/client/assets/hi-IN-UTYRMTUF-DOUcwrDO.js +0 -3
  415. package/dist/client/assets/hu-HU-AJOSEBW6-FqTyvHlD.js +0 -3
  416. package/dist/client/assets/id-ID-ETLTVG6C-CQqh3CLS.js +0 -8
  417. package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +0 -1
  418. package/dist/client/assets/index-CSNIMyOP.css +0 -1
  419. package/dist/client/assets/index-DG3N2Ps-.js +0 -2
  420. package/dist/client/assets/it-IT-B4B6TP6L-V-yK3SZz.js +0 -12
  421. package/dist/client/assets/ja-JP-IYKVURR5-BQKBXRpX.js +0 -12
  422. package/dist/client/assets/kaa-SE2BUIKX-CZ5kfwPg.js +0 -1
  423. package/dist/client/assets/kab-KAB-Y3GLKXLR-Do7GWfuN.js +0 -4
  424. package/dist/client/assets/kk-KZ-ABWUFVOH-BpqVciQz.js +0 -1
  425. package/dist/client/assets/ko-KR-7JQDXKGM-N42lep78.js +0 -5
  426. package/dist/client/assets/ku-TR-NAH2Q5B7-K8LLl9fk.js +0 -6
  427. package/dist/client/assets/lt-LT-VQFYRSNQ-BmOd0ALn.js +0 -3
  428. package/dist/client/assets/lv-LV-T62VSYUM-B22WdPhp.js +0 -4
  429. package/dist/client/assets/main-D0wCxpVn.js +0 -903
  430. package/dist/client/assets/mermaid-parser.core-Bl0efOMt.js +0 -4
  431. package/dist/client/assets/mermaid.core-BJRLUQZE.js +0 -11
  432. package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +0 -1
  433. package/dist/client/assets/mr-IN-V4FHLCJE-XX069tpm.js +0 -9
  434. package/dist/client/assets/my-MM-E3SQ6E54-cst_-5SB.js +0 -1
  435. package/dist/client/assets/nb-NO-MLNOFN5H-Bu2URWko.js +0 -8
  436. package/dist/client/assets/nl-NL-D5L3ZV4M-BqrV0btt.js +0 -13
  437. package/dist/client/assets/nn-NO-NNHDGPKB-DK-xZaWM.js +0 -4
  438. package/dist/client/assets/oc-FR-DWCRF55G-BZ5Po5R6.js +0 -4
  439. package/dist/client/assets/pa-IN-3JSAY44M-BZQSjKrS.js +0 -4
  440. package/dist/client/assets/pegDiagram-XKGWAZYB-B31fKPR2.js +0 -1
  441. package/dist/client/assets/percentages-ETZPVQEE-DFxFqXgH.js +0 -1
  442. package/dist/client/assets/pl-PL-ACURYKP3-qcEOSfCk.js +0 -12
  443. package/dist/client/assets/preload-helper-HclGiUj8.js +0 -1
  444. package/dist/client/assets/preview-render-compiler-CrJIooVD.js +0 -35
  445. package/dist/client/assets/preview-render-compiler-O0JxBVNF.js +0 -1
  446. package/dist/client/assets/preview-render-profile-B4RWYWHt.js +0 -1
  447. package/dist/client/assets/preview-render-worker-_QTxqKvP.js +0 -60
  448. package/dist/client/assets/prod-BiYPMR1i.js +0 -177
  449. package/dist/client/assets/prod-VxdGZ5Ly.js +0 -1
  450. package/dist/client/assets/pt-BR-LOX7MLGD-DLueHSyZ.js +0 -10
  451. package/dist/client/assets/pt-PT-CZ2U2RFQ-BJ-GAEm6.js +0 -12
  452. package/dist/client/assets/quick-switcher-controller-CaEjEtq_.js +0 -1
  453. package/dist/client/assets/railroadDiagram-O6MQD6OU-BPifP0MB.js +0 -1
  454. package/dist/client/assets/ro-RO-2HECL2X6-CJUvKAf0.js +0 -12
  455. package/dist/client/assets/ru-RU-HAYNXO46-BWSlvTrt.js +0 -10
  456. package/dist/client/assets/runtime-config-BLrEKVO1.js +0 -1
  457. package/dist/client/assets/si-LK-W5KNS4H6-DGGCsn7k.js +0 -1
  458. package/dist/client/assets/sk-SK-7K2CFGDV-CY4uTYgQ.js +0 -7
  459. package/dist/client/assets/sl-SI-OXV2QZWW-2-weqaBY.js +0 -6
  460. package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +0 -1
  461. package/dist/client/assets/sv-SE-JTOBZRGL-9-IUtVkO.js +0 -12
  462. package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +0 -8
  463. package/dist/client/assets/ta-IN-KFAVKXGT-gHO6Q_DH.js +0 -6
  464. package/dist/client/assets/th-TH-VDMSCPDL-BvJuw6PJ.js +0 -1
  465. package/dist/client/assets/tr-TR-CEZ6GX45-CG6UU3Su.js +0 -4
  466. package/dist/client/assets/uk-UA-Q3H3OXQC-CSuIg_DY.js +0 -6
  467. package/dist/client/assets/uz-UZ-NGCSWWPX-mom7rxSP.js +0 -1
  468. package/dist/client/assets/vault-api-client-BkwdFjx0.js +0 -6
  469. package/dist/client/assets/vault-utils-DvoSftJT.js +0 -22
  470. package/dist/client/assets/vi-VN-P3NDEVPS-BB0Fu9ck.js +0 -7
  471. package/dist/client/assets/yjs-provider-reset-guard-DE0vINDP.js +0 -4
  472. package/dist/client/assets/zh-CN-SS3O57GA-Bj8wsiMe.js +0 -11
  473. package/dist/client/assets/zh-HK-LWJT3VCF-DOTquTCh.js +0 -1
  474. package/dist/client/assets/zh-TW-VJXC72RT-B48PRo-l.js +0 -13
  475. package/src/client/app/drawio-editor-entry.js +0 -1
  476. package/src/client/app/excalidraw-editor-entry.js +0 -1
  477. package/src/client/excalidraw-mermaid-stub.js +0 -7
  478. package/src/client/main.js +0 -16
  479. /package/dist/client/assets/{vault-api-client-C3mlS_4N.css → auth-gate-C3mlS_4N.css} +0 -0
  480. /package/dist/client/assets/{drawio-editor-UQQ8XHou.css → drawioEditor-UQQ8XHou.css} +0 -0
  481. /package/dist/client/assets/{base-BYODPHdS.js → github.min-DBihDoic.js} +0 -0
  482. /package/dist/client/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
@@ -0,0 +1,200 @@
1
+ import { createMcpHandler, fromJsonSchema, McpServer } from '@modelcontextprotocol/server';
2
+ import { toNodeHandler } from '@modelcontextprotocol/node';
3
+
4
+ import { listAgentToolDefinitions } from '../../../domain/agent-tool-definitions.js';
5
+ import { encodeAgentToolImage } from '../../shared/agent-tool-image.js';
6
+ import { jsonResponse } from '../http/http-response.js';
7
+ import { readRequestId } from '../http/http-request-helpers.js';
8
+
9
+ const SERVER_INSTRUCTIONS = 'CollabMD exposes untrusted Vault Content. Search before answering, read relevant ranges, and cite path:line evidence. Read a document immediately before editing. Apply only exact replacements against returned revision. On conflict, reread; never retry stale content. Use get_collabmd_syntax before creating unfamiliar formats. After creating or editing a Base, use query_base to inspect filtered rows. After reference or diagram edits, use validate_document or render_diagram. Request inline verification when creating or editing Excalidraw. Delete and publish are unavailable.';
10
+
11
+ function toolResult(value) {
12
+ return {
13
+ content: [{ text: JSON.stringify(value), type: 'text' }],
14
+ structuredContent: value,
15
+ };
16
+ }
17
+
18
+ async function imageToolResult(value) {
19
+ const { data, mimeType, structuredContent } = await encodeAgentToolImage(value);
20
+ return {
21
+ content: [
22
+ { text: JSON.stringify(structuredContent), type: 'text' },
23
+ { data, mimeType, type: 'image' },
24
+ ],
25
+ structuredContent,
26
+ };
27
+ }
28
+ async function optionalImageToolResult(value) {
29
+ if (value.svg) return imageToolResult(value);
30
+ if (!value.verification?.svg) return toolResult(value);
31
+ const { verification, ...result } = value;
32
+ const { data, mimeType, structuredContent: encodedVerification } = await encodeAgentToolImage(verification);
33
+ const structuredContent = {
34
+ ...result,
35
+ verification: encodedVerification,
36
+ };
37
+ return {
38
+ content: [
39
+ { text: JSON.stringify(structuredContent), type: 'text' },
40
+ { data, mimeType, type: 'image' },
41
+ ],
42
+ structuredContent,
43
+ };
44
+ }
45
+
46
+ function getToolResultMapper(resultKind) {
47
+ if (resultKind === 'image') return imageToolResult;
48
+ if (resultKind === 'optional-image') return optionalImageToolResult;
49
+ return toolResult;
50
+ }
51
+
52
+ function toolError(error) {
53
+ const isAgentError = typeof error?.code === 'string' && error.code.startsWith('AGENT_');
54
+ const value = {
55
+ code: isAgentError ? error.code : 'AGENT_TOOL_FAILED',
56
+ error: isAgentError ? error.message : 'Agent tool failed',
57
+ };
58
+ if (isAgentError && Number.isFinite(error?.retryAfterMs)) {
59
+ value.retryAfterMs = error.retryAfterMs;
60
+ }
61
+ return {
62
+ content: [{ text: JSON.stringify(value), type: 'text' }],
63
+ isError: true,
64
+ structuredContent: value,
65
+ };
66
+ }
67
+
68
+ function registerTool(server, name, config, handler, {
69
+ actor,
70
+ rateLimiter,
71
+ resultMapper = toolResult,
72
+ }) {
73
+ server.registerTool(name, config, async (input, context) => {
74
+ try {
75
+ rateLimiter(actor.rateLimitKey);
76
+ return await resultMapper(await handler(input, context));
77
+ } catch (error) {
78
+ if (typeof error?.code !== 'string' || !error.code.startsWith('AGENT_')) {
79
+ console.error(`[mcp] ${name} failed (${actor.requestId}):`, error?.message || 'Unknown error');
80
+ }
81
+ return toolError(error);
82
+ }
83
+ });
84
+ }
85
+
86
+ function buildAgentServer({ actor, agentContentService, rateLimiter, version }) {
87
+ const server = new McpServer(
88
+ { name: 'collabmd', version },
89
+ { instructions: SERVER_INSTRUCTIONS },
90
+ );
91
+ for (const definition of listAgentToolDefinitions(actor.scopes)) {
92
+ registerTool(server, definition.name, {
93
+ annotations: definition.annotations,
94
+ description: definition.description,
95
+ inputSchema: fromJsonSchema(definition.inputSchema),
96
+ outputSchema: fromJsonSchema(definition.outputSchema),
97
+ }, (input, context) => agentContentService[definition.method](actor, {
98
+ ...input,
99
+ signal: context.signal,
100
+ }), {
101
+ actor,
102
+ rateLimiter,
103
+ resultMapper: getToolResultMapper(definition.resultKind),
104
+ });
105
+ }
106
+ return server;
107
+ }
108
+
109
+ function readHttpHostname(value) {
110
+ try {
111
+ const url = new URL(value);
112
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') return '';
113
+ return url.hostname.replace(/^\[|\]$/gu, '').toLowerCase();
114
+ } catch {
115
+ return '';
116
+ }
117
+ }
118
+
119
+ function readRequestHostname(req) {
120
+ return readHttpHostname(`http://${String(req.headers.host || '')}`);
121
+ }
122
+
123
+ export function createAgentMcpHandler({
124
+ agentConnectionService,
125
+ agentContentService,
126
+ config,
127
+ rateLimiter,
128
+ }) {
129
+ const mcpHandler = createMcpHandler(({ authInfo }) => buildAgentServer({
130
+ actor: authInfo.extra.actor,
131
+ agentContentService,
132
+ rateLimiter,
133
+ version: config.build?.version || '0.1.0',
134
+ }));
135
+ const nodeHandler = toNodeHandler(mcpHandler, {
136
+ onerror: (error) => console.error('[mcp] Transport failed:', error.message),
137
+ });
138
+
139
+ return async function handleAgentMcp(req, res, requestUrl) {
140
+ if (requestUrl.pathname !== '/mcp') return false;
141
+ const authRequired = config.auth.strategy !== 'none';
142
+ const allowedHosts = config.agentAccess.allowedHosts;
143
+ const hostname = readRequestHostname(req);
144
+ const hasOrigin = Boolean(req.headers.origin);
145
+ const originHostname = hasOrigin ? readHttpHostname(String(req.headers.origin)) : '';
146
+ const browserOriginAllowed = hasOrigin
147
+ && hostname
148
+ && originHostname === hostname
149
+ && allowedHosts.includes(hostname);
150
+ if (
151
+ (authRequired && (!hostname || !allowedHosts.includes(hostname)))
152
+ || (hasOrigin && !browserOriginAllowed)
153
+ ) {
154
+ jsonResponse(req, res, 403, { error: 'MCP request origin or host is not allowed' });
155
+ return true;
156
+ }
157
+
158
+ let actor;
159
+ let token = '';
160
+ if (authRequired) {
161
+ const authorization = String(req.headers.authorization || '');
162
+ const match = authorization.match(/^Bearer\s+(.+)$/iu);
163
+ if (!match) {
164
+ res.setHeader('WWW-Authenticate', 'Bearer scope="vault:read"');
165
+ jsonResponse(req, res, 401, { error: 'Agent Connection token is required' });
166
+ return true;
167
+ }
168
+ token = match[1];
169
+ try {
170
+ actor = await agentConnectionService.authenticateToken(token);
171
+ } catch (error) {
172
+ res.setHeader('WWW-Authenticate', 'Bearer scope="vault:read"');
173
+ jsonResponse(req, res, Number(error?.statusCode) || 401, {
174
+ code: error?.code || 'AGENT_TOKEN_INVALID',
175
+ error: error?.message || 'Agent Connection token is invalid',
176
+ });
177
+ return true;
178
+ }
179
+ } else {
180
+ actor = {
181
+ collaborator: null,
182
+ connectionId: 'anonymous',
183
+ scopes: ['vault:edit', 'vault:read'],
184
+ };
185
+ }
186
+
187
+ actor.requestId = readRequestId(req);
188
+ actor.rateLimitKey = actor.connectionId === 'anonymous'
189
+ ? `anonymous:${req.socket?.remoteAddress || 'unknown'}`
190
+ : actor.connectionId;
191
+ req.auth = {
192
+ clientId: actor.connectionId,
193
+ extra: { actor },
194
+ scopes: actor.scopes,
195
+ token,
196
+ };
197
+ await nodeHandler(req, res);
198
+ return true;
199
+ };
200
+ }
@@ -0,0 +1,120 @@
1
+ import { mkdir } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+
4
+ function parseScopes(value) {
5
+ try {
6
+ const scopes = JSON.parse(value || '[]');
7
+ return Array.isArray(scopes) ? scopes : [];
8
+ } catch {
9
+ return [];
10
+ }
11
+ }
12
+
13
+ function rowToConnection(row) {
14
+ if (!row) return null;
15
+ return {
16
+ clientKind: row.client_kind,
17
+ createdAt: row.created_at,
18
+ expiresAt: row.expires_at,
19
+ id: row.id,
20
+ label: row.label,
21
+ revokedAt: row.revoked_at,
22
+ scopes: parseScopes(row.scopes_json),
23
+ subjectEmail: row.subject_email,
24
+ subjectId: row.subject_id,
25
+ subjectType: row.subject_type,
26
+ tokenHash: row.token_hash,
27
+ };
28
+ }
29
+
30
+ export class AgentConnectionStore {
31
+ constructor({ dbPath }) {
32
+ this.dbPath = dbPath;
33
+ this.db = null;
34
+ this.statements = new Map();
35
+ }
36
+
37
+ async initialize() {
38
+ if (this.db) return;
39
+ await mkdir(dirname(this.dbPath), { recursive: true });
40
+ const { DatabaseSync } = await import('node:sqlite');
41
+ this.db = new DatabaseSync(this.dbPath);
42
+ this.db.exec('PRAGMA journal_mode = WAL');
43
+ this.db.exec(`
44
+ CREATE TABLE IF NOT EXISTS agent_connections (
45
+ id TEXT PRIMARY KEY,
46
+ subject_type TEXT NOT NULL,
47
+ subject_id TEXT NOT NULL,
48
+ subject_email TEXT NOT NULL DEFAULT '',
49
+ label TEXT NOT NULL,
50
+ client_kind TEXT NOT NULL,
51
+ scopes_json TEXT NOT NULL,
52
+ token_hash TEXT NOT NULL UNIQUE,
53
+ created_at INTEGER NOT NULL,
54
+ expires_at INTEGER NOT NULL,
55
+ revoked_at INTEGER
56
+ );
57
+ CREATE INDEX IF NOT EXISTS agent_connections_subject_idx
58
+ ON agent_connections(subject_type, subject_id, created_at DESC);
59
+ `);
60
+ }
61
+
62
+ prepare(key, sql) {
63
+ if (!this.statements.has(key)) this.statements.set(key, this.db.prepare(sql));
64
+ return this.statements.get(key);
65
+ }
66
+
67
+ async close() {
68
+ this.statements.clear();
69
+ this.db?.close();
70
+ this.db = null;
71
+ }
72
+
73
+ async create(connection) {
74
+ this.prepare(
75
+ 'create',
76
+ `INSERT INTO agent_connections (
77
+ id, subject_type, subject_id, subject_email, label, client_kind,
78
+ scopes_json, token_hash, created_at, expires_at, revoked_at
79
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)`,
80
+ ).run(
81
+ connection.id,
82
+ connection.subjectType,
83
+ connection.subjectId,
84
+ connection.subjectEmail,
85
+ connection.label,
86
+ connection.clientKind,
87
+ JSON.stringify(connection.scopes),
88
+ connection.tokenHash,
89
+ connection.createdAt,
90
+ connection.expiresAt,
91
+ );
92
+ return connection;
93
+ }
94
+
95
+ async getByTokenHash(tokenHash) {
96
+ return rowToConnection(this.prepare(
97
+ 'getByTokenHash',
98
+ 'SELECT * FROM agent_connections WHERE token_hash = ? LIMIT 1',
99
+ ).get(tokenHash));
100
+ }
101
+
102
+ async listBySubject(subjectType, subjectId) {
103
+ return this.prepare(
104
+ 'listBySubject',
105
+ `SELECT * FROM agent_connections
106
+ WHERE subject_type = ? AND subject_id = ? AND revoked_at IS NULL
107
+ ORDER BY created_at DESC`,
108
+ ).all(subjectType, subjectId).map(rowToConnection);
109
+ }
110
+
111
+ async revoke(id, subjectType, subjectId, revokedAt) {
112
+ const result = this.prepare(
113
+ 'revoke',
114
+ `UPDATE agent_connections SET revoked_at = ?
115
+ WHERE id = ? AND subject_type = ? AND subject_id = ? AND revoked_at IS NULL`,
116
+ ).run(revokedAt, id, subjectType, subjectId);
117
+ return Number(result.changes) > 0;
118
+ }
119
+
120
+ }
@@ -1,6 +1,7 @@
1
1
  import { copyFile, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
 
4
+ import { ensureCollabMetadataGitExclude } from '../git/local-exclude.js';
4
5
  import { sanitizeVaultPath } from './path-utils.js';
5
6
 
6
7
  const PULL_BACKUP_STORAGE_ROOT = '.collabmd/pull-backups';
@@ -98,32 +99,6 @@ function formatSummary({
98
99
  ].join('\n');
99
100
  }
100
101
 
101
- async function ensureLocalGitExclude(vaultDir) {
102
- const excludePath = resolve(vaultDir, '.git/info/exclude');
103
- let existingContent = '';
104
-
105
- try {
106
- existingContent = await readFile(excludePath, 'utf8');
107
- } catch (error) {
108
- if (error?.code !== 'ENOENT') {
109
- throw error;
110
- }
111
- }
112
-
113
- const lines = existingContent
114
- .split(/\r?\n/u)
115
- .map((line) => line.trim())
116
- .filter(Boolean);
117
- if (lines.includes('.collabmd') || lines.includes('.collabmd/')) {
118
- return;
119
- }
120
-
121
- const prefix = existingContent.length > 0 && !existingContent.endsWith('\n')
122
- ? '\n'
123
- : '';
124
- await writeFile(excludePath, `${existingContent}${prefix}.collabmd/\n`, 'utf8');
125
- }
126
-
127
102
  export class PullBackupStore {
128
103
  constructor({ vaultDir }) {
129
104
  this.vaultDir = resolve(vaultDir);
@@ -148,7 +123,7 @@ export class PullBackupStore {
148
123
  headRef = null,
149
124
  targetRef = null,
150
125
  } = {}) {
151
- await ensureLocalGitExclude(this.vaultDir);
126
+ await ensureCollabMetadataGitExclude(this.vaultDir);
152
127
 
153
128
  const backupId = createBackupId(headRef, createdAt);
154
129
  const backupDir = this.getBackupPath(backupId);
@@ -2,9 +2,11 @@ import { dirname, join, resolve } from 'path';
2
2
  import { mkdir, readFile, readdir, rename, rm, stat, writeFile } from 'fs/promises';
3
3
 
4
4
  import { resolveVaultFilePath, toVaultRelativePath } from './path-utils.js';
5
+ import { mapWithConcurrency } from '../../shared/async-utils.js';
5
6
 
6
7
  const COMMENT_STORAGE_ROOT = '.collabmd/comments';
7
8
  const YJS_SNAPSHOT_STORAGE_ROOT = '.collabmd/yjs';
9
+ const COMMENT_READ_CONCURRENCY = 8;
8
10
 
9
11
  function resolveSidecarPath(vaultDir, filePath, storageRoot, extension) {
10
12
  const { absolute: absoluteVaultPath } = resolveVaultFilePath(vaultDir, filePath);
@@ -75,7 +77,7 @@ export class SidecarStore {
75
77
  async listCommentThreadEntries({ filePaths = null } = {}) {
76
78
  const allowedPaths = filePaths ? new Set(filePaths) : null;
77
79
  const rootPath = this.getCommentStorageRootPath();
78
- const entries = [];
80
+ const commentFilePaths = [];
79
81
 
80
82
  const visitDirectory = async (absoluteDirectoryPath, relativeDirectoryPath = '') => {
81
83
  let dirEntries;
@@ -108,14 +110,19 @@ export class SidecarStore {
108
110
  continue;
109
111
  }
110
112
 
111
- const threads = await this.readCommentThreads(filePath);
112
- if (threads.length > 0) {
113
- entries.push({ filePath, threads });
114
- }
113
+ commentFilePaths.push(filePath);
115
114
  }
116
115
  };
117
116
 
118
117
  await visitDirectory(rootPath);
118
+ const entries = (await mapWithConcurrency(
119
+ commentFilePaths,
120
+ COMMENT_READ_CONCURRENCY,
121
+ async (filePath) => {
122
+ const threads = await this.readCommentThreads(filePath);
123
+ return threads.length > 0 ? { filePath, threads } : null;
124
+ },
125
+ )).filter(Boolean);
119
126
  return entries.sort((left, right) => left.filePath.localeCompare(right.filePath, undefined, { sensitivity: 'base' }));
120
127
  }
121
128
 
@@ -1,5 +1,5 @@
1
1
  import { createReadStream } from 'fs';
2
- import { mkdir, readFile, readdir, rename, rm, rmdir, stat, writeFile } from 'fs/promises';
2
+ import { copyFile, mkdir, readFile, readdir, rename, rm, rmdir, stat, writeFile } from 'fs/promises';
3
3
  import { basename, dirname, extname, join, relative, resolve } from 'path';
4
4
  import sharp from 'sharp';
5
5
 
@@ -708,7 +708,11 @@ export class VaultFileStore {
708
708
  : null;
709
709
 
710
710
  if (backupPath) {
711
- await rename(operation.targetPath, backupPath);
711
+ if (operation.kind === 'write') {
712
+ await copyFile(operation.targetPath, backupPath);
713
+ } else {
714
+ await rename(operation.targetPath, backupPath);
715
+ }
712
716
  }
713
717
 
714
718
  try {
@@ -721,6 +725,9 @@ export class VaultFileStore {
721
725
  }
722
726
  } catch (error) {
723
727
  if (backupPath) {
728
+ if (operation.kind === 'write') {
729
+ await rm(operation.targetPath, { force: true });
730
+ }
724
731
  await rename(backupPath, operation.targetPath);
725
732
  }
726
733
  throw error;
@@ -757,9 +764,8 @@ export class VaultFileStore {
757
764
  return this.sidecarStore.readCommentThreads(filePath);
758
765
  }
759
766
 
760
- async readCommentOverview() {
761
- const snapshot = await this.scanWorkspaceState();
762
- const commentSupportedFilePaths = snapshot.filePaths.filter((filePath) => (
767
+ async readCommentOverview({ filePaths }) {
768
+ const commentSupportedFilePaths = filePaths.filter((filePath) => (
763
769
  supportsCommentsForFilePath(filePath)
764
770
  ));
765
771
  const entries = await this.sidecarStore.listCommentThreadEntries({
@@ -24,9 +24,22 @@ function rejectUpgrade(socket, statusCode, statusMessage, {
24
24
  socket.destroy();
25
25
  }
26
26
 
27
- function extractRoomName(pathname, wsBasePath) {
28
- const roomSegment = pathname.slice(wsBasePath.length + 1);
29
- return decodeURIComponent(roomSegment || 'default');
27
+ // ponytail: /ws/v/:knownId/:room scopes to a vault; anything else stays a legacy primary room.
28
+ // A primary-vault file literally at v/<vaultId>/... is shadowed by design.
29
+ function extractVaultAndRoom(pathname, wsBasePath, isKnownVaultId) {
30
+ const rest = pathname.slice(wsBasePath.length + 1);
31
+ if (rest === 'v' || rest.startsWith('v/')) {
32
+ const after = rest === 'v' ? '' : rest.slice('v/'.length);
33
+ const slashIndex = after.indexOf('/');
34
+ if (slashIndex > 0) {
35
+ const candidate = after.slice(0, slashIndex);
36
+ const roomPart = after.slice(slashIndex + 1);
37
+ if (roomPart && isKnownVaultId?.(candidate)) {
38
+ return { roomName: decodeURIComponent(roomPart) || 'default', vaultId: candidate };
39
+ }
40
+ }
41
+ }
42
+ return { roomName: decodeURIComponent(rest || 'default'), vaultId: null };
30
43
  }
31
44
 
32
45
  export function attachCollaborationGateway({
@@ -37,6 +50,7 @@ export function attachCollaborationGateway({
37
50
  httpServer,
38
51
  maxPayload,
39
52
  roomRegistry,
53
+ vaultRegistry = null,
40
54
  wsBasePath,
41
55
  }) {
42
56
  const websocketServer = new WebSocketServer({
@@ -99,26 +113,38 @@ export function attachCollaborationGateway({
99
113
  }) ?? (() => {});
100
114
 
101
115
  websocketServer.on('connection', (ws, req, requestUrl, user = null) => {
102
- const roomName = extractRoomName(requestUrl.pathname, wsBasePath);
103
- const room = roomRegistry.getOrCreate(roomName);
104
- const session = new ClientSocketSession({
105
- onDisconnected: (disconnectedRoomName) => {
106
- socketSessions.delete(ws);
107
- const remaining = roomRegistry.rooms.get(disconnectedRoomName)?.clients.size ?? 0;
108
- console.log(`[ws] "${disconnectedRoomName}" disconnected (${remaining} active client(s))`);
109
- },
110
- onFailed: () => {
111
- socketSessions.delete(ws);
112
- },
113
- room,
114
- roomName,
115
- ws,
116
- });
117
- socketSessions.set(ws, {
118
- session,
119
- userEmail: normalizeHostedEmail(user?.email),
116
+ const { roomName, vaultId } = extractVaultAndRoom(requestUrl.pathname, wsBasePath, vaultRegistry?.isKnownVaultId?.bind(vaultRegistry));
117
+ const registryPromise = vaultId && vaultRegistry
118
+ ? vaultRegistry.getOrCreateContextAsync(vaultId).then((context) => context.roomRegistry)
119
+ : Promise.resolve(roomRegistry);
120
+ registryPromise.then((targetRegistry) => {
121
+ const room = targetRegistry.getOrCreate(roomName);
122
+ const session = new ClientSocketSession({
123
+ onDisconnected: (disconnectedRoomName) => {
124
+ socketSessions.delete(ws);
125
+ const remaining = targetRegistry.rooms.get(disconnectedRoomName)?.clients.size ?? 0;
126
+ console.log(`[ws] "${disconnectedRoomName}" disconnected (${remaining} active client(s))`);
127
+ },
128
+ onFailed: () => {
129
+ socketSessions.delete(ws);
130
+ },
131
+ room,
132
+ roomName,
133
+ ws,
134
+ });
135
+ socketSessions.set(ws, {
136
+ session,
137
+ userEmail: normalizeHostedEmail(user?.email),
138
+ });
139
+ void session.initialize();
140
+ }).catch((error) => {
141
+ console.error(`[ws] Failed to open room "${roomName}":`, error.message);
142
+ try {
143
+ ws.close(1011, 'Vault unavailable');
144
+ } catch {
145
+ try { ws.terminate(); } catch { /* ignore */ }
146
+ }
120
147
  });
121
- void session.initialize();
122
148
  });
123
149
 
124
150
  httpServer.on('upgrade', (req, socket, head) => {
@@ -0,0 +1,22 @@
1
+ import sharp from 'sharp';
2
+
3
+ export async function encodeAgentToolImage(value) {
4
+ const { format, svg } = value;
5
+ const metadata = { ...value };
6
+ delete metadata.format;
7
+ delete metadata.scene;
8
+ delete metadata.svg;
9
+ const mimeType = format === 'svg' ? 'image/svg+xml' : 'image/png';
10
+ const image = format === 'svg'
11
+ ? Buffer.from(svg)
12
+ : await sharp(Buffer.from(svg)).png().toBuffer();
13
+ return {
14
+ data: image.toString('base64'),
15
+ mimeType,
16
+ structuredContent: {
17
+ ...metadata,
18
+ format,
19
+ mimeType,
20
+ },
21
+ };
22
+ }
@@ -0,0 +1,27 @@
1
+ export function createAgentToolRateLimiter(requestsPerMinute) {
2
+ const limit = Math.max(1, Number.parseInt(requestsPerMinute, 10) || 120);
3
+ const windows = new Map();
4
+ let nextSweepAt = 0;
5
+ return (key) => {
6
+ const timestamp = Date.now();
7
+ if (timestamp >= nextSweepAt) {
8
+ for (const [windowKey, window] of windows) {
9
+ if (timestamp >= window.resetAt) windows.delete(windowKey);
10
+ }
11
+ nextSweepAt = timestamp + 60_000;
12
+ }
13
+ let window = windows.get(key);
14
+ if (!window || timestamp >= window.resetAt) {
15
+ window = { count: 0, resetAt: timestamp + 60_000 };
16
+ windows.set(key, window);
17
+ }
18
+ if (window.count >= limit) {
19
+ const error = new Error('Agent tool request limit reached; retry after the current window');
20
+ error.code = 'AGENT_RATE_LIMITED';
21
+ error.retryAfterMs = Math.max(1, window.resetAt - timestamp);
22
+ error.statusCode = 429;
23
+ throw error;
24
+ }
25
+ window.count += 1;
26
+ };
27
+ }