collabmd 0.1.49 → 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 (400) hide show
  1. package/README.md +10 -659
  2. package/bin/collabmd.js +36 -20
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-Crf9Y3Q6.js +1 -0
  4. package/dist/client/assets/{abnfDiagram-VCTEODGH-CdVZqicp.js → abnfDiagram-VCTEODGH-PuinKbSQ.js} +1 -1
  5. package/dist/client/assets/ar-SA-5WIASEJP-Di7OimCN.js +10 -0
  6. package/dist/client/assets/{architectureDiagram-5GKGNRK7-wUo0bXif.js → architectureDiagram-5GKGNRK7-46hPkrZv.js} +1 -1
  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-I7D4REHJ-BRSK3m49.js → blockDiagram-I7D4REHJ-C1S5Bzf8.js} +1 -1
  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/{c4Diagram-7LVT6UL2-yD2poxqw.js → c4Diagram-7LVT6UL2-VAk1HPmz.js} +1 -1
  14. package/dist/client/assets/ca-ES-2KGUU5XB-C9t-c0cH.js +8 -0
  15. package/dist/client/assets/channel-jwdhnPiV.js +1 -0
  16. package/dist/client/assets/chunk-2E4U76K2-Ba8Wf22k.js +1 -0
  17. package/dist/client/assets/{chunk-4HAMMTFA-DStbIfJ1.js → chunk-4HAMMTFA-Ht-73lsT.js} +1 -1
  18. package/dist/client/assets/chunk-5XKZK2GL-D4UAZSOJ.js +1 -0
  19. package/dist/client/assets/{chunk-75Z2AOVW-C5pGd3W9.js → chunk-75Z2AOVW-B2cZexqK.js} +1 -1
  20. package/dist/client/assets/{chunk-CLGD4ZFX-BMeArk03.js → chunk-CLGD4ZFX-Cmtx89ht.js} +1 -1
  21. package/dist/client/assets/{chunk-DU6HZSFF-Zkp69c6c.js → chunk-DU6HZSFF-C6d6PJfE.js} +1 -1
  22. package/dist/client/assets/{chunk-F27PBJKO-D4xNct1r.js → chunk-F27PBJKO-Dg3H6KLL.js} +1 -1
  23. package/dist/client/assets/{chunk-GMAD6QVW-NZ6WpDb8.js → chunk-GMAD6QVW-DUfjx_d5.js} +1 -1
  24. package/dist/client/assets/{chunk-GVQU2GXP-D8SDprfX.js → chunk-GVQU2GXP-D1l7oRGR.js} +1 -1
  25. package/dist/client/assets/{chunk-IMKFNOWR-D8jEuU3Q.js → chunk-IMKFNOWR-3F6NhHUP.js} +1 -1
  26. package/dist/client/assets/{chunk-L3NEJ4N5-aijKP-eh.js → chunk-L3NEJ4N5-BmCVn4y-.js} +1 -1
  27. package/dist/client/assets/{chunk-OSK3NFVY-CCbLQAMa.js → chunk-OSK3NFVY-CWHXAmfx.js} +1 -1
  28. package/dist/client/assets/{chunk-P2QGCYS3-Oag_FdCq.js → chunk-P2QGCYS3-Du8EtwOa.js} +1 -1
  29. package/dist/client/assets/{chunk-POPQ4Y6H-CYnpIgXT.js → chunk-POPQ4Y6H-B5yJIrZE.js} +1 -1
  30. package/dist/client/assets/{chunk-PWAF6VOD-JSNrcBmP.js → chunk-PWAF6VOD-B3gML4ps.js} +1 -1
  31. package/dist/client/assets/{chunk-SHT3W25Y-BiQGljao.js → chunk-SHT3W25Y-BKaI8jZO.js} +1 -1
  32. package/dist/client/assets/{chunk-SVP7TREG-DB485R5x.js → chunk-SVP7TREG-XlsB_ZMZ.js} +1 -1
  33. package/dist/client/assets/{chunk-TICWLB2K-8rAVvoS3.js → chunk-TICWLB2K-Cpp2z8yK.js} +1 -1
  34. package/dist/client/assets/chunk-TLUHSLCS-Yl7B0Vrz.js +1 -0
  35. package/dist/client/assets/chunk-ZNVOA63L-BmCQjhx-.js +40 -0
  36. package/dist/client/assets/{chunk-FLYJHZSQ-Be7lKF17.js → chunk-ZPMXAHWN-Dt0TxJa6.js} +2 -2
  37. package/dist/client/assets/classDiagram-ZZMXUADV-BRw9vo8U.js +1 -0
  38. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BRw9vo8U.js +1 -0
  39. package/dist/client/assets/comment-markdown-renderer-B9_vPc3F.js +1 -0
  40. package/dist/client/assets/comment-thread-store-NNHqRVsX.js +1 -0
  41. package/dist/client/assets/comment-threads-nJhK1yfc.js +4 -0
  42. package/dist/client/assets/cs-CZ-VUCGPRML-BfCoYAgj.js +7 -0
  43. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-rTz9RhFH.js → cynefinDiagram-5FMLGOSQ-BRoCEoZM.js} +1 -1
  44. package/dist/client/assets/da-DK-NNDP2IVP-DBw9ZNTR.js +2 -0
  45. package/dist/client/assets/{dagre-GXQ25YYZ-Cr67wLpQ.js → dagre-GXQ25YYZ-BSfKCfy7.js} +1 -1
  46. package/dist/client/assets/de-CH-I7RAVIZN-DYW18Vsr.js +11 -0
  47. package/dist/client/assets/de-DE-WBQ3DQLR-DYW18Vsr.js +11 -0
  48. package/dist/client/assets/deferred-collab-rBe4nuQ2.css +1 -0
  49. package/dist/client/assets/deferred-git-BHKtkFYi.css +1 -0
  50. package/dist/client/assets/deferred-preview-pe7Iwwx3.css +1 -0
  51. package/dist/client/assets/{diagram-S7CK7UJ4-DywERe__.js → diagram-S7CK7UJ4-D7KaM9yj.js} +1 -1
  52. package/dist/client/assets/{diagram-UQ7AKVKN-CNYlXtu4.js → diagram-UQ7AKVKN-JevUZuYi.js} +1 -1
  53. package/dist/client/assets/{diagram-VSXAHHWV-0H1a61Bn.js → diagram-VSXAHHWV-B3-U-Q2E.js} +1 -1
  54. package/dist/client/assets/{diagram-VX7I27RA-CsJbsx5F.js → diagram-VX7I27RA-pSD4HMh1.js} +1 -1
  55. package/dist/client/assets/{diagram-Z3DM3KII-D0mLxEgI.js → diagram-Z3DM3KII-D8r1_CIb.js} +1 -1
  56. package/dist/client/assets/{direct-engine-DdrQKpgq-CtKfQzCt.js → direct-engine-DdrQKpgq-B5zIoeQw.js} +1 -1
  57. package/dist/client/assets/dist-B3HdUPsK.js +1 -0
  58. package/dist/client/assets/{dist-Tw-Fxpeb.js → dist-B7XMN9AT.js} +1 -1
  59. package/dist/client/assets/dist-BIRygGYH.js +1 -0
  60. package/dist/client/assets/dist-BPyOlNLY.js +2 -0
  61. package/dist/client/assets/{dist-D5wCC32z.js → dist-BR81yxMt.js} +1 -1
  62. package/dist/client/assets/{dist-TW8iFRyW.js → dist-B_B4XLmq.js} +1 -1
  63. package/dist/client/assets/dist-Bdy9ZRzd.js +9 -0
  64. package/dist/client/assets/{dist-netZOQtD.js → dist-Bfxzlnrf.js} +1 -1
  65. package/dist/client/assets/{dist-DzNmC81X.js → dist-Bx3QkS-3.js} +1 -1
  66. package/dist/client/assets/{dist-mj2Ht75J.js → dist-By7ieqAf.js} +1 -1
  67. package/dist/client/assets/dist-ByhQbe-x.js +1 -0
  68. package/dist/client/assets/{dist-CdmKGRGr.js → dist-BzFSJM0U.js} +1 -1
  69. package/dist/client/assets/dist-C5NkYKAa.js +1 -0
  70. package/dist/client/assets/{dist-D3fehAZ2.js → dist-CELhfKzh.js} +1 -1
  71. package/dist/client/assets/dist-CEirJSxk.js +1 -0
  72. package/dist/client/assets/dist-CO0-4CuV.js +39 -0
  73. package/dist/client/assets/dist-CRnJ0D9h.js +1 -0
  74. package/dist/client/assets/{dist-GvvCNBe4.js → dist-CbDyXgCo.js} +1 -1
  75. package/dist/client/assets/{dist-BeajGMhO.js → dist-CqXVyYoH.js} +1 -1
  76. package/dist/client/assets/{dist-LQ4kDCKz.js → dist-CrWzIWEE.js} +1 -1
  77. package/dist/client/assets/dist-CyNrloSI.js +1 -0
  78. package/dist/client/assets/dist-D60_kdpQ.js +1 -0
  79. package/dist/client/assets/{dist-DuH3ZrHo.js → dist-DCpIH3-_.js} +1 -1
  80. package/dist/client/assets/{dist-BPHLJ09L.js → dist-DJAMplZI.js} +2 -2
  81. package/dist/client/assets/{dist-DGEbEfw4.js → dist-DVXzbeDx.js} +1 -1
  82. package/dist/client/assets/{dist-C5NgpdG5.js → dist-Drv_wZYC.js} +1 -1
  83. package/dist/client/assets/{dist-DVy5woUy.js → dist-EWJYvBK1.js} +1 -1
  84. package/dist/client/assets/dist-Hdhj3L3t.js +1 -0
  85. package/dist/client/assets/{dist-DpYDHR9p.js → dist-gRRhmB-2.js} +3 -3
  86. package/dist/client/assets/dist-kWb2d1CH.js +1 -0
  87. package/dist/client/assets/dist-kiD2GIsD.js +13 -0
  88. package/dist/client/assets/{dist-JaU3aRlD.js → dist-l-56SowH.js} +1 -1
  89. package/dist/client/assets/{dist-BK9QvQrc.js → dist-nxQErAaK.js} +2 -2
  90. package/dist/client/assets/dist-sLzRQQk7.js +1 -0
  91. package/dist/client/assets/document-formatter-Qdiq9uJs.js +1 -0
  92. package/dist/client/assets/drawioEditor-CHf1vtdQ.js +9 -0
  93. package/dist/client/assets/{ebnfDiagram-PWID7BFC-HeTxHpCU.js → ebnfDiagram-PWID7BFC-UJ0Fz5ci.js} +1 -1
  94. package/dist/client/assets/editor-session-4Bn81iWm.js +14 -0
  95. package/dist/client/assets/el-GR-TYQHVGXW-Dx82YYAS.js +7 -0
  96. package/dist/client/assets/embedded-editor-base-jK221GC8.css +1 -0
  97. package/dist/client/assets/{embedpdf-DA4bA119-BPqZxwjc.js → embedpdf-DA4bA119-E8wZ11J2.js} +2 -3
  98. package/dist/client/assets/{embedpdf-BmE13ZZ0.js → embedpdf-LUXDBD3-.js} +1 -1
  99. package/dist/client/assets/{en-SJ2YIMFF-CJBL3nkq.js → en-2RFA324Y-BsuNJTcL.js} +1 -1
  100. package/dist/client/assets/{erDiagram-RLTQ6QDP-CbrDdd5P.js → erDiagram-RLTQ6QDP-CWrH1UJ9.js} +1 -1
  101. package/dist/client/assets/es-ES-JEUOREKJ-Rx0NUQDl.js +12 -0
  102. package/dist/client/assets/eu-ES-SO5DEEAN-CDYm-BcK.js +8 -0
  103. package/dist/client/assets/excalidraw-element-link-iA6zo0_f.js +7 -0
  104. package/dist/client/assets/{excalidrawEditor-BbSbI80a.css → excalidrawEditor-DDE0n1Pk.css} +1 -1
  105. package/dist/client/assets/excalidrawEditor-WIuguTz7.js +9 -0
  106. package/dist/client/assets/export-page-AN-wI5p4.js +56 -0
  107. package/dist/client/assets/exportDocument-B7IagJhQ.css +1 -0
  108. package/dist/client/assets/exportDocument-B9xNKpQe.js +2 -0
  109. package/dist/client/assets/fa-IR-FIYUE2GQ-C865Nx3X.js +9 -0
  110. package/dist/client/assets/fi-FI-REAEF6HQ-BIpjJqIb.js +6 -0
  111. package/dist/client/assets/flowDiagram-HODETNUW-kb1lUSBo.js +1 -0
  112. package/dist/client/assets/fr-FR-SUCL7J6B-DGAKE8jH.js +12 -0
  113. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-BHgOYiZz.js → ganttDiagram-EL5Y4UJY-BBNzDfaV.js} +1 -1
  114. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-Dl__X3Sk.js → gitGraphDiagram-WWUBYQGX-Csf0Dm_1.js} +1 -1
  115. package/dist/client/assets/gl-ES-KHCSOGVH-DWKh0CMu.js +6 -0
  116. package/dist/client/assets/he-IL-JYXVXV2Q-zqbcM-4g.js +9 -0
  117. package/dist/client/assets/hi-IN-BU52H3BO-CY8v6eG9.js +3 -0
  118. package/dist/client/assets/highlight-theme-CzNkO-IJ.js +1 -0
  119. package/dist/client/assets/hu-HU-OWADXDQ3-CEl6Udfh.js +3 -0
  120. package/dist/client/assets/id-ID-EOMR5R3I-CGQwUjoL.js +8 -0
  121. package/dist/client/assets/image-2QKV3NAF-BUbX0y5Y.js +1 -0
  122. package/dist/client/assets/index-BAmZnTFV.css +1 -0
  123. package/dist/client/assets/index-mWiw418b.js +1111 -0
  124. package/dist/client/assets/{infoDiagram-27XIBGKW-DBpoANC9.js → infoDiagram-27XIBGKW-Bzy6kCbb.js} +1 -1
  125. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BMPC6hfp.js → ishikawaDiagram-5VMMS53U-CRy9vIS5.js} +1 -1
  126. package/dist/client/assets/it-IT-FC2VTM3L-KTijNcUe.js +12 -0
  127. package/dist/client/assets/ja-JP-JBNTKYP4-BflWlGhw.js +12 -0
  128. package/dist/client/assets/{journeyDiagram-3NMN7TZE-B1sApUmM.js → journeyDiagram-3NMN7TZE-D4ZR_s9J.js} +1 -1
  129. package/dist/client/assets/kaa-TC3VIB7V-B-xtZfy0.js +1 -0
  130. package/dist/client/assets/kab-KAB-UOUDSQKM-BmO0O4Y4.js +4 -0
  131. package/dist/client/assets/{kanban-definition-UXKFOSKX-C9yP4td1.js → kanban-definition-UXKFOSKX-CIDTmu5g.js} +1 -1
  132. package/dist/client/assets/kk-KZ-P5H2X7YS-CSQFB8IN.js +1 -0
  133. package/dist/client/assets/{km-KH-PCWDKPHP-DSmy5shj.js → km-KH-IHMV2US7-BxrjuEzr.js} +4 -4
  134. package/dist/client/assets/ko-KR-ZTMANIDF-BnNRXd5J.js +5 -0
  135. package/dist/client/assets/ku-TR-GPJTRB5G-BZM7f2aT.js +6 -0
  136. package/dist/client/assets/{line-BFl3ujec.js → line-DSWLHgpx.js} +1 -1
  137. package/dist/client/assets/lobby-presence-Rdjnc0_0.js +1 -0
  138. package/dist/client/assets/lt-LT-V3XDOK3P-MVQBOHmF.js +3 -0
  139. package/dist/client/assets/lv-LV-DVQ3FADO-CrenwAhS.js +4 -0
  140. package/dist/client/assets/markdown-it-CocJWnjv.js +13 -0
  141. package/dist/client/assets/mermaid-parser.core-DrdLA3p0.js +3 -0
  142. package/dist/client/assets/mermaid.core-C_FK-7n4.js +1 -0
  143. package/dist/client/assets/{mermaid.core-BrY09czX.js → mermaid.core-D0cMM4Rl.js} +2 -3
  144. package/dist/client/assets/{mindmap-definition-YA3MSWOX-BUQHcYbK.js → mindmap-definition-YA3MSWOX-DO8NB9VH.js} +1 -1
  145. package/dist/client/assets/mr-IN-VZ6HH5FE-B-PHPglH.js +9 -0
  146. package/dist/client/assets/my-MM-XYKWHRK6-Be5sYp5q.js +1 -0
  147. package/dist/client/assets/nb-NO-UNO2GGZJ-BvSKGdja.js +8 -0
  148. package/dist/client/assets/nl-NL-76EFHT4P-C2yNx1Cj.js +13 -0
  149. package/dist/client/assets/nn-NO-CFKD7ABE-4NsqlDRP.js +4 -0
  150. package/dist/client/assets/oc-FR-YBJTCJ3J-B4OTQsWW.js +4 -0
  151. package/dist/client/assets/pa-IN-SNOXSMRV-CKj_sOG7.js +4 -0
  152. package/dist/client/assets/{pegDiagram-XKGWAZYB-Bi2Iml7Z.js → pegDiagram-XKGWAZYB-DS6Ab21R.js} +1 -1
  153. package/dist/client/assets/percentages-Q7USCRWZ-DWE6uvTs.js +1 -0
  154. package/dist/client/assets/{pieDiagram-E7YTZNPT-_gYXnMoi.js → pieDiagram-E7YTZNPT-BbFe6Tgs.js} +1 -1
  155. package/dist/client/assets/pl-PL-BSY6YFZ3-CFuzA6L0.js +12 -0
  156. package/dist/client/assets/preload-helper-CtT0-S4g.js +1 -0
  157. package/dist/client/assets/preview-render-compiler-C_7J7eia.js +43 -0
  158. package/dist/client/assets/preview-render-compiler-DzJ1KR_M.js +1 -0
  159. package/dist/client/assets/preview-render-worker-1DoIDllV.js +59 -0
  160. package/dist/client/assets/prod-D5TxmmoB.js +1 -0
  161. package/dist/client/assets/prod-pbFU4TaM.js +145 -0
  162. package/dist/client/assets/pt-BR-CZDV62R3-CkPMtyNx.js +10 -0
  163. package/dist/client/assets/pt-PT-JO57XJJW-CBSnfGtF.js +12 -0
  164. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-DwexhEhd.js → quadrantDiagram-AXDQQJYC-fJE7iAxt.js} +1 -1
  165. package/dist/client/assets/quick-switcher-De4PjZFC.css +1 -0
  166. package/dist/client/assets/quick-switcher-controller-CUajuy78.js +1 -0
  167. package/dist/client/assets/{railroadDiagram-O6MQD6OU-BVA5UbMu.js → railroadDiagram-O6MQD6OU-CUQKqbCK.js} +1 -1
  168. package/dist/client/assets/{requirementDiagram-BXWQKSXE-C4cKwiIw.js → requirementDiagram-BXWQKSXE-Balm0WW8.js} +1 -1
  169. package/dist/client/assets/ro-RO-UZ5ICYYN-BOuntc_r.js +12 -0
  170. package/dist/client/assets/room-DX7lIfnu.js +1 -0
  171. package/dist/client/assets/ru-RU-AN7JPREC-D-ow3SNR.js +10 -0
  172. package/dist/client/assets/runtime-config-BFVdhnJu.js +1 -0
  173. package/dist/client/assets/runtime-paths-Cn0snt_9.js +1 -0
  174. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-B5HHkRT2.js → sankeyDiagram-P5KCCOFB-CcbMqrlQ.js} +1 -1
  175. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-BX6jqJFD.js → sequenceDiagram-WJ2MYXX4-BL1j3Sn-.js} +1 -1
  176. package/dist/client/assets/si-LK-7CBLD6QQ-c91EepX0.js +1 -0
  177. package/dist/client/assets/sk-SK-SWR6DKBI-D5vFMIL6.js +7 -0
  178. package/dist/client/assets/sl-SI-JRML4FIH-D53L_0S2.js +6 -0
  179. package/dist/client/assets/{stateDiagram-D77RDMKH-CmqxyRGx.js → stateDiagram-D77RDMKH-DNi924hh.js} +1 -1
  180. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-C62JEwak.js +1 -0
  181. package/dist/client/assets/sv-SE-4ZPKFFXF-DT-G7RCI.js +12 -0
  182. package/dist/client/assets/{swimlanes-42K2YHIH-Bmgb9Zld.js → swimlanes-42K2YHIH-ColgjSH4.js} +1 -1
  183. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-B9UZhEj4.js +8 -0
  184. package/dist/client/assets/ta-IN-V6NHHU6Z-D5jy7_AE.js +6 -0
  185. package/dist/client/assets/th-TH-P7CTMGDK-6sy0NO7K.js +1 -0
  186. package/dist/client/assets/{timeline-definition-24CTP7MA-BA-lVH6P.js → timeline-definition-24CTP7MA-7pch5JAr.js} +1 -1
  187. package/dist/client/assets/tr-TR-GUFYG22B-ClVaf8h1.js +4 -0
  188. package/dist/client/assets/uk-UA-K6SV5NFQ-BLTTtyNB.js +6 -0
  189. package/dist/client/assets/uz-UZ-TVKTZO2G-Bm02Eg3D.js +1 -0
  190. package/dist/client/assets/vault-api-client-QjZ_T03l.js +7 -0
  191. package/dist/client/assets/vault-utils-Bct69Xw2.js +1 -0
  192. package/dist/client/assets/{vennDiagram-4TSXK5OY-DNdUC_Xj.js → vennDiagram-4TSXK5OY-C5taziCX.js} +1 -1
  193. package/dist/client/assets/vi-VN-7FKFXJNO-CL3WPhmG.js +7 -0
  194. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-C2oY-YbF.js → wardleyDiagram-VM6X3IG4-BbSlUwuM.js} +1 -1
  195. package/dist/client/assets/{wiki-link-resolver-DFIwErjc.js → wiki-link-resolver-C2P_WmTV.js} +1 -1
  196. package/dist/client/assets/{worker-engine-m0rlHn8R-S8mpn_O0.js → worker-engine-m0rlHn8R-eSDcDGEI.js} +1 -1
  197. package/dist/client/assets/workspace-change-CVA9dVmy.js +1 -0
  198. package/dist/client/assets/workspace-sync-client-D4nblH_2.js +1 -0
  199. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-CoIR8CBX.js → xychartDiagram-S5SC5T6Z-D06X1arY.js} +1 -1
  200. package/dist/client/assets/yjs-B41tM6Sz.js +4 -0
  201. package/dist/client/assets/yjs-provider-reset-guard-R43MnLNc.js +1 -0
  202. package/dist/client/assets/zh-CN-AOKVLNNK-DGidDH2b.js +11 -0
  203. package/dist/client/assets/zh-HK-CDKPF5DC-CRcNR3rk.js +1 -0
  204. package/dist/client/assets/zh-TW-ZVGYESGW-C7Qji1y6.js +13 -0
  205. package/dist/client/drawio-editor.html +7 -8
  206. package/dist/client/excalidraw-editor.html +31 -33
  207. package/dist/client/export-document.html +5 -7
  208. package/dist/client/index.html +30 -26
  209. package/package.json +14 -20
  210. package/src/client/app/drawio-editor.html +1 -1
  211. package/src/client/app/excalidraw-editor.html +1 -1
  212. package/src/client/app/export-document.html +1 -1
  213. package/src/client/app/index.html +28 -4
  214. package/src/client/app/main-entry.js +1 -19
  215. package/src/client/application/app-shell/comments-feature.js +6 -0
  216. package/src/client/application/app-shell/ui-feature-shell.js +136 -58
  217. package/src/client/application/app-shell/ui-feature-tab-activity.js +8 -3
  218. package/src/client/application/app-shell-elements.js +5 -0
  219. package/src/client/application/highlight-theme.js +16 -0
  220. package/src/client/application/preview-render-compiler.js +43 -20
  221. package/src/client/application/preview-render-executor.js +0 -26
  222. package/src/client/application/preview-renderer.js +24 -7
  223. package/src/client/application/workspace-coordinator.js +20 -21
  224. package/src/client/bootstrap/collabmd-app-shell.js +71 -35
  225. package/src/client/bootstrap/lazy-collab-clients.js +90 -0
  226. package/src/client/domain/excalidraw-scene-reconcile.js +5 -2
  227. package/src/client/domain/hash-routes.js +5 -0
  228. package/src/client/domain/highlight-runtime.js +47 -0
  229. package/src/client/domain/lobby-chat.js +2 -0
  230. package/src/client/domain/runtime-paths.js +56 -7
  231. package/src/client/domain/vault-utils.js +11 -0
  232. package/src/client/excalidraw-editor.js +20 -4
  233. package/src/client/infrastructure/auth-client.js +1 -2
  234. package/src/client/infrastructure/browser-preferences-port.js +16 -0
  235. package/src/client/infrastructure/editor-view-adapter.js +43 -8
  236. package/src/client/infrastructure/excalidraw-room-client.js +9 -1
  237. package/src/client/infrastructure/hosted-api-client.js +60 -0
  238. package/src/client/infrastructure/lobby-presence.js +2 -2
  239. package/src/client/infrastructure/runtime-config.js +3 -1
  240. package/src/client/infrastructure/webmcp-tool-registry.js +16 -2
  241. package/src/client/presentation/comment-markdown-renderer.js +2 -14
  242. package/src/client/presentation/comment-overview-controller.js +1 -2
  243. package/src/client/presentation/comment-ui/comment-ui-shared.js +5 -2
  244. package/src/client/presentation/file-explorer-controller.js +3 -0
  245. package/src/client/presentation/file-explorer-view.js +272 -174
  246. package/src/client/presentation/git-panel-controller.js +1 -1
  247. package/src/client/presentation/hosted-workspace-gate-controller.js +180 -0
  248. package/src/client/presentation/layout-controller.js +10 -1
  249. package/src/client/presentation/team-settings-controller.js +228 -0
  250. package/src/client/styles/deferred-collab.css +5 -0
  251. package/src/client/styles/deferred-git.css +7 -0
  252. package/src/client/styles/deferred-preview.css +6 -0
  253. package/src/client/styles/features/diagram-preview.css +0 -15
  254. package/src/client/styles/features/outline.css +4 -2
  255. package/src/client/styles/features/preview-markdown.css +25 -11
  256. package/src/client/styles/features/team-settings.css +162 -0
  257. package/src/client/styles/foundation/tokens.css +2 -2
  258. package/src/client/styles/layout/editor-page.css +0 -13
  259. package/src/client/styles/layout/overlays.css +16 -0
  260. package/src/client/styles/layout/responsive.css +5 -5
  261. package/src/client/styles/layout/shell.css +20 -1
  262. package/src/client/styles/layout/sidebar.css +92 -3
  263. package/src/client/styles/style.css +3 -19
  264. package/src/domain/agent-tool-definitions.js +139 -63
  265. package/src/domain/collabmd-content-capabilities.js +4 -4
  266. package/src/domain/excalidraw-agent-scene.js +108 -6
  267. package/src/domain/excalidraw-agent-verification.js +95 -1
  268. package/src/domain/excalidraw-room-codec.js +12 -1
  269. package/src/domain/literal-text-search.js +13 -0
  270. package/src/server/application/agent-content-service.js +142 -74
  271. package/src/server/config/env.js +96 -5
  272. package/src/server/create-app-server.js +23 -153
  273. package/src/server/domain/hosted-workspace.js +10 -1
  274. package/src/server/domain/ripgrep-search-service.js +68 -21
  275. package/src/server/infrastructure/git/local-exclude.js +13 -1
  276. package/src/server/infrastructure/http/create-agent-api-handler.js +1 -1
  277. package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -0
  278. package/src/server/infrastructure/http/create-request-handler.js +95 -26
  279. package/src/server/infrastructure/http/create-static-handler.js +3 -0
  280. package/src/server/infrastructure/http/create-vault-api-query-handler.js +15 -2
  281. package/src/server/infrastructure/mcp/create-agent-mcp-handler.js +2 -1
  282. package/src/server/infrastructure/persistence/sidecar-store.js +12 -5
  283. package/src/server/infrastructure/persistence/vault-file-store.js +2 -3
  284. package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +48 -22
  285. package/src/server/shared/agent-tool-rate-limiter.js +7 -0
  286. package/src/server/startup/git-remote-bootstrap.js +56 -49
  287. package/src/server/vault-registry.js +251 -0
  288. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-C-nmgL5g.js +0 -1
  289. package/dist/client/assets/ar-SA-PQUY64WN-xjXgbW6d.js +0 -10
  290. package/dist/client/assets/az-AZ-OXJXL76K-4JkO4Pca.js +0 -1
  291. package/dist/client/assets/base-CaIEJUF9.css +0 -1
  292. package/dist/client/assets/bg-BG-W2GKIJDF-DnkH_o81.js +0 -5
  293. package/dist/client/assets/bn-BD-TGL7M4PJ-CG4JkmtP.js +0 -3
  294. package/dist/client/assets/bn-IN-BKETKYEH-CG4JkmtP.js +0 -3
  295. package/dist/client/assets/ca-ES-LD5SCRVV-U6_TVMX9.js +0 -8
  296. package/dist/client/assets/channel-Fa4GS_-F.js +0 -1
  297. package/dist/client/assets/chunk-2E4U76K2-BPnTT-J3.js +0 -2
  298. package/dist/client/assets/chunk-7XWMRXBY-CfMzEq80.js +0 -1
  299. package/dist/client/assets/chunk-RM4UPSZO-DOWllDY8.js +0 -41
  300. package/dist/client/assets/chunk-TLUHSLCS-DTY5v0aj.js +0 -2
  301. package/dist/client/assets/classDiagram-ZZMXUADV-BsQWoR3Q.js +0 -1
  302. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BsQWoR3Q.js +0 -1
  303. package/dist/client/assets/comment-thread-store-CX98zR6q.js +0 -1
  304. package/dist/client/assets/comment-threads-BnRwo5B9.js +0 -4
  305. package/dist/client/assets/cs-CZ-OFPU5DBV-BmFAIhqX.js +0 -7
  306. package/dist/client/assets/da-DK-FRDJFYWF-H387Jw8B.js +0 -2
  307. package/dist/client/assets/de-CH-ZG7H3QK3-C_groygo.js +0 -11
  308. package/dist/client/assets/de-DE-SIJYH4IH-C_groygo.js +0 -11
  309. package/dist/client/assets/dist--hk9I5HQ.js +0 -1
  310. package/dist/client/assets/dist-B1XEa-Zs.js +0 -1
  311. package/dist/client/assets/dist-BJ1bJs33.js +0 -1
  312. package/dist/client/assets/dist-Bd1JucQF.js +0 -1
  313. package/dist/client/assets/dist-ByrG2qBA.js +0 -1
  314. package/dist/client/assets/dist-C0G3AaXG.js +0 -1
  315. package/dist/client/assets/dist-CKS_-are.js +0 -1
  316. package/dist/client/assets/dist-D37Hyu3h.js +0 -9
  317. package/dist/client/assets/dist-Dl_tpDSr.js +0 -1
  318. package/dist/client/assets/dist-Dm4w5UId.js +0 -1
  319. package/dist/client/assets/dist-RKBTaQMb.js +0 -13
  320. package/dist/client/assets/dist-eBx8q6Sy.js +0 -1
  321. package/dist/client/assets/dist-jVU5Be5P.js +0 -1
  322. package/dist/client/assets/document-formatter-rDDjRfZ2.js +0 -2
  323. package/dist/client/assets/drawioEditor-JubEEha7.js +0 -9
  324. package/dist/client/assets/editor-session-Bk6oIvSr.js +0 -54
  325. package/dist/client/assets/el-GR-IEE2CGI2-BkT6YT54.js +0 -7
  326. package/dist/client/assets/embedded-editor-base-BlCgz6mw.css +0 -1
  327. package/dist/client/assets/es-Bfdp096f.js +0 -22
  328. package/dist/client/assets/es-ES-TVVPWKV5-CpPKJXTM.js +0 -12
  329. package/dist/client/assets/eu-ES-CGBMFQDT-Bu3N2493.js +0 -8
  330. package/dist/client/assets/excalidraw-element-link-YLIaTnVF.js +0 -7
  331. package/dist/client/assets/excalidrawEditor-dBMbRX_S.js +0 -9
  332. package/dist/client/assets/export-page-CRRQ2NEl.js +0 -57
  333. package/dist/client/assets/exportDocument-BlQRd9_m.js +0 -2
  334. package/dist/client/assets/exportDocument-CNSbjZwu.css +0 -1
  335. package/dist/client/assets/fa-IR-IE6XAPR4-BEvLCORD.js +0 -9
  336. package/dist/client/assets/fi-FI-P7TKNHRM-DI0q8iSX.js +0 -6
  337. package/dist/client/assets/file-icon-svg-Y_kpF957.js +0 -1
  338. package/dist/client/assets/flowDiagram-HODETNUW-D5Gy0wmg.js +0 -1
  339. package/dist/client/assets/fr-FR-QI2XZNT7-y8kXd8LA.js +0 -12
  340. package/dist/client/assets/gl-ES-TLYCNOZZ-Br-Fhff-.js +0 -6
  341. package/dist/client/assets/he-IL-ZX43XLGP-qKQq6V9X.js +0 -9
  342. package/dist/client/assets/hi-IN-UTYRMTUF-DOUcwrDO.js +0 -3
  343. package/dist/client/assets/hu-HU-AJOSEBW6-FqTyvHlD.js +0 -3
  344. package/dist/client/assets/id-ID-ETLTVG6C-CQqh3CLS.js +0 -8
  345. package/dist/client/assets/image-ZVKINSPA-DgzW5zAy.js +0 -1
  346. package/dist/client/assets/index-D3RER1SZ.js +0 -1023
  347. package/dist/client/assets/index-DREVKl_K.css +0 -1
  348. package/dist/client/assets/it-IT-B4B6TP6L-V-yK3SZz.js +0 -12
  349. package/dist/client/assets/ja-JP-IYKVURR5-BQKBXRpX.js +0 -12
  350. package/dist/client/assets/kaa-SE2BUIKX-CZ5kfwPg.js +0 -1
  351. package/dist/client/assets/kab-KAB-Y3GLKXLR-Do7GWfuN.js +0 -4
  352. package/dist/client/assets/kk-KZ-ABWUFVOH-BpqVciQz.js +0 -1
  353. package/dist/client/assets/ko-KR-7JQDXKGM-N42lep78.js +0 -5
  354. package/dist/client/assets/ku-TR-NAH2Q5B7-K8LLl9fk.js +0 -6
  355. package/dist/client/assets/lt-LT-VQFYRSNQ-BmOd0ALn.js +0 -3
  356. package/dist/client/assets/lv-LV-T62VSYUM-B22WdPhp.js +0 -4
  357. package/dist/client/assets/mermaid-parser.core-Bl0efOMt.js +0 -4
  358. package/dist/client/assets/mermaid.core-DfcNfOTv.js +0 -1
  359. package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +0 -1
  360. package/dist/client/assets/mr-IN-V4FHLCJE-XX069tpm.js +0 -9
  361. package/dist/client/assets/my-MM-E3SQ6E54-cst_-5SB.js +0 -1
  362. package/dist/client/assets/nb-NO-MLNOFN5H-Bu2URWko.js +0 -8
  363. package/dist/client/assets/nl-NL-D5L3ZV4M-BqrV0btt.js +0 -13
  364. package/dist/client/assets/nn-NO-NNHDGPKB-DK-xZaWM.js +0 -4
  365. package/dist/client/assets/oc-FR-DWCRF55G-BZ5Po5R6.js +0 -4
  366. package/dist/client/assets/pa-IN-3JSAY44M-BZQSjKrS.js +0 -4
  367. package/dist/client/assets/percentages-ETZPVQEE-DFxFqXgH.js +0 -1
  368. package/dist/client/assets/pl-PL-ACURYKP3-qcEOSfCk.js +0 -12
  369. package/dist/client/assets/preload-helper-HclGiUj8.js +0 -1
  370. package/dist/client/assets/preview-render-compiler-CfxJYldJ.js +0 -41
  371. package/dist/client/assets/preview-render-compiler-Cu8_i9iS.js +0 -1
  372. package/dist/client/assets/preview-render-worker-c4Yi93qW.js +0 -66
  373. package/dist/client/assets/prod-BiJL30sl.js +0 -1
  374. package/dist/client/assets/prod-qAk7rHa4.js +0 -177
  375. package/dist/client/assets/pt-BR-LOX7MLGD-DLueHSyZ.js +0 -10
  376. package/dist/client/assets/pt-PT-CZ2U2RFQ-BJ-GAEm6.js +0 -12
  377. package/dist/client/assets/quick-switcher-controller-BoIK_wuG.js +0 -1
  378. package/dist/client/assets/ro-RO-2HECL2X6-CJUvKAf0.js +0 -12
  379. package/dist/client/assets/ru-RU-HAYNXO46-BWSlvTrt.js +0 -10
  380. package/dist/client/assets/runtime-config-DcmnGcXU.js +0 -1
  381. package/dist/client/assets/si-LK-W5KNS4H6-DGGCsn7k.js +0 -1
  382. package/dist/client/assets/sk-SK-7K2CFGDV-CY4uTYgQ.js +0 -7
  383. package/dist/client/assets/sl-SI-OXV2QZWW-2-weqaBY.js +0 -6
  384. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-zoLLQVyh.js +0 -1
  385. package/dist/client/assets/sv-SE-JTOBZRGL-9-IUtVkO.js +0 -12
  386. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DS-KQN37.js +0 -8
  387. package/dist/client/assets/ta-IN-KFAVKXGT-gHO6Q_DH.js +0 -6
  388. package/dist/client/assets/th-TH-VDMSCPDL-BvJuw6PJ.js +0 -1
  389. package/dist/client/assets/tr-TR-CEZ6GX45-CG6UU3Su.js +0 -4
  390. package/dist/client/assets/uk-UA-Q3H3OXQC-CSuIg_DY.js +0 -6
  391. package/dist/client/assets/uz-UZ-NGCSWWPX-mom7rxSP.js +0 -1
  392. package/dist/client/assets/vault-api-client-iZLhMJKe.js +0 -6
  393. package/dist/client/assets/vi-VN-P3NDEVPS-BB0Fu9ck.js +0 -7
  394. package/dist/client/assets/yjs-provider-reset-guard-9ul1qF6k.js +0 -4
  395. package/dist/client/assets/zh-CN-SS3O57GA-Bj8wsiMe.js +0 -11
  396. package/dist/client/assets/zh-HK-LWJT3VCF-DOTquTCh.js +0 -1
  397. package/dist/client/assets/zh-TW-VJXC72RT-B48PRo-l.js +0 -13
  398. package/integrations/pi/index.ts +0 -94
  399. /package/dist/client/assets/{vault-api-client-C3mlS_4N.css → auth-gate-C3mlS_4N.css} +0 -0
  400. /package/dist/client/assets/{base-BYODPHdS.js → github.min-DBihDoic.js} +0 -0
