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
@@ -11,6 +11,7 @@ export const EXCALIDRAW_META_KEY = 'excalidraw-meta';
11
11
  export const EXCALIDRAW_ROOM_SCHEMA_VERSION = 1;
12
12
  export const EXCALIDRAW_ROOM_TEXT_KEY = 'codemirror';
13
13
  export const EXCALIDRAW_SCHEMA_VERSION_KEY = 'schemaVersion';
14
+ export const EXCALIDRAW_REPLACE_GENERATION_KEY = 'replaceGeneration';
14
15
 
15
16
  function createEmptyScene() {
16
17
  return {
@@ -222,6 +223,15 @@ export function isExcalidrawRoomDocStructured(ydoc) {
222
223
  return Number(meta.get(EXCALIDRAW_SCHEMA_VERSION_KEY)) === EXCALIDRAW_ROOM_SCHEMA_VERSION;
223
224
  }
224
225
 
226
+ export function readExcalidrawReplaceGeneration(ydoc) {
227
+ if (!ydoc) {
228
+ return 0;
229
+ }
230
+
231
+ const value = Number(ydoc.getMap(EXCALIDRAW_META_KEY).get(EXCALIDRAW_REPLACE_GENERATION_KEY));
232
+ return Number.isFinite(value) && value > 0 ? value : 0;
233
+ }
234
+
225
235
  export function ensureExcalidrawRoomSchema(ydoc) {
226
236
  const meta = ydoc.getMap(EXCALIDRAW_META_KEY);
227
237
  if (Number(meta.get(EXCALIDRAW_SCHEMA_VERSION_KEY)) !== EXCALIDRAW_ROOM_SCHEMA_VERSION) {
@@ -295,7 +305,7 @@ export function replaceExcalidrawRoomScene(ydoc, rawScene, {
295
305
  }
296
306
 
297
307
  const scene = normalizeScene(rawScene);
298
- ensureExcalidrawRoomSchema(ydoc);
308
+ const meta = ensureExcalidrawRoomSchema(ydoc);
299
309
 
300
310
  const elementsMap = ydoc.getMap(EXCALIDRAW_ELEMENTS_KEY);
301
311
  const filesMap = ydoc.getMap(EXCALIDRAW_FILES_KEY);
@@ -321,6 +331,7 @@ export function replaceExcalidrawRoomScene(ydoc, rawScene, {
321
331
  const nextAppState = normalizeAppState(scene.appState);
322
332
  appStateMap.set('gridSize', nextAppState.gridSize);
323
333
  appStateMap.set('viewBackgroundColor', nextAppState.viewBackgroundColor);
334
+ meta.set(EXCALIDRAW_REPLACE_GENERATION_KEY, readExcalidrawReplaceGeneration(ydoc) + 1);
324
335
 
325
336
  return scene;
326
337
  }
@@ -0,0 +1,13 @@
1
+ const WORD_CHARACTER = /[\p{L}\p{N}_]/u;
2
+
3
+ function isWordCharacterAt(value, index) {
4
+ if (index < 0 || index >= value.length) return false;
5
+ let start = index;
6
+ const codeUnit = value.charCodeAt(index);
7
+ if (index > 0 && codeUnit >= 0xDC00 && codeUnit <= 0xDFFF) start -= 1;
8
+ return WORD_CHARACTER.test(String.fromCodePoint(value.codePointAt(start)));
9
+ }
10
+
11
+ export function isWholeWordMatch(value, start, end) {
12
+ return !isWordCharacterAt(value, start - 1) && !isWordCharacterAt(value, end);
13
+ }
@@ -10,14 +10,19 @@ import { listRenderableDiagrams, resolveRenderableDiagram } from '../../domain/d
10
10
  import { createEditableContentRevision } from '../../domain/editable-content-revision.js';
11
11
  import { normalizeEditableText } from '../../domain/editable-text.js';
12
12
  import { applyExactTextChanges, resolveExactTextChanges } from '../../domain/exact-text-edits.js';
13
- import { applyAgentExcalidrawEdits, createAgentExcalidrawScene } from '../../domain/excalidraw-agent-scene.js';
13
+ import {
14
+ applyAgentExcalidrawEditsWithSummary,
15
+ createAgentExcalidrawScene,
16
+ } from '../../domain/excalidraw-agent-scene.js';
14
17
  import { inspectAgentExcalidrawScene, renderAgentExcalidrawSvg } from '../../domain/excalidraw-agent-verification.js';
15
- import { getVaultFileKind } from '../../domain/file-kind.js';
18
+ import { getVaultFileKind, isBaseFilePath } from '../../domain/file-kind.js';
19
+ import { isWholeWordMatch } from '../../domain/literal-text-search.js';
16
20
  import { createWikiTargetIndex } from '../../domain/wiki-link-resolver.js';
17
21
  import {
18
22
  classifyPublicVideoEmbed,
19
23
  isPublicVideoEmbedCandidate,
20
24
  } from '../../domain/video-embed.js';
25
+ import { isPlainObject, parseBaseSource } from '../domain/bases/base-definition.js';
21
26
  import {
22
27
  collectMarkdownImageSources,
23
28
  collectMarkdownReferences,
@@ -32,6 +37,35 @@ const MAX_REPLACEMENTS = 20;
32
37
  const MAX_REPLACEMENT_CHARACTERS = 50_000;
33
38
  const EMBEDDABLE_KINDS = new Set(['base', 'drawio', 'excalidraw', 'image', 'mermaid', 'plantuml']);
34
39
 
40
+ function assertValidAgentBaseContent(path, content) {
41
+ if (!isBaseFilePath(path)) return;
42
+ try {
43
+ const raw = parseBaseSource(content);
44
+ if (raw != null && !isPlainObject(raw)) {
45
+ throw new Error('Base source must be a YAML object');
46
+ }
47
+ } catch (error) {
48
+ throw createAgentContentError('AGENT_INVALID_BASE', error.message || 'Base source is invalid', 400);
49
+ }
50
+ }
51
+
52
+ function toAgentBaseQueryResult(path, { columns, rows, view }, limit) {
53
+ return {
54
+ columns: columns.map(({ id, label }) => ({ id, label })),
55
+ path,
56
+ rows: rows.slice(0, limit).map((row) => ({
57
+ cells: Object.fromEntries(columns.map(({ id }) => [id, String(row.cells[id]?.text ?? '')])),
58
+ path: row.path,
59
+ })),
60
+ totalRows: rows.length,
61
+ truncated: rows.length > limit,
62
+ view: {
63
+ name: view.name,
64
+ type: view.type,
65
+ },
66
+ };
67
+ }
68
+
35
69
  function createAgentContentError(code, message, statusCode = 400) {
36
70
  const error = new Error(message);
37
71
  error.code = code;
@@ -101,7 +135,7 @@ function createInlineExcalidrawVerification(scene, options, { deferRender = fals
101
135
  return verification;
102
136
  }
103
137
 
104
- function searchLiveText(content, query, maxSnippets = 5) {
138
+ function searchLiveText(content, query, maxSnippets = 5, wholeWord = false) {
105
139
  const normalizedQuery = query.toLocaleLowerCase();
106
140
  const snippets = [];
107
141
  let matchCount = 0;
@@ -109,17 +143,19 @@ function searchLiveText(content, query, maxSnippets = 5) {
109
143
  const normalizedLine = lineText.toLocaleLowerCase();
110
144
  let start = normalizedLine.indexOf(normalizedQuery);
111
145
  while (start >= 0) {
112
- matchCount += 1;
113
- if (snippets.length < maxSnippets) {
114
- const snippetStart = Math.max(0, start - 90);
115
- const snippetEnd = Math.min(lineText.length, start + query.length + 90);
116
- snippets.push({
117
- column: start + 1,
118
- line: lineIndex + 1,
119
- matchEnd: start - snippetStart + query.length + (snippetStart > 0 ? 3 : 0),
120
- matchStart: start - snippetStart + (snippetStart > 0 ? 3 : 0),
121
- text: `${snippetStart > 0 ? '...' : ''}${lineText.slice(snippetStart, snippetEnd)}${snippetEnd < lineText.length ? '...' : ''}`,
122
- });
146
+ if (!wholeWord || isWholeWordMatch(normalizedLine, start, start + normalizedQuery.length)) {
147
+ matchCount += 1;
148
+ if (snippets.length < maxSnippets) {
149
+ const snippetStart = Math.max(0, start - 90);
150
+ const snippetEnd = Math.min(lineText.length, start + query.length + 90);
151
+ snippets.push({
152
+ column: start + 1,
153
+ line: lineIndex + 1,
154
+ matchEnd: start - snippetStart + query.length + (snippetStart > 0 ? 3 : 0),
155
+ matchStart: start - snippetStart + (snippetStart > 0 ? 3 : 0),
156
+ text: `${snippetStart > 0 ? '...' : ''}${lineText.slice(snippetStart, snippetEnd)}${snippetEnd < lineText.length ? '...' : ''}`,
157
+ });
158
+ }
123
159
  }
124
160
  start = normalizedLine.indexOf(normalizedQuery, start + Math.max(query.length, 1));
125
161
  }
@@ -130,6 +166,7 @@ function searchLiveText(content, query, maxSnippets = 5) {
130
166
  export class AgentContentService {
131
167
  constructor({
132
168
  backlinkIndex = null,
169
+ baseQueryService = null,
133
170
  plantUmlRenderer = null,
134
171
  roomRegistry,
135
172
  searchService,
@@ -137,6 +174,7 @@ export class AgentContentService {
137
174
  workspaceMutationCoordinator,
138
175
  }) {
139
176
  this.backlinkIndex = backlinkIndex;
177
+ this.baseQueryService = baseQueryService;
140
178
  this.plantUmlRenderer = plantUmlRenderer;
141
179
  this.roomRegistry = roomRegistry;
142
180
  this.searchService = searchService;
@@ -214,31 +252,13 @@ export class AgentContentService {
214
252
  };
215
253
  }
216
254
 
217
- async renderExcalidraw(actor, {
218
- format = 'png',
219
- padding = 32,
220
- path,
221
- scale = 1,
222
- } = {}) {
223
- const current = await this.readExcalidrawScene(actor, path);
224
- const result = {
225
- elementCount: current.scene.elements.filter((element) => !element.isDeleted).length,
226
- format,
227
- path: current.path,
228
- revision: current.revision,
229
- scene: current.scene,
230
- };
231
- if (actor.origin !== 'webmcp') {
232
- Object.assign(result, renderAgentExcalidrawSvg(current.scene, { padding, scale }));
233
- }
234
- return result;
235
- }
236
255
 
237
256
  async verifyExcalidraw(actor, {
238
257
  format = 'png',
239
258
  inspectOcclusion = true,
240
259
  padding = 32,
241
260
  path,
261
+ render = true,
242
262
  scale = 1,
243
263
  } = {}) {
244
264
  const current = await this.readExcalidrawScene(actor, path);
@@ -250,52 +270,45 @@ export class AgentContentService {
250
270
  elementCount: inspection.elementCount,
251
271
  format,
252
272
  inspection,
273
+ layout: inspection.layout,
253
274
  path: current.path,
254
275
  revision: current.revision,
255
- scene: current.scene,
276
+ valid: inspection.valid,
256
277
  };
278
+ if (!render) return result;
279
+
280
+ result.scene = current.scene;
257
281
  if (actor.origin !== 'webmcp') {
258
282
  Object.assign(result, renderAgentExcalidrawSvg(current.scene, { padding, scale }));
259
283
  }
260
284
  return result;
261
285
  }
262
286
 
263
- listDocuments(actor, { cursor = '', kinds = [], limit = 100, prefix = '' } = {}) {
287
+ listWorkspaceEntries(actor, {
288
+ cursor = '',
289
+ kinds = [],
290
+ limit = 100,
291
+ prefix = '',
292
+ pathQuery = '',
293
+ } = {}) {
264
294
  requireScope(actor, 'vault:read');
265
295
  const normalizedPrefix = normalizeWorkspacePath(prefix);
296
+ const normalizedPathQuery = String(pathQuery).trim().toLocaleLowerCase();
266
297
  const kindFilter = new Set(Array.isArray(kinds) ? kinds : []);
267
298
  const state = this.workspaceMutationCoordinator?.workspaceState;
268
- const documents = Array.from(state?.entries?.values?.() ?? [])
269
- .filter((entry) => entry.nodeType !== 'directory' && isAgentReadablePath(entry.path))
270
- .filter((entry) => !normalizedPrefix || entry.path === normalizedPrefix || entry.path.startsWith(`${normalizedPrefix}/`))
271
- .filter((entry) => kindFilter.size === 0 || kindFilter.has(getVaultFileKind(entry.path)))
272
- .sort((left, right) => compareWorkspacePaths(left.path, right.path));
273
- const start = cursor ? Math.max(0, documents.findIndex((entry) => entry.path === cursor) + 1) : 0;
274
- const pageSize = clampInteger(limit, 100, 1, 200);
275
- const page = documents.slice(start, start + pageSize).map((entry) => {
276
- const metadata = state?.metadata?.get?.(entry.path);
277
- return {
278
- kind: getVaultFileKind(entry.path),
279
- mtimeMs: Number(metadata?.mtimeMs ?? entry.mtimeMs ?? 0),
280
- path: entry.path,
281
- size: Number(metadata?.size ?? 0),
282
- };
283
- });
284
- const truncated = start + page.length < documents.length;
285
- return {
286
- documents: page,
287
- nextCursor: truncated ? page.at(-1)?.path ?? null : null,
288
- truncated,
289
- };
290
- }
291
- listWorkspaceEntries(actor, { cursor = '', limit = 100, prefix = '' } = {}) {
292
- requireScope(actor, 'vault:read');
293
- const normalizedPrefix = normalizeWorkspacePath(prefix);
294
- const state = this.workspaceMutationCoordinator?.workspaceState;
295
299
  const entries = Array.from(state?.entries?.values?.() ?? [])
296
300
  .filter((entry) => !normalizedPrefix || entry.path === normalizedPrefix || entry.path.startsWith(`${normalizedPrefix}/`))
301
+ .filter((entry) => kindFilter.size === 0 || kindFilter.has(getVaultFileKind(entry.path)))
302
+ .filter((entry) => !normalizedPathQuery || entry.path.toLocaleLowerCase().includes(normalizedPathQuery))
297
303
  .sort((left, right) => compareWorkspacePaths(left.path, right.path));
298
- const start = cursor ? Math.max(0, entries.findIndex((entry) => entry.path === cursor) + 1) : 0;
304
+ let start = 0;
305
+ if (cursor) {
306
+ const cursorIndex = entries.findIndex((entry) => entry.path === cursor);
307
+ if (cursorIndex < 0) {
308
+ throw createAgentContentError('AGENT_CURSOR_INVALID', 'Pagination cursor is no longer valid', 400);
309
+ }
310
+ start = cursorIndex + 1;
311
+ }
299
312
  const pageSize = clampInteger(limit, 100, 1, 200);
300
313
  const page = entries.slice(start, start + pageSize).map((entry) => {
301
314
  const isDirectory = entry.nodeType === 'directory';
@@ -322,21 +335,46 @@ export class AgentContentService {
322
335
  }
323
336
 
324
337
 
325
- async searchVault(actor, { limit = 50, query = '', signal = null } = {}) {
338
+ async searchVault(actor, {
339
+ kinds = [],
340
+ limit = 50,
341
+ maxSnippetsPerFile = 5,
342
+ prefix = '',
343
+ query = '',
344
+ wholeWord = false,
345
+ signal = null,
346
+ } = {}) {
326
347
  requireScope(actor, 'vault:read');
327
348
  const normalizedQuery = String(query ?? '').trim().slice(0, 500);
328
- const result = await this.searchService.search({ limit, query: normalizedQuery, signal });
349
+ const normalizedPrefix = normalizeWorkspacePath(prefix);
350
+ const kindFilter = new Set(Array.isArray(kinds) ? kinds : []);
351
+ const snippetLimit = clampInteger(maxSnippetsPerFile, 5, 1, 10);
352
+ const result = await this.searchService.search({
353
+ kinds: [...kindFilter],
354
+ limit,
355
+ maxSnippetsPerFile: snippetLimit,
356
+ prefix: normalizedPrefix,
357
+ query: normalizedQuery,
358
+ wholeWord,
359
+ signal,
360
+ });
329
361
  if (normalizedQuery.length < 2) return result;
330
362
 
331
363
  const liveFiles = [];
332
364
  for (const [path, room] of this.roomRegistry?.getRooms?.() ?? []) {
333
- if (!isAgentReadablePath(path) || !room.isHydrated?.()) continue;
365
+ const kind = getVaultFileKind(path);
366
+ if (
367
+ !isAgentReadablePath(path)
368
+ || !room.isHydrated?.()
369
+ || (normalizedPrefix && path !== normalizedPrefix && !path.startsWith(`${normalizedPrefix}/`))
370
+ || (kindFilter.size > 0 && !kindFilter.has(kind))
371
+ ) continue;
334
372
  const content = room.readEditableContent?.();
335
373
  if (content === null || content === undefined) continue;
336
374
  if (content.length > MAX_AGENT_READ_SOURCE_CHARACTERS) continue;
337
- const live = searchLiveText(content, normalizedQuery);
375
+ const live = searchLiveText(content, normalizedQuery, snippetLimit, wholeWord);
338
376
  if (live.matchCount > 0) {
339
- liveFiles.push({ file: path, kind: getVaultFileKind(path), ...live });
377
+ liveFiles.push({ file: path, kind, ...live });
340
378
  }
341
379
  }
342
380
  if (liveFiles.length === 0) return result;
@@ -474,6 +512,32 @@ export class AgentContentService {
474
512
  };
475
513
  }
476
514
 
515
+ async queryBase(actor, { limit = 50, path, search = '', view = '' } = {}) {
516
+ requireScope(actor, 'vault:read');
517
+ const normalizedPath = normalizeWorkspacePath(path);
518
+ if (!isBaseFilePath(normalizedPath)) {
519
+ throw createAgentContentError('AGENT_UNSUPPORTED_DOCUMENT', 'Base queries require a .base path', 400);
520
+ }
521
+ const content = await this.readCurrentContent(normalizedPath);
522
+ if (!this.baseQueryService?.query) {
523
+ throw createAgentContentError('AGENT_BASE_QUERY_UNAVAILABLE', 'Bases query service is unavailable', 503);
524
+ }
525
+ const pageSize = clampInteger(limit, 50, 1, 200);
526
+ try {
527
+ const result = await this.baseQueryService.query({
528
+ basePath: normalizedPath,
529
+ search,
530
+ source: content,
531
+ sourcePath: normalizedPath,
532
+ view,
533
+ });
534
+ return toAgentBaseQueryResult(normalizedPath, result, pageSize);
535
+ } catch (error) {
536
+ if (error?.code?.startsWith('AGENT_')) throw error;
537
+ throw createAgentContentError('AGENT_BASE_QUERY_FAILED', error.message || 'Failed to query base', 400);
538
+ }
539
+ }
540
+
477
541
  async renderDiagram(actor, { format = 'png', path, startLine } = {}) {
478
542
  requireScope(actor, 'vault:read');
479
543
  const normalizedPath = normalizeWorkspacePath(path);
@@ -552,15 +616,14 @@ export class AgentContentService {
552
616
  error.code = error.code?.startsWith('EXACT_EDIT_') ? 'AGENT_REPLACEMENT_MISMATCH' : error.code;
553
617
  throw error;
554
618
  }
619
+ const nextContent = applyExactTextChanges(content, changes);
620
+ assertValidAgentBaseContent(normalizedPath, nextContent);
555
621
  const room = this.roomRegistry?.get?.(normalizedPath);
556
- let nextContent;
557
622
  if (room) {
558
623
  room.applyExactTextChanges(changes, {
559
624
  origin: createCollaborationOrigin(actor),
560
625
  });
561
- nextContent = room.readEditableContent();
562
626
  } else {
563
- nextContent = applyExactTextChanges(content, changes);
564
627
  const result = await this.workspaceMutationCoordinator.writeEditableContent({
565
628
  content: nextContent,
566
629
  origin: getMutationOrigin(actor),
@@ -573,7 +636,7 @@ export class AgentContentService {
573
636
  return {
574
637
  path: normalizedPath,
575
638
  replacementCount: changes.length,
576
- revision: await createEditableContentRevision(nextContent),
639
+ revision: await createEditableContentRevision(room ? room.readEditableContent() : nextContent),
577
640
  };
578
641
  });
579
642
  }
@@ -644,6 +707,7 @@ export class AgentContentService {
644
707
  async editExcalidraw(actor, {
645
708
  create = [],
646
709
  delete: remove = [],
710
+ normalizeTextPlacement,
647
711
  path,
648
712
  reorder = [],
649
713
  replace = [],
@@ -666,11 +730,12 @@ export class AgentContentService {
666
730
  if (revision !== await createEditableContentRevision(content)) {
667
731
  throw createAgentContentError('AGENT_REVISION_CONFLICT', 'Document changed; read it again before editing', 409);
668
732
  }
669
- let scene;
733
+ let edit;
670
734
  try {
671
- scene = applyAgentExcalidrawEdits(JSON.parse(content), {
735
+ edit = applyAgentExcalidrawEditsWithSummary(JSON.parse(content), {
672
736
  create,
673
737
  delete: remove,
738
+ normalizeTextPlacement,
674
739
  reorder,
675
740
  replace,
676
741
  update,
@@ -685,6 +750,7 @@ export class AgentContentService {
685
750
  }
686
751
  throw error;
687
752
  }
753
+ const { reflowed, scene } = edit;
688
754
  const room = this.roomRegistry?.get?.(normalizedPath);
689
755
  let nextContent;
690
756
  if (room) {
@@ -714,6 +780,7 @@ export class AgentContentService {
714
780
  elementCount: storedScene.elements.filter((element) => !element.isDeleted).length,
715
781
  path: normalizedPath,
716
782
  reordered: reorder.length,
783
+ reflowed,
717
784
  replaced: replace.length,
718
785
  revision: await createEditableContentRevision(nextContent),
719
786
  translated: translate?.ids?.length ?? 0,
@@ -738,6 +805,7 @@ export class AgentContentService {
738
805
  if (normalizedContent.length > MAX_DOCUMENT_CHARACTERS) {
739
806
  throw createAgentContentError('AGENT_DOCUMENT_TOO_LARGE', 'Document is too large for agent creation', 413);
740
807
  }
808
+ assertValidAgentBaseContent(normalizedPath, normalizedContent);
741
809
  return this.runForPath(normalizedPath, async () => {
742
810
  const result = await this.workspaceMutationCoordinator.createFile({
743
811
  content: normalizedContent,
@@ -1,4 +1,4 @@
1
- import { resolve } from 'path';
1
+ import { basename, isAbsolute, relative, resolve } from 'path';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { fileURLToPath } from 'url';
4
4
 
@@ -199,6 +199,94 @@ export function resolveCliVaultDir(positionals = [], env = process.env) {
199
199
  return resolve(positionals[0] || env.COLLABMD_VAULT_DIR || '.');
200
200
  }
201
201
 
202
+ const VAULT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
203
+
204
+ const VAULT_ID_HINT = 'Use letters, numbers, ".", "_", or "-" starting with a letter or number.';
205
+
206
+ export function parseVaultList(rawValue) {
207
+ return normalizeCsvList(rawValue).map((entry) => {
208
+ const separatorIndex = entry.indexOf('=');
209
+ const hasName = separatorIndex > 0;
210
+ const rawDir = (hasName ? entry.slice(separatorIndex + 1) : entry).trim();
211
+ if (!rawDir) {
212
+ throw new Error(`Vault entry "${entry}" is missing a directory path.`);
213
+ }
214
+ const dir = resolve(rawDir);
215
+ const id = (hasName ? entry.slice(0, separatorIndex).trim() : basename(dir));
216
+ if (!VAULT_ID_PATTERN.test(id)) {
217
+ throw new Error(`Invalid vault id "${id}". ${VAULT_ID_HINT}`);
218
+ }
219
+ return { id, dir };
220
+ });
221
+ }
222
+
223
+ export function resolveConfiguredVaults(overrides = {}, env = process.env) {
224
+ if (Array.isArray(overrides.vaults)) {
225
+ return overrides.vaults.map(({ id, dir, repoUrl }) => {
226
+ if (!VAULT_ID_PATTERN.test(String(id ?? ''))) {
227
+ throw new Error(`Invalid vault id "${id}". ${VAULT_ID_HINT}`);
228
+ }
229
+ return { id, dir: resolve(dir), repoUrl: normalizeOptionalString(repoUrl) };
230
+ });
231
+ }
232
+ // ponytail: explicit directory (CLI positional) wins over the operator list
233
+ if (overrides.vaultDir) {
234
+ const dir = resolve(overrides.vaultDir);
235
+ return [{ id: basename(dir), dir }];
236
+ }
237
+ const rawList = normalizeOptionalString(env.COLLABMD_VAULTS);
238
+ if (!rawList) {
239
+ const dir = resolveConfiguredVaultDir(overrides, env);
240
+ return [{ id: basename(dir), dir }];
241
+ }
242
+ const vaults = parseVaultList(rawList);
243
+ const seenIds = new Set();
244
+ for (const vault of vaults) {
245
+ if (seenIds.has(vault.id)) {
246
+ throw new Error(`Duplicate vault id "${vault.id}" in COLLABMD_VAULTS.`);
247
+ }
248
+ seenIds.add(vault.id);
249
+ }
250
+ for (let i = 0; i < vaults.length; i += 1) {
251
+ for (let j = i + 1; j < vaults.length; j += 1) {
252
+ const between = relative(vaults[i].dir, vaults[j].dir);
253
+ if (between === '' || (!between.startsWith('..') && !isAbsolute(between))) {
254
+ throw new Error(`Vaults "${vaults[i].id}" and "${vaults[j].id}" overlap. Vault directories must not nest.`);
255
+ }
256
+ }
257
+ }
258
+ return vaults;
259
+ }
260
+
261
+ export function mangleVaultIdForEnv(vaultId) {
262
+ return String(vaultId ?? '').toUpperCase().replace(/[^A-Z0-9]/g, '_');
263
+ }
264
+
265
+ // ponytail: explicit repoUrl wins, then COLLABMD_GIT_REPO_URL_<ID>, then the shared URL for the primary
266
+ export function resolveVaultRepoUrls(vaultDefs = [], overrides = {}, env = process.env) {
267
+ const globalRepoUrl = normalizeOptionalString(overrides.remote?.repoUrl ?? overrides.git?.remote?.repoUrl ?? env.COLLABMD_GIT_REPO_URL);
268
+ const bySuffix = new Map();
269
+ for (const def of vaultDefs) {
270
+ const suffix = mangleVaultIdForEnv(def.id);
271
+ if (!bySuffix.has(suffix)) {
272
+ bySuffix.set(suffix, []);
273
+ }
274
+ bySuffix.get(suffix).push(def.id);
275
+ }
276
+ return vaultDefs.map((def, index) => {
277
+ if (def.repoUrl) {
278
+ return def;
279
+ }
280
+ const suffix = mangleVaultIdForEnv(def.id);
281
+ const varName = `COLLABMD_GIT_REPO_URL_${suffix}`;
282
+ const perVaultUrl = normalizeOptionalString(env[varName]);
283
+ if (perVaultUrl && bySuffix.get(suffix).length > 1) {
284
+ throw new Error(`Ambiguous git remote: vaults ${bySuffix.get(suffix).map((id) => `"${id}"`).join(' and ')} share ${varName}.`);
285
+ }
286
+ return { ...def, repoUrl: perVaultUrl || (index === 0 ? globalRepoUrl : '') };
287
+ });
288
+ }
289
+
202
290
  function getDefaultHost(nodeEnv) {
203
291
  return nodeEnv === 'production' ? '0.0.0.0' : '127.0.0.1';
204
292
  }
@@ -208,7 +296,7 @@ function resolveOptionalPath(filePath) {
208
296
  return normalized ? resolve(normalized) : '';
209
297
  }
210
298
 
211
- function loadGitConfig(overrides = {}) {
299
+ function loadGitConfig(overrides = {}, { vaultRepoUrls = [] } = {}) {
212
300
  const remoteOverrides = overrides.remote ?? {};
213
301
  const identityOverrides = overrides.identity ?? {};
214
302
  const enabled = overrides.enabled ?? (process.env.COLLABMD_GIT_ENABLED !== 'false');
@@ -240,7 +328,7 @@ function loadGitConfig(overrides = {}) {
240
328
  remoteOverrides.sshKnownHostsFile
241
329
  ?? process.env.COLLABMD_GIT_SSH_KNOWN_HOSTS_FILE,
242
330
  );
243
- const remoteEnabled = repoUrl.length > 0;
331
+ const remoteEnabled = repoUrl.length > 0 || vaultRepoUrls.some((entry) => String(entry ?? '').length > 0);
244
332
 
245
333
  if (remoteEnabled && !sshPrivateKeyFile && !sshPrivateKeyBase64) {
246
334
  throw new Error(
@@ -452,7 +540,9 @@ function resolvePublicDir(nodeEnv) {
452
540
 
453
541
  export function loadConfig(overrides = {}) {
454
542
  const nodeEnv = process.env.NODE_ENV || 'development';
455
- const vaultDir = resolveConfiguredVaultDir(overrides);
543
+ const vaults = resolveVaultRepoUrls(resolveConfiguredVaults(overrides), overrides);
544
+ // ponytail: vaultDir stays the primary vault; other vaults resolve through the registry
545
+ const vaultDir = overrides.vaultDir || vaults[0].dir;
456
546
  const basePath = normalizeAppBasePath(process.env.BASE_PATH || '');
457
547
  const publicDir = resolvePublicDir(nodeEnv);
458
548
  const authOverrides = overrides.auth ?? {};
@@ -469,7 +559,7 @@ export function loadConfig(overrides = {}) {
469
559
  const oidc = authStrategy === AUTH_STRATEGY_OIDC
470
560
  ? loadOidcConfig(authOverrides.oidc, { basePath })
471
561
  : null;
472
- const git = loadGitConfig(overrides.git);
562
+ const git = loadGitConfig(overrides.git, { vaultRepoUrls: vaults.map((vault) => vault.repoUrl) });
473
563
  const hosted = loadHostedConfig(overrides.hosted, { authStrategy, vaultDir });
474
564
  const agentAccess = loadAgentAccessConfig(overrides.agentAccess, {
475
565
  basePath,
@@ -531,6 +621,7 @@ export function loadConfig(overrides = {}) {
531
621
  plantumlServerUrl: process.env.PLANTUML_SERVER_URL || 'https://www.plantuml.com/plantuml',
532
622
  publicDir,
533
623
  vaultDir,
624
+ vaults,
534
625
  publicWsBaseUrl: process.env.PUBLIC_WS_BASE_URL || '',
535
626
  testWsRoomHydrateDelayMs: parsePositiveInt(process.env.TEST_WS_ROOM_HYDRATE_DELAY_MS, 0),
536
627
  wikiLinkAutoCreate: process.env.COLLABMD_WIKI_LINK_AUTO_CREATE !== 'false',