@@ -42,6 +42,7 @@ export function createRequestHandler(
42
42
  githubSetupFlow = null,
43
43
  structurizrWorkspaceService = null,
44
44
  agentIntegration = null,
45
+ vaultRegistry = null,
45
46
  ) {
46
47
  const handleStaticRequest = createStaticHandler(config, authService, searchService);
47
48
  const handleAuthApi = createAuthApiHandler({ authService });
@@ -50,28 +51,43 @@ export function createRequestHandler(
50
51
  githubSetupFlow,
51
52
  hostedWorkspaceService,
52
53
  });
53
- const handleGitApiQuery = createGitApiQueryHandler({ gitService });
54
- const handleGitApiCommand = createGitApiCommandHandler({
55
- authService,
56
- gitService,
57
- workspaceMutationCoordinator,
58
- });
59
- const handleVaultApiQuery = createVaultApiQueryHandler({
60
- baseQueryService,
61
- backlinkIndex,
62
- config,
63
- searchService,
64
- vaultFileStore,
65
- workspaceMutationCoordinator,
66
- });
67
- const handleVaultApiCommand = createVaultApiCommandHandler({
68
- backlinkIndex,
69
- maxPdfUploadBytes: config.maxPdfUploadBytes,
70
- renderDocx,
71
- roomRegistry,
72
- vaultFileStore,
73
- workspaceMutationCoordinator,
74
- });
54
+ // ponytail: one builder for legacy primary paths and scoped vaults; only the parts differ
55
+ const vaultHandlerCache = new Map();
56
+ function getVaultHandlers(id, parts) {
57
+ let handlers = vaultHandlerCache.get(id);
58
+ if (!handlers) {
59
+ handlers = {
60
+ command: createVaultApiCommandHandler({
61
+ backlinkIndex: parts.backlinkIndex,
62
+ maxPdfUploadBytes: config.maxPdfUploadBytes,
63
+ renderDocx,
64
+ roomRegistry: parts.roomRegistry,
65
+ vaultFileStore: parts.vaultFileStore,
66
+ workspaceMutationCoordinator: parts.workspaceMutationCoordinator,
67
+ }),
68
+ gitCommand: createGitApiCommandHandler({
69
+ authService,
70
+ gitService: parts.gitService,
71
+ workspaceMutationCoordinator: parts.workspaceMutationCoordinator,
72
+ }),
73
+ gitQuery: createGitApiQueryHandler({ gitService: parts.gitService }),
74
+ query: createVaultApiQueryHandler({
75
+ baseQueryService: parts.baseQueryService,
76
+ backlinkIndex: parts.backlinkIndex,
77
+ config,
78
+ searchService: parts.searchService,
79
+ vaultFileStore: parts.vaultFileStore,
80
+ workspaceMutationCoordinator: parts.workspaceMutationCoordinator,
81
+ }),
82
+ };
83
+ vaultHandlerCache.set(id, handlers);
84
+ }
85
+ return handlers;
86
+ }
87
+ const primaryHandlers = getVaultHandlers(
88
+ vaultRegistry?.getPrimaryContext?.()?.def.id ?? '__primary__',
89
+ { backlinkIndex, baseQueryService, gitService, roomRegistry, searchService, vaultFileStore, workspaceMutationCoordinator },
90
+ );
75
91
  const handlePlantUmlApi = createPlantUmlApiHandler({ plantUmlRenderer });
76
92
  const handleStructurizrApi = createStructurizrApiHandler({
77
93
  basePath: config.basePath,
@@ -94,6 +110,56 @@ export function createRequestHandler(
94
110
  })
95
111
  : async () => false;
96
112
 
113
+ function parseVaultScope(pathname) {
114
+ if (!pathname.startsWith('/api/v/')) {
115
+ return null;
116
+ }
117
+ const rest = pathname.slice('/api/v/'.length);
118
+ const slashIndex = rest.indexOf('/');
119
+ if (slashIndex === -1) {
120
+ return null;
121
+ }
122
+ const vaultId = rest.slice(0, slashIndex);
123
+ if (!vaultId) {
124
+ return null;
125
+ }
126
+ return { subPath: `/api${rest.slice(slashIndex)}`, vaultId };
127
+ }
128
+
129
+ async function handleVaultScopedApi(req, res, requestUrl) {
130
+ const scope = parseVaultScope(requestUrl.pathname);
131
+ if (!scope || !vaultRegistry) {
132
+ return false;
133
+ }
134
+ let context;
135
+ try {
136
+ context = await vaultRegistry.getOrCreateContextAsync(scope.vaultId);
137
+ } catch (error) {
138
+ jsonResponse(req, res, error?.statusCode || 500, { error: error?.message || 'Vault unavailable' });
139
+ return true;
140
+ }
141
+ const subUrl = new URL(requestUrl.toString());
142
+ subUrl.pathname = scope.subPath;
143
+ const handlers = getVaultHandlers(context.def.id, context);
144
+ if (await handlers.query(req, res, subUrl)) {
145
+ return true;
146
+ }
147
+ if (await handlers.command(req, res, subUrl)) {
148
+ return true;
149
+ }
150
+ if (subUrl.pathname.startsWith('/api/git')) {
151
+ if (await handlers.gitQuery(req, res, subUrl)) {
152
+ return true;
153
+ }
154
+ if (await handlers.gitCommand(req, res, subUrl)) {
155
+ return true;
156
+ }
157
+ jsonResponse(req, res, 404, { error: 'Git API endpoint not found' });
158
+ return true;
159
+ }
160
+ return false;
161
+ }
162
+
97
163
  function handleBasePathRedirect(req, res, originalRequestUrl) {
98
164
  if (
99
165
  config.basePath
@@ -231,10 +297,13 @@ export function createRequestHandler(
231
297
  }
232
298
 
233
299
  if (requestUrl.pathname.startsWith('/api/')) {
234
- if (await handleVaultApiQuery(req, res, requestUrl)) {
300
+ if (await handleVaultScopedApi(req, res, requestUrl)) {
301
+ return;
302
+ }
303
+ if (await primaryHandlers.query(req, res, requestUrl)) {
235
304
  return;
236
305
  }
237
- if (await handleVaultApiCommand(req, res, requestUrl)) {
306
+ if (await primaryHandlers.command(req, res, requestUrl)) {
238
307
  return;
239
308
  }
240
309
  if (await handlePlantUmlApi(req, res, requestUrl)) {
@@ -247,10 +316,10 @@ export function createRequestHandler(
247
316
  jsonResponse(req, res, 503, { error: 'Git integration is not configured' });
248
317
  return;
249
318
  }
250
- if (await handleGitApiQuery(req, res, requestUrl)) {
319
+ if (await primaryHandlers.gitQuery(req, res, requestUrl)) {
251
320
  return;
252
321
  }
253
- if (await handleGitApiCommand(req, res, requestUrl)) {
322
+ if (await primaryHandlers.gitCommand(req, res, requestUrl)) {
254
323
  return;
255
324
  }
256
325
  jsonResponse(req, res, 404, { error: 'Git API endpoint not found' });
@@ -58,8 +58,10 @@ function buildRuntimeConfig({
58
58
  structurizr,
59
59
  wikiLinkAutoCreate,
60
60
  wsBasePath,
61
+ vaults,
61
62
  }) {
62
63
  return `window.__COLLABMD_CONFIG__ = ${JSON.stringify({
64
+ activeVault: vaults?.[0]?.id ?? '',
63
65
  agentAccess: {
64
66
  enabled: Boolean(agentAccess?.enabled),
65
67
  endpoint: agentAccess?.endpoint || '',
@@ -79,6 +81,7 @@ function buildRuntimeConfig({
79
81
  structurizrEnabled: Boolean(structurizr?.enabled ?? structurizr?.serverUrl),
80
82
  wikiLinkAutoCreate,
81
83
  wsBasePath,
84
+ vaults: (vaults ?? []).map(({ id }) => ({ id })),
82
85
  })};\n`;
83
86
  }
84
87
 
@@ -274,14 +274,20 @@ async function handleFileTree(req, res, _requestUrl, { vaultFileStore, workspace
274
274
  }
275
275
  }
276
276
 
277
- async function handleCommentOverview(req, res, _requestUrl, { vaultFileStore }) {
277
+ async function handleCommentOverview(req, res, _requestUrl, {
278
+ vaultFileStore,
279
+ workspaceMutationCoordinator,
280
+ }) {
278
281
  try {
279
282
  if (typeof vaultFileStore.readCommentOverview !== 'function') {
280
283
  jsonResponse(req, res, 503, { error: 'Comment overview is unavailable' });
281
284
  return;
282
285
  }
283
286
 
284
- const overview = await vaultFileStore.readCommentOverview();
287
+ const workspaceState = await workspaceMutationCoordinator.getWorkspaceStateSnapshot();
288
+ const overview = await vaultFileStore.readCommentOverview({
289
+ filePaths: workspaceState.filePaths,
290
+ });
285
291
  jsonResponse(req, res, 200, { overview });
286
292
  } catch (error) {
287
293
  console.error('[api] Failed to read comment overview:', error.message);
@@ -486,6 +492,12 @@ async function handleSearch(req, res, requestUrl, { searchService }) {
486
492
  }
487
493
  }
488
494
 
495
+ async function handleVaultList(req, res, _requestUrl, { config }) {
496
+ // ponytail: ids only — absolute vault dirs are operator internals
497
+ const vaults = (config?.vaults ?? []).map(({ id }) => ({ id }));
498
+ jsonResponse(req, res, 200, { activeVault: vaults[0]?.id ?? null, vaults });
499
+ }
500
+
489
501
  // --- Route table ---
490
502
 
491
503
  function createRouteTable(context) {
@@ -494,6 +506,7 @@ function createRouteTable(context) {
494
506
  { method: 'POST', path: '/api/base/property-values', handler: handleBasePropertyValues },
495
507
  { method: 'POST', path: '/api/base/transform', handler: handleBaseTransform },
496
508
  { method: 'POST', path: '/api/base/export', handler: handleBaseExport },
509
+ { method: 'GET', path: '/api/vaults', handler: handleVaultList },
497
510
  { method: 'GET', path: '/api/files', handler: handleFileTree },
498
511
  { method: 'GET', path: '/api/comments/overview', handler: handleCommentOverview },
499
512
  { method: 'GET', path: '/api/file', handler: handleFileRead },
@@ -6,7 +6,7 @@ import { encodeAgentToolImage } from '../../shared/agent-tool-image.js';
6
6
  import { jsonResponse } from '../http/http-response.js';
7
7
  import { readRequestId } from '../http/http-request-helpers.js';
8
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 reference or diagram edits, use validate_document or render_diagram. Request inline verification when creating or editing Excalidraw. Delete and publish are unavailable.';
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
10
 
11
11
  function toolResult(value) {
12
12
  return {
@@ -26,6 +26,7 @@ async function imageToolResult(value) {
26
26
  };
27
27
  }
28
28
  async function optionalImageToolResult(value) {
29
+ if (value.svg) return imageToolResult(value);
29
30
  if (!value.verification?.svg) return toolResult(value);
30
31
  const { verification, ...result } = value;
31
32
  const { data, mimeType, structuredContent: encodedVerification } = await encodeAgentToolImage(verification);
@@ -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
 
@@ -764,9 +764,8 @@ export class VaultFileStore {
764
764
  return this.sidecarStore.readCommentThreads(filePath);
765
765
  }
766
766
 
767
- async readCommentOverview() {
768
- const snapshot = await this.scanWorkspaceState();
769
- const commentSupportedFilePaths = snapshot.filePaths.filter((filePath) => (
767
+ async readCommentOverview({ filePaths }) {
768
+ const commentSupportedFilePaths = filePaths.filter((filePath) => (
770
769
  supportsCommentsForFilePath(filePath)
771
770
  ));
772
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) => {
@@ -1,8 +1,15 @@
1
1
  export function createAgentToolRateLimiter(requestsPerMinute) {
2
2
  const limit = Math.max(1, Number.parseInt(requestsPerMinute, 10) || 120);
3
3
  const windows = new Map();
4
+ let nextSweepAt = 0;
4
5
  return (key) => {
5
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
+ }
6
13
  let window = windows.get(key);
7
14
  if (!window || timestamp >= window.resetAt) {
8
15
  window = { count: 0, resetAt: timestamp + 60_000 };
@@ -316,6 +316,47 @@ async function ensureRepositoryIdentity(vaultDir, config, options = {}) {
316
316
  });
317
317
  }
318
318
 
319
+ async function prepareVaultCheckout({ gitConfig, options = {}, repoUrl, vaultDir }) {
320
+ const commandEnv = gitConfig.commandEnv;
321
+ if (await pathExists(vaultDir)) {
322
+ if (!(await isDirectory(vaultDir))) {
323
+ throw new Error(`Vault path "${vaultDir}" exists but is not a directory.`);
324
+ }
325
+
326
+ if (await isGitRepository(vaultDir, options)) {
327
+ const checkoutState = await updateExistingCheckout(vaultDir, repoUrl, {
328
+ ...options,
329
+ commandEnv,
330
+ });
331
+ await ensureCollabMetadataGitExclude(vaultDir);
332
+ await ensureRepositoryIdentity(vaultDir, gitConfig, {
333
+ ...options,
334
+ commandEnv,
335
+ });
336
+
337
+ if (checkoutState?.syncSkipped) {
338
+ console.warn(`Skipping git sync for "${vaultDir}" because the existing checkout has uncommitted changes.`);
339
+ }
340
+
341
+ return;
342
+ }
343
+
344
+ if (await isDirectoryEmpty(vaultDir)) {
345
+ await cloneIntoVault(vaultDir, repoUrl, { ...options, commandEnv });
346
+ await ensureCollabMetadataGitExclude(vaultDir);
347
+ await ensureRepositoryIdentity(vaultDir, gitConfig, { ...options, commandEnv });
348
+ return;
349
+ }
350
+
351
+ throw new Error(`Refusing to initialize "${vaultDir}" because it is not empty and is not a git repository.`);
352
+ }
353
+
354
+ await ensureDirectory(dirname(vaultDir));
355
+ await cloneIntoVault(vaultDir, repoUrl, { ...options, commandEnv });
356
+ await ensureCollabMetadataGitExclude(vaultDir);
357
+ await ensureRepositoryIdentity(vaultDir, gitConfig, { ...options, commandEnv });
358
+ }
359
+
319
360
  export async function prepareConfigForStartup(config, options = {}) {
320
361
  const gitConfig = config.git ?? {
321
362
  cleanup: null,
@@ -346,59 +387,25 @@ export async function prepareConfigForStartup(config, options = {}) {
346
387
  return config;
347
388
  }
348
389
 
349
- if (await pathExists(config.vaultDir)) {
350
- if (!(await isDirectory(config.vaultDir))) {
351
- throw new Error(`Vault path "${config.vaultDir}" exists but is not a directory.`);
390
+ // ponytail: one checkout per mapped vault; unmapped vaults boot from disk untouched
391
+ const vaults = config.vaults?.length
392
+ ? config.vaults
393
+ : [{ dir: config.vaultDir, id: null, repoUrl: config.git.remote.repoUrl }];
394
+ for (const vault of vaults) {
395
+ if (!vault.repoUrl) {
396
+ continue;
352
397
  }
353
-
354
- if (await isGitRepository(config.vaultDir, options)) {
355
- const checkoutState = await updateExistingCheckout(config.vaultDir, config.git.remote.repoUrl, {
356
- ...options,
357
- commandEnv: config.git.commandEnv,
358
- });
359
- await ensureCollabMetadataGitExclude(config.vaultDir);
360
- await ensureRepositoryIdentity(config.vaultDir, config.git, {
361
- ...options,
362
- commandEnv: config.git.commandEnv,
363
- });
364
-
365
- if (checkoutState?.syncSkipped) {
366
- console.warn(
367
- `Skipping git sync for "${config.vaultDir}" because the existing checkout has uncommitted changes.`,
368
- );
369
- }
370
-
371
- return config;
372
- }
373
-
374
- if (await isDirectoryEmpty(config.vaultDir)) {
375
- await cloneIntoVault(config.vaultDir, config.git.remote.repoUrl, {
376
- ...options,
377
- commandEnv: config.git.commandEnv,
398
+ try {
399
+ await prepareVaultCheckout({
400
+ gitConfig: config.git,
401
+ options,
402
+ repoUrl: vault.repoUrl,
403
+ vaultDir: vault.dir,
378
404
  });
379
- await ensureCollabMetadataGitExclude(config.vaultDir);
380
- await ensureRepositoryIdentity(config.vaultDir, config.git, {
381
- ...options,
382
- commandEnv: config.git.commandEnv,
383
- });
384
- return config;
405
+ } catch (error) {
406
+ throw vault.id ? new Error(`Vault "${vault.id}": ${error.message}`) : error;
385
407
  }
386
-
387
- throw new Error(
388
- `Refusing to initialize "${config.vaultDir}" because it is not empty and is not a git repository.`,
389
- );
390
408
  }
391
-
392
- await ensureDirectory(dirname(config.vaultDir));
393
- await cloneIntoVault(config.vaultDir, config.git.remote.repoUrl, {
394
- ...options,
395
- commandEnv: config.git.commandEnv,
396
- });
397
- await ensureCollabMetadataGitExclude(config.vaultDir);
398
- await ensureRepositoryIdentity(config.vaultDir, config.git, {
399
- ...options,
400
- commandEnv: config.git.commandEnv,
401
- });
402
409
  return config;
403
410
  } catch (error) {
404
411
  await runtimeCleanup();