collabmd 0.1.54 → 0.1.55

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 (447) hide show
  1. package/bin/collabmd.js +19 -38
  2. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-cMeDxAEL.js +1 -0
  3. package/dist/client/assets/{abnfDiagram-VCTEODGH-DxNxad6-.js → abnfDiagram-VCTEODGH-D2UdmYvj.js} +1 -1
  4. package/dist/client/assets/{abnfDiagram-O67JEVCF-Dwt6a0Ds.js → abnfDiagram-YUKMZFIV-DbmU4Q-X.js} +1 -1
  5. package/dist/client/assets/api-client-utils-C5ESDKMG.js +1 -0
  6. package/dist/client/assets/architecture-7GRP2DOG-BBwRXFv3.js +1 -1
  7. package/dist/client/assets/architecture-WOLXFQ4H-C0NxYiG7.js +1 -0
  8. package/dist/client/assets/{architectureDiagram-NJMV4G6O-D5CGiX3G.js → architectureDiagram-47P4ROYG-C7OjXK9S.js} +3 -3
  9. package/dist/client/assets/{architectureDiagram-5GKGNRK7-C1uvg5id.js → architectureDiagram-5GKGNRK7-CSiUzzeN.js} +1 -1
  10. package/dist/client/assets/base-CaIEJUF9.css +1 -0
  11. package/dist/client/assets/{blockDiagram-BEXU5L5S-BgTM0var.js → blockDiagram-E7TT5TSB-DMG-YlZw.js} +3 -3
  12. package/dist/client/assets/{blockDiagram-I7D4REHJ-B2YonsoG.js → blockDiagram-I7D4REHJ-sXfAgK2w.js} +1 -1
  13. package/dist/client/assets/{browser-BKLM0ThC-BCLQGPD6-K2seJgRL.js → browser-BKLM0ThC-BCLQGPD6-CcMAHZXi.js} +1 -1
  14. package/dist/client/assets/{c4Diagram-7LVT6UL2-r4IwomZm.js → c4Diagram-7LVT6UL2-C88V_K-8.js} +1 -1
  15. package/dist/client/assets/{c4Diagram-YGBWAQC7-_xZPrNkB.js → c4Diagram-CRA5TL53-D3F9ElJv.js} +2 -2
  16. package/dist/client/assets/canvasEditor-BJkwGzO1.css +1 -0
  17. package/dist/client/assets/canvasEditor-sBK7KfrD.js +1 -0
  18. package/dist/client/assets/{chunk-6AZGARVD--pTGpDnx.js → chunk-24IY7LWP-flnn6SWX.js} +1 -1
  19. package/dist/client/assets/chunk-2BW5OAIV-CNFO1U_e.js +10 -0
  20. package/dist/client/assets/{chunk-2E4U76K2-CIQUuV9n.js → chunk-2E4U76K2-DEnS5IbF.js} +1 -1
  21. package/dist/client/assets/{chunk-5V3GS4D5-B5uC2oxu.js → chunk-3M4EKCLJ-D-sZGCtO.js} +1 -1
  22. package/dist/client/assets/chunk-3YJQHVM4-Ctp__8EK.js +2 -0
  23. package/dist/client/assets/{chunk-7PRAP22T-9uTvtc_-.js → chunk-4EA7E6EY-bU4wRJot.js} +1 -1
  24. package/dist/client/assets/{chunk-4HAMMTFA-q0ldNVvr.js → chunk-4HAMMTFA-CQy6Skzw.js} +1 -1
  25. package/dist/client/assets/{chunk-6K3QC6MW-JnuvEGV4.js → chunk-4S7OKTRW-BpUW13a3.js} +1 -1
  26. package/dist/client/assets/{chunk-ICYGCRZG-odvlDZyA.js → chunk-53FOQ5SW-5lPdGYP4.js} +1 -1
  27. package/dist/client/assets/{chunk-75Z2AOVW-DitkSoSG.js → chunk-75Z2AOVW-BRdhvVTZ.js} +1 -1
  28. package/dist/client/assets/{chunk-GWA4HPMP-CGmv2yIq.js → chunk-7TKQ45FW-rA2u-WUl.js} +1 -1
  29. package/dist/client/assets/{chunk-GTNCS2PH-ChgkzEIi.js → chunk-AW2ZBBNX-DL0KGAdi.js} +3 -3
  30. package/dist/client/assets/{chunk-747NJXEK-BjqqAsS9.js → chunk-BP2KR52E-DAQ1pzDV.js} +1 -1
  31. package/dist/client/assets/{chunk-CLGD4ZFX-BfYJtJm1.js → chunk-CLGD4ZFX-DJiSE0gD.js} +1 -1
  32. package/dist/client/assets/{chunk-5DYCD2WN-BKWCKnK-.js → chunk-DBDB3WZW-CXleNlok.js} +1 -1
  33. package/dist/client/assets/{chunk-DU6HZSFF-CWlP1Dk_.js → chunk-DU6HZSFF-C-18UZkS.js} +1 -1
  34. package/dist/client/assets/{chunk-MBY4JIJT-DTJ4UcAm.js → chunk-E2ZNV5FY-D_07zfWd.js} +3 -3
  35. package/dist/client/assets/chunk-EU5HNXII-CETVNUXF.js +213 -0
  36. package/dist/client/assets/{chunk-F27PBJKO-DPcsPcEs.js → chunk-F27PBJKO-_beIJos4.js} +1 -1
  37. package/dist/client/assets/{chunk-2ZTRR5NV-DcPRfelM.js → chunk-F6S3BTY2-DVWKCAHp.js} +1 -1
  38. package/dist/client/assets/{chunk-ISPTBLVO-BMsDq9Ha.js → chunk-FLFP27SU-CydzbSsY.js} +2 -2
  39. package/dist/client/assets/chunk-FVRAUYC3-C7b9SJ81.js +1 -0
  40. package/dist/client/assets/{chunk-GMAD6QVW-Bgk8qnty.js → chunk-GMAD6QVW-DnZH7DxV.js} +1 -1
  41. package/dist/client/assets/{chunk-GVQU2GXP-CQ8cl-Uu.js → chunk-GVQU2GXP-B0Vm415C.js} +1 -1
  42. package/dist/client/assets/chunk-H5A3YXKD-ChP7mNJq.js +41 -0
  43. package/dist/client/assets/{chunk-742MDFTN-D1nh6vNv.js → chunk-HJ2JQQFS-DQX7RePR.js} +1 -1
  44. package/dist/client/assets/{chunk-NETBCI7D-CmUwDWUZ.js → chunk-HTAEGDNF-C0PA_N-c.js} +1 -1
  45. package/dist/client/assets/{chunk-IMKFNOWR-CBqxfpcP.js → chunk-IMKFNOWR-DoO8IHzF.js} +1 -1
  46. package/dist/client/assets/{chunk-IH6LHLGP-BNevEHZK.js → chunk-KPI5JJXK-B2ld5-w4.js} +1 -1
  47. package/dist/client/assets/{chunk-WEXAMYUT-DDlVNp8J.js → chunk-KQW6MTUR-OQ4MyMr_.js} +1 -1
  48. package/dist/client/assets/{chunk-L3NEJ4N5-BflzkdTI.js → chunk-L3NEJ4N5-CvHossEU.js} +1 -1
  49. package/dist/client/assets/chunk-NGNAAXSQ-DqoPQk1a.js +136 -0
  50. package/dist/client/assets/{chunk-UA2S7LBM-DicYDjDM.js → chunk-NTY3LDVX-CVWLK_fh.js} +1 -1
  51. package/dist/client/assets/{chunk-UY3FDG6J-QT-rkt0y.js → chunk-OD3NTWWA-Dz9nCUGX.js} +1 -1
  52. package/dist/client/assets/{chunk-OSK3NFVY-DqeKV_pg.js → chunk-OSK3NFVY-C3JOcBao.js} +1 -1
  53. package/dist/client/assets/{chunk-P2QGCYS3-BA--DhpW.js → chunk-P2QGCYS3-Bfo8qS8r.js} +1 -1
  54. package/dist/client/assets/{chunk-POPQ4Y6H-V_NEc45n.js → chunk-POPQ4Y6H-sv6rCftH.js} +1 -1
  55. package/dist/client/assets/{chunk-PWAF6VOD-D_kLse-N.js → chunk-PWAF6VOD-B-AT-L2H.js} +1 -1
  56. package/dist/client/assets/{chunk-3Z5EZCMW-BAnA6eQ7.js → chunk-QNH66VMT-Cb9xxTwQ.js} +1 -1
  57. package/dist/client/assets/{chunk-SHT3W25Y-YM3S-A_M.js → chunk-SHT3W25Y-C1lu518T.js} +1 -1
  58. package/dist/client/assets/{chunk-GNY47TPC-CTrH5O5R.js → chunk-SVEVUXB4-BnM-LXop.js} +1 -1
  59. package/dist/client/assets/{chunk-SVP7TREG-DdNhDOmW.js → chunk-SVP7TREG-CKqt0syj.js} +1 -1
  60. package/dist/client/assets/{chunk-TICWLB2K-BGGgCr4x.js → chunk-TICWLB2K-D2ZnWAfF.js} +1 -1
  61. package/dist/client/assets/{chunk-TLUHSLCS-DCZhIDYA.js → chunk-TLUHSLCS-BMIhqv1X.js} +1 -1
  62. package/dist/client/assets/{chunk-6EIED4P4-DBVWq7Tz.js → chunk-TPMEZKFX-DIPHIqGb.js} +1 -1
  63. package/dist/client/assets/{chunk-6TQVIW2G-BSj0l_pu.js → chunk-VPELOWWC-DXayM28-.js} +1 -1
  64. package/dist/client/assets/chunk-VPRB5NB3-BqaJfj_v.js +127 -0
  65. package/dist/client/assets/{chunk-I5DQTOEV-aBZooNp1.js → chunk-VTWWFHGB-SZnJiyWY.js} +1 -1
  66. package/dist/client/assets/{chunk-KI3K4JFJ-FTtDwx3-.js → chunk-VZTHESGH-eHyXmK8W.js} +1 -1
  67. package/dist/client/assets/{chunk-7INBJB4K-CDmiHbaX.js → chunk-XC4XBNZT-D9oehSn8.js} +20 -20
  68. package/dist/client/assets/{chunk-XHIXRSVI-DN_fEwws.js → chunk-YK26KJH5-DVy3MGMd.js} +1 -1
  69. package/dist/client/assets/{chunk-6AEJRKK7-DTVZj5bY.js → chunk-Z6ETV63D-DOcrnz-P.js} +1 -1
  70. package/dist/client/assets/{chunk-OUJLGHUK-75UXlPjl.js → chunk-ZO67DCNQ-BAOMIkLF.js} +1 -1
  71. package/dist/client/assets/classDiagram-ZZMXUADV-BmETdFmC.js +1 -0
  72. package/dist/client/assets/{classDiagram-v2-NBCMYWYE-3TQORq33.js → classDiagram-v2-K4WV4PDN-eaadfJDB.js} +3 -3
  73. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BmETdFmC.js +1 -0
  74. package/dist/client/assets/{comment-markdown-renderer-Bxi_JRSR.js → comment-markdown-renderer-CpBKaj7H.js} +1 -1
  75. package/dist/client/assets/comment-thread-store-DUQsWtnu.js +1 -0
  76. package/dist/client/assets/comment-threads-DnfkLVJA.js +4 -0
  77. package/dist/client/assets/comment-ui-shared-D_pgPUti.js +7 -0
  78. package/dist/client/assets/cynefin-EF2NZ3EQ-DVkJeZ8i.js +1 -0
  79. package/dist/client/assets/cynefin-OW5HDTMX-CF3N9j1_.js +1 -1
  80. package/dist/client/assets/{cynefinDiagram-VND7K2PF-DwfMZ3vk.js → cynefinDiagram-3GCD6N5R-DjpAsBHC.js} +1 -1
  81. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-DTnLZaO7.js → cynefinDiagram-5FMLGOSQ-D2rFQG67.js} +1 -1
  82. package/dist/client/assets/dagre-C-rnJpZF.js +1 -0
  83. package/dist/client/assets/{dagre-GXQ25YYZ-Vtyx08Qh.js → dagre-GXQ25YYZ-Cku9eia9.js} +2 -2
  84. package/dist/client/assets/{dagre-6A5THRUB-DewyAGK6.js → dagre-W4DXFKR2-DOMOIsPd.js} +2 -2
  85. package/dist/client/assets/deferred-collab-C9aa9cvT.css +1 -0
  86. package/dist/client/assets/deferred-git-BPQ-UgrN.css +1 -0
  87. package/dist/client/assets/deferred-preview-B-RebLry.css +1 -0
  88. package/dist/client/assets/{diagram-22UHCM2B-DbZirFfl.js → diagram-2UJZ2QOL-D8WvnEyx.js} +6 -6
  89. package/dist/client/assets/{diagram-3UASUU5V-DmhdYv6_.js → diagram-OVF4WLC6-D8_escYE.js} +2 -2
  90. package/dist/client/assets/{diagram-CDSNMT55-D_qyS11R.js → diagram-PFPMY2P6-B1izZfrN.js} +3 -3
  91. package/dist/client/assets/{diagram-S7CK7UJ4-CGTzfo2f.js → diagram-S7CK7UJ4-BzicH2t-.js} +1 -1
  92. package/dist/client/assets/{diagram-MLGK6HIB-DIBG6Ivu.js → diagram-UMYRVEAY-Djf7WDjZ.js} +1 -1
  93. package/dist/client/assets/{diagram-UQ7AKVKN-CWZS8QtB.js → diagram-UQ7AKVKN-DqX4zTtr.js} +1 -1
  94. package/dist/client/assets/{diagram-VSXAHHWV-DaO1nOZF.js → diagram-VSXAHHWV-DnVbfI4Y.js} +1 -1
  95. package/dist/client/assets/{diagram-VX7I27RA-B54P6Cyf.js → diagram-VX7I27RA-D-Dj0TQC.js} +1 -1
  96. package/dist/client/assets/{diagram-MPIPVDR6-D9XsALDV.js → diagram-YEKJPTXX-B40bP3Yr.js} +2 -2
  97. package/dist/client/assets/{diagram-Z3DM3KII-Cl2EXiXp.js → diagram-Z3DM3KII-_iT7Uz5p.js} +1 -1
  98. package/dist/client/assets/diagram-ZIFT7M5P-BUUK0oNw.js +3 -0
  99. package/dist/client/assets/{direct-engine-DVLMOJWp-C-YL5NFb.js → direct-engine-DVLMOJWp-DWtWIifK.js} +1 -1
  100. package/dist/client/assets/dist-26Ce-5t4.js +1 -0
  101. package/dist/client/assets/dist-8MLNn-I6.js +1 -0
  102. package/dist/client/assets/dist-Amm5Pr1C.js +1 -0
  103. package/dist/client/assets/dist-BXXPaoUV.js +1 -0
  104. package/dist/client/assets/{dist-CoXN2D3R.js → dist-Bkb-_VdB.js} +1 -1
  105. package/dist/client/assets/dist-Bl4yuUS9.js +1 -0
  106. package/dist/client/assets/{dist-lw5TGjI6.js → dist-C2CGvCPd.js} +1 -1
  107. package/dist/client/assets/dist-C2niyEh0.js +1 -0
  108. package/dist/client/assets/{dist-DOHWxIty.js → dist-CFCSUmJk.js} +1 -1
  109. package/dist/client/assets/dist-CHUI56fT.js +6 -0
  110. package/dist/client/assets/dist-CJh3Qrid.js +13 -0
  111. package/dist/client/assets/{dist-Ch6Sr9KF.js → dist-CKxETpSC.js} +3 -3
  112. package/dist/client/assets/dist-CSHJthAI.js +2 -0
  113. package/dist/client/assets/dist-CbKnZGN4.js +1 -0
  114. package/dist/client/assets/{dist-KrdpB_GB.js → dist-Cik4RJXj.js} +1 -1
  115. package/dist/client/assets/{dist-uk11ih8u.js → dist-CqkAY6Ot.js} +2 -2
  116. package/dist/client/assets/dist-D2ql2LCd.js +1 -0
  117. package/dist/client/assets/{dist-BpAUe9sL.js → dist-D47MOYFN.js} +1 -1
  118. package/dist/client/assets/dist-DBhUaexM.js +1 -0
  119. package/dist/client/assets/dist-DJux6Vc5.js +1 -0
  120. package/dist/client/assets/{dist-9Eodxf4G.js → dist-DLNdMWPH.js} +1 -1
  121. package/dist/client/assets/dist-DPJj-Y3l.js +1 -0
  122. package/dist/client/assets/{dist-BSAZ-Hek.js → dist-DRYFMufe.js} +6 -6
  123. package/dist/client/assets/{dist-BrKhPlc9.js → dist-DTGcVSU8.js} +1 -1
  124. package/dist/client/assets/dist-DlOxjzWi.js +9 -0
  125. package/dist/client/assets/{dist-BT9gJXCb.js → dist-DogjjM_B.js} +1 -1
  126. package/dist/client/assets/dist-Dyv_RvyB.js +23 -0
  127. package/dist/client/assets/dist-FUFeH5Cx.js +1 -0
  128. package/dist/client/assets/dist-It70ktCU.js +1 -0
  129. package/dist/client/assets/dist-QMvcnJHf.js +1 -0
  130. package/dist/client/assets/dist-QN1K2czv.js +11 -0
  131. package/dist/client/assets/dist-W8ilOKl3.js +1 -0
  132. package/dist/client/assets/dist-_17-t9qP.js +1 -0
  133. package/dist/client/assets/{dist-DeCV9FU4.js → dist-uE774WWs.js} +1 -1
  134. package/dist/client/assets/document-formatter-DtXmKZcy.js +1 -0
  135. package/dist/client/assets/drawioEditor-DO6IOaJ1.js +9 -0
  136. package/dist/client/assets/{ebnfDiagram-PWID7BFC-PfC84FyI.js → ebnfDiagram-PWID7BFC-IemGPf9X.js} +1 -1
  137. package/dist/client/assets/{ebnfDiagram-ZINNZB2B-DYvm_QtE.js → ebnfDiagram-VR2GEFS7-9fXqy1DI.js} +1 -1
  138. package/dist/client/assets/editor-session-CPsqXY_A.js +13 -0
  139. package/dist/client/assets/elk-IJKZMXRS-DsbrbBYg.js +27 -0
  140. package/dist/client/assets/embedded-editor-base-C44ZcCZv.css +1 -0
  141. package/dist/client/assets/{embedpdf-TkbBYowM.js → embedpdf-BfUI-3pv.js} +1 -1
  142. package/dist/client/assets/{embedpdf-cl9qiF45-itpgqvGY.js → embedpdf-cl9qiF45-CLMxJTMP.js} +2 -2
  143. package/dist/client/assets/en-7ZVUCEYH-C_VXKxxb.js +1 -0
  144. package/dist/client/assets/{erDiagram-OPXOYQCR-o8GRv8A_.js → erDiagram-O2IAPWRE-Cdadm-HN.js} +2 -2
  145. package/dist/client/assets/{erDiagram-RLTQ6QDP-C9cJl5NB.js → erDiagram-RLTQ6QDP-CGGmjm8t.js} +1 -1
  146. package/dist/client/assets/eventmodeling-K75KTNOO-BWBlZ5cR.js +1 -0
  147. package/dist/client/assets/eventmodeling-NTZA5JFV-CDy1bN6j.js +1 -1
  148. package/dist/client/assets/excalidraw-element-link-NQnskRkm.js +1 -0
  149. package/dist/client/assets/excalidraw-scene-DLlw4jyc.js +1 -0
  150. package/dist/client/assets/excalidrawEditor-DiKOIudt.css +1 -0
  151. package/dist/client/assets/excalidrawEditor-W2lZ5Mej.js +9 -0
  152. package/dist/client/assets/export-page-Bomh9oEr.js +46 -0
  153. package/dist/client/assets/exportDocument-BFIOECJ3.js +2 -0
  154. package/dist/client/assets/exportDocument-D0mONgQ4.css +1 -0
  155. package/dist/client/assets/file-kind-BGxTVHan.js +1 -0
  156. package/dist/client/assets/{file-search-BA8o_gs0.js → file-search-Dk2O14Vw.js} +1 -1
  157. package/dist/client/assets/flowDiagram-HODETNUW-DcVVYJUZ.js +1 -0
  158. package/dist/client/assets/flowDiagram-OXPTDLAJ-Dy6y46oF.js +1 -0
  159. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-x40PW0Ah.js → ganttDiagram-EL5Y4UJY-Duu4KnsU.js} +1 -1
  160. package/dist/client/assets/ganttDiagram-R7TSEDQI-BWy52pjn.js +292 -0
  161. package/dist/client/assets/gitGraph-4MIJSDKK-B-rpDYbz.js +1 -1
  162. package/dist/client/assets/gitGraph-VSP46ZUC-1499lQAI.js +1 -0
  163. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-ahsNaZsp.js → gitGraphDiagram-WWUBYQGX-CaJ0vC1a.js} +1 -1
  164. package/dist/client/assets/gitGraphDiagram-XJZIOB7I-DJwp9ilx.js +106 -0
  165. package/dist/client/assets/graphlib-DS17s2tU.js +1 -0
  166. package/dist/client/assets/image-6XY3GD3F-DCWbu6d4.js +1 -0
  167. package/dist/client/assets/image-lightbox-controller-DAcXEXxT.js +184 -0
  168. package/dist/client/assets/index-CglpXOg7.css +1 -0
  169. package/dist/client/assets/index-D3WGkxfI.js +960 -0
  170. package/dist/client/assets/info-A6RAGUB7-BlutK7BT.js +1 -1
  171. package/dist/client/assets/info-OHQRW6UA-BDFQOo4H.js +1 -0
  172. package/dist/client/assets/{infoDiagram-27XIBGKW-MrZyptIy.js → infoDiagram-27XIBGKW-DBJh7QOu.js} +1 -1
  173. package/dist/client/assets/{infoDiagram-VRGFBTTK-KkUjDRAQ.js → infoDiagram-5W2HQ5XZ-DmWsqJ0w.js} +1 -1
  174. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-Bnt9yM0O.js → ishikawaDiagram-5VMMS53U-CeEbSJem.js} +1 -1
  175. package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-Di9BcpOY.js → ishikawaDiagram-K3B6WC7H-DH1NI35G.js} +2 -2
  176. package/dist/client/assets/{journeyDiagram-3NMN7TZE-Bl0abK1r.js → journeyDiagram-3NMN7TZE-BoIEEr6U.js} +1 -1
  177. package/dist/client/assets/{journeyDiagram-ZHPQQLJL-J-sGrs9e.js → journeyDiagram-COXZFDF6-CnHV2f9V.js} +3 -3
  178. package/dist/client/assets/{kanban-definition-PNTS6WVX-5ZDV_yIa.js → kanban-definition-P3RFRI5V-Cxvn5ZAG.js} +4 -4
  179. package/dist/client/assets/{kanban-definition-UXKFOSKX-DMgUfNt0.js → kanban-definition-UXKFOSKX-BY16Tgbr.js} +1 -1
  180. package/dist/client/assets/keyboard-shortcuts-BWNCBJqw.js +1 -0
  181. package/dist/client/assets/lobby-presence-DNNXcuwR.js +1 -0
  182. package/dist/client/assets/{markdown-CZ1tYEW8.js → markdown-DU84620G.js} +1 -1
  183. package/dist/client/assets/markdown-headings-zYEUahfW.js +41 -0
  184. package/dist/client/assets/{markdown-math-CyyBVuDO.js → markdown-math-B96cnrz1.js} +11 -11
  185. package/dist/client/assets/{mermaid-parser.core-Bpogunsh.js → mermaid-parser.core-R-uwU5kf.js} +3 -3
  186. package/dist/client/assets/{mermaid-parser.core-DBy--Jc0.js → mermaid-parser.core-mE6t1qEO.js} +1 -1
  187. package/dist/client/assets/mermaid.core-D8Z6LN7O.js +10 -0
  188. package/dist/client/assets/{mindmap-definition-NLK3R4M7-ByVb-0vj.js → mindmap-definition-LZFPQGKD-DVfFenfJ.js} +3 -3
  189. package/dist/client/assets/{mindmap-definition-YA3MSWOX-DBZN5_GH.js → mindmap-definition-YA3MSWOX-DtiE80UJ.js} +1 -1
  190. package/dist/client/assets/packet-AYTQ26CC-DvbY8dI6.js +1 -1
  191. package/dist/client/assets/packet-JDAUHWVQ-DJ9K2MA4.js +1 -0
  192. package/dist/client/assets/{pegDiagram-GJSIUBJH-aost1sSO.js → pegDiagram-BGZESJAR-DxfvEcwv.js} +1 -1
  193. package/dist/client/assets/{pegDiagram-XKGWAZYB-DRo8CZu3.js → pegDiagram-XKGWAZYB-CyozY-Kt.js} +1 -1
  194. package/dist/client/assets/pie-WAS4IAKB-DWSm9SSD.js +1 -1
  195. package/dist/client/assets/pie-XZMESJXO-CQIQasY-.js +1 -0
  196. package/dist/client/assets/{pieDiagram-5QR66LMP-BICdpEuz.js → pieDiagram-CAPJLFHJ-CRlMcrv3.js} +2 -2
  197. package/dist/client/assets/{pieDiagram-E7YTZNPT-CZThaHsc.js → pieDiagram-E7YTZNPT-BRdmTkDq.js} +1 -1
  198. package/dist/client/assets/preload-helper-CYtfOYgs.js +1 -0
  199. package/dist/client/assets/preview-render-compiler-D_aJv7Ew.js +3 -0
  200. package/dist/client/assets/{preview-render-worker-BA4VK_GY.js → preview-render-worker-dFNyrVyB.js} +46 -42
  201. package/dist/client/assets/prod-ItolaHmf.js +145 -0
  202. package/dist/client/assets/prod-rdly4JJQ.js +1 -0
  203. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-C5iowkl_.js → quadrantDiagram-AXDQQJYC-7QyPIXkF.js} +1 -1
  204. package/dist/client/assets/{quadrantDiagram-O4NWA36T-Bgx5bF97.js → quadrantDiagram-GDMTTRAM-DE30uqTl.js} +3 -3
  205. package/dist/client/assets/quick-switcher-controller-DsK70I7K.js +1 -0
  206. package/dist/client/assets/radar-ABXABTNO-ByfpCXh9.js +1 -0
  207. package/dist/client/assets/radar-RG4KPBEZ-BfNQUEQy.js +1 -1
  208. package/dist/client/assets/railroad-74A4TZTK-BaQ6U6eJ.js +1 -1
  209. package/dist/client/assets/railroad-I3PHUGI6-CTUn9HhI.js +1 -0
  210. package/dist/client/assets/railroad-abnf-HS5TGJTU-BJ3KZw7J.js +1 -1
  211. package/dist/client/assets/railroad-abnf-LNEFI6M7-Ct-b-y0F.js +1 -0
  212. package/dist/client/assets/railroad-ebnf-DWYD2UWJ-BZMYMWOe.js +1 -0
  213. package/dist/client/assets/railroad-ebnf-LZEXJU2U-DA0sEq7w.js +1 -1
  214. package/dist/client/assets/railroad-peg-JR7BVNR7-Dj23PxYc.js +1 -0
  215. package/dist/client/assets/railroad-peg-WCYAUIDC-DCmlICzO.js +1 -1
  216. package/dist/client/assets/{railroadDiagram-O6MQD6OU-BTt_rKjT.js → railroadDiagram-O6MQD6OU-BPk3RS2D.js} +1 -1
  217. package/dist/client/assets/{railroadDiagram-XR7U4H2S-DbVoNgSz.js → railroadDiagram-SM67HX2B-CZRXJ647.js} +1 -1
  218. package/dist/client/assets/{requirementDiagram-BXWQKSXE-BkvazG7r.js → requirementDiagram-BXWQKSXE-BRwfym6z.js} +1 -1
  219. package/dist/client/assets/{requirementDiagram-PLB6GJNP-BT0j9C40.js → requirementDiagram-X7JNWC4A-BofCuLJA.js} +4 -4
  220. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-C_IemB9h.js → sankeyDiagram-P5KCCOFB-D4LcrKpW.js} +1 -1
  221. package/dist/client/assets/{sankeyDiagram-IPEJSGJF-X1BCUIrf.js → sankeyDiagram-UM26HJRW-CLKMDbej.js} +3 -3
  222. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-CxFBgLGd.js → sequenceDiagram-WJ2MYXX4-DQjtv-Bs.js} +1 -1
  223. package/dist/client/assets/sequenceDiagram-ZO4K6R2Y-CDP_m6ma.js +169 -0
  224. package/dist/client/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  225. package/dist/client/assets/sizeCapture-INFHLROL-BMR1ovSU.js +1 -0
  226. package/dist/client/assets/src-D5mvpivG.js +2 -0
  227. package/dist/client/assets/{standalone-DbyFjvTU.js → standalone-D_lg5NC9.js} +1 -1
  228. package/dist/client/assets/{stateDiagram-D77RDMKH-BaSQ6Owj.js → stateDiagram-D77RDMKH-DSMvV-kF.js} +1 -1
  229. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-ClmOOUsT.js +1 -0
  230. package/dist/client/assets/{stateDiagram-v2-GCMORJYK-CsVcfwVp.js → stateDiagram-v2-TBUQTH76-Dc5-FKzd.js} +2 -2
  231. package/dist/client/assets/{swimlanes-42K2YHIH-CALFEmiS.js → swimlanes-42K2YHIH-BUz31lO3.js} +1 -1
  232. package/dist/client/assets/{swimlanes-2SLR337P-CnYTVqRX.js → swimlanes-N4OXWK64-Dd3dFdPD.js} +1 -1
  233. package/dist/client/assets/swimlanesDiagram-K3J5GTZL-Bz9gFdls.js +8 -0
  234. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DoDs3zod.js +8 -0
  235. package/dist/client/assets/{timeline-definition-24CTP7MA-zse-5Dbm.js → timeline-definition-24CTP7MA-BvqCvSjy.js} +1 -1
  236. package/dist/client/assets/{timeline-definition-EJHVYXUP-BhqPlKkN.js → timeline-definition-YOQAKGHF-D2XWPSLs.js} +3 -3
  237. package/dist/client/assets/treeView-D4JQ5SDB-DcX7Bx0H.js +1 -0
  238. package/dist/client/assets/treeView-Q6P3EWNA-BvHOzbu9.js +1 -1
  239. package/dist/client/assets/treemap-SAJKECNS-BcCHmcAX.js +1 -0
  240. package/dist/client/assets/treemap-WGGIJYW6-oety7paS.js +1 -1
  241. package/dist/client/assets/usecaseDiagram-VIAY4XPW-CDe-IMjS.js +328 -0
  242. package/dist/client/assets/vault-api-client-DrRW0QwO.js +7 -0
  243. package/dist/client/assets/{vennDiagram-4TSXK5OY-DgHr6cJD.js → vennDiagram-4TSXK5OY-BW6Qp12d.js} +1 -1
  244. package/dist/client/assets/{vennDiagram-UO4OBE2U-BRwLn2Q1.js → vennDiagram-BLWOH2XV-KxIPKpHi.js} +3 -3
  245. package/dist/client/assets/wardley-7MLQ67FV-DOahSwbZ.js +1 -0
  246. package/dist/client/assets/wardley-WFR3VGLG-BdwDpX_I.js +1 -1
  247. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-9A60XZis.js → wardleyDiagram-VM6X3IG4-BoCETVsK.js} +1 -1
  248. package/dist/client/assets/{wardleyDiagram-VNRHLVJA-B_tMcVFG.js → wardleyDiagram-YMQ3BMBF-BNYqEy7M.js} +4 -4
  249. package/dist/client/assets/{wiki-link-resolver-Dch88erO.js → wiki-link-resolver-BCdGUpdu.js} +1 -1
  250. package/dist/client/assets/{worker-engine-BCCrxWYm-CX0qJ_cG.js → worker-engine-BCCrxWYm-1fphds7O.js} +1 -1
  251. package/dist/client/assets/workspace-sync-client-C_P9wtjf.js +1 -0
  252. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-D00iy-wB.js → xychartDiagram-S5SC5T6Z-eB5Fu9P7.js} +1 -1
  253. package/dist/client/assets/xychartDiagram-TAQBALBS-Sv6aaptV.js +7 -0
  254. package/dist/client/assets/yjs-Jd9fna_Y.js +4 -0
  255. package/dist/client/assets/yjs-provider-reset-guard-Cqu0Z6xH.js +1 -0
  256. package/dist/client/canvas-editor.html +16 -0
  257. package/dist/client/drawio-editor.html +7 -6
  258. package/dist/client/excalidraw-editor.html +31 -30
  259. package/dist/client/export-document.html +4 -3
  260. package/dist/client/index.html +2 -2
  261. package/package.json +27 -29
  262. package/scripts/local-compose.mjs +101 -0
  263. package/src/client/app/canvas-editor.html +13 -0
  264. package/src/client/application/app-shell/git-feature.js +3 -2
  265. package/src/client/application/app-shell/ui-feature-identity.js +1 -0
  266. package/src/client/application/app-shell/ui-feature-shell.js +2 -0
  267. package/src/client/application/app-shell/ui-feature-tab-activity.js +4 -0
  268. package/src/client/application/app-shell/workspace-feature.js +8 -34
  269. package/src/client/application/diagram-chrome.js +8 -11
  270. package/src/client/application/diagram-preview-hydrator.js +5 -5
  271. package/src/client/application/mermaid-preview-hydrator.js +3 -2
  272. package/src/client/application/plantuml-preview-hydrator.js +6 -0
  273. package/src/client/application/preview-render-compiler.js +34 -98
  274. package/src/client/application/preview-render-executor.js +3 -0
  275. package/src/client/application/preview-render-worker.js +2 -0
  276. package/src/client/application/preview-renderer.js +9 -5
  277. package/src/client/application/workspace-coordinator.js +18 -10
  278. package/src/client/application/workspace-preview-controller.js +105 -158
  279. package/src/client/application/workspace-route-controller.js +29 -54
  280. package/src/client/bootstrap/canvas-markdown-preview.js +87 -0
  281. package/src/client/bootstrap/collabmd-app-shell.js +28 -13
  282. package/src/client/canvas-editor.js +143 -0
  283. package/src/client/domain/canvas-view.js +50 -0
  284. package/src/client/domain/excalidraw-scene.js +4 -49
  285. package/src/client/domain/highlight-runtime.js +0 -4
  286. package/src/client/domain/markdown-formatting.js +12 -94
  287. package/src/client/domain/markdown-headings.js +98 -0
  288. package/src/client/domain/wiki-link-completions.js +42 -10
  289. package/src/client/infrastructure/browser-preferences-port.js +27 -33
  290. package/src/client/infrastructure/canvas-room-client.js +210 -0
  291. package/src/client/infrastructure/canvas-text-editor.js +36 -0
  292. package/src/client/infrastructure/comment-thread-store.js +19 -77
  293. package/src/client/infrastructure/editor-view-adapter.js +0 -30
  294. package/src/client/infrastructure/excalidraw-room-client.js +22 -10
  295. package/src/client/infrastructure/hosted-api-client.js +4 -2
  296. package/src/client/infrastructure/vault-api-client.js +4 -4
  297. package/src/client/presentation/canvas-editor-view.js +1028 -0
  298. package/src/client/presentation/canvas-embed-controller.js +116 -0
  299. package/src/client/presentation/canvas-picker.js +111 -0
  300. package/src/client/presentation/drawio-embed-controller.js +1 -3
  301. package/src/client/presentation/excalidraw-embed-controller.js +10 -3
  302. package/src/client/presentation/file-action-controller.js +37 -0
  303. package/src/client/presentation/file-explorer-controller.js +1 -2
  304. package/src/client/presentation/file-explorer-view.js +7 -1
  305. package/src/client/presentation/file-icon-svg.js +1 -1
  306. package/src/client/presentation/file-tree-state.js +4 -1
  307. package/src/client/presentation/image-lightbox-controller.js +1 -5
  308. package/src/client/presentation/team-settings-controller.js +44 -10
  309. package/src/client/styles/components/actions.css +4 -16
  310. package/src/client/styles/components/surfaces.css +0 -7
  311. package/src/client/styles/features/comment-card.css +1 -2
  312. package/src/client/styles/features/comment-markdown.css +0 -18
  313. package/src/client/styles/features/diagram-preview.css +0 -18
  314. package/src/client/styles/features/git-branch.css +0 -4
  315. package/src/client/styles/foundation/themes.css +6 -0
  316. package/src/client/styles/foundation/utilities.css +1 -2
  317. package/src/client/styles/layout/editor-page.css +0 -13
  318. package/src/client/styles/layout/responsive.css +2 -7
  319. package/src/client/styles/layout/shell.css +13 -1
  320. package/src/client/styles/layout/view-modes.css +1 -0
  321. package/src/client/styles/surfaces/canvas-editor.css +239 -0
  322. package/src/domain/canvas-room-codec.js +359 -0
  323. package/src/domain/collabmd-content-capabilities.js +10 -1
  324. package/src/domain/comment-threads.js +49 -5
  325. package/src/domain/excalidraw-room-codec.js +23 -73
  326. package/src/domain/excalidraw-scene.js +48 -0
  327. package/src/domain/file-kind.js +13 -1
  328. package/src/server/application/workspace-reconciliation.js +0 -14
  329. package/src/server/domain/backlink-index.js +1 -36
  330. package/src/server/domain/bases/base-index-snapshot-store.js +41 -24
  331. package/src/server/domain/bases/base-query-service.js +1 -47
  332. package/src/server/domain/collaboration/collaboration-room.js +149 -15
  333. package/src/server/domain/collaboration/room-registry.js +7 -7
  334. package/src/server/domain/hosted-workspace.js +29 -2
  335. package/src/server/domain/plantuml-encoder.js +7 -43
  336. package/src/server/infrastructure/git/diff-service.js +1 -5
  337. package/src/server/infrastructure/git/history-service.js +18 -2
  338. package/src/server/infrastructure/git/untracked-files.js +1 -1
  339. package/src/server/infrastructure/http/create-git-api-command-handler.js +60 -149
  340. package/src/server/infrastructure/http/create-hosted-api-handler.js +5 -2
  341. package/src/server/infrastructure/http/create-vault-api-query-handler.js +2 -2
  342. package/src/server/infrastructure/http/http-response.js +2 -36
  343. package/src/server/infrastructure/http/request-body.js +14 -49
  344. package/src/server/infrastructure/persistence/hosted-metadata-store.js +12 -3
  345. package/src/server/infrastructure/persistence/path-utils.js +8 -2
  346. package/src/server/infrastructure/persistence/vault-file-store.js +26 -60
  347. package/src/server/{infrastructure/git → shared}/image-mime.js +2 -2
  348. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-kJfwukbn.js +0 -1
  349. package/dist/client/assets/_basePickBy-QJXUw_pr.js +0 -1
  350. package/dist/client/assets/_baseUniq-DR4vVjyC.js +0 -1
  351. package/dist/client/assets/architecture-7GRP2DOG-DJVtYNt-.js +0 -1
  352. package/dist/client/assets/browser-utils-S4QYY31r.js +0 -1
  353. package/dist/client/assets/chunk-3FUC2YCW-8tZlhTGX.js +0 -1
  354. package/dist/client/assets/chunk-7M6MHVWA-BDakkknV.js +0 -213
  355. package/dist/client/assets/chunk-FOHPRMQF-Dmmo5Kak.js +0 -161
  356. package/dist/client/assets/chunk-O7XYJQB3-D0_ZY2za.js +0 -126
  357. package/dist/client/assets/chunk-T5WUORNS-DD7KlyY6.js +0 -40
  358. package/dist/client/assets/chunk-Z7XXMR3K-P4Vaq8hD.js +0 -10
  359. package/dist/client/assets/chunk-ZIGJFQKS-b8OUHKK5.js +0 -2
  360. package/dist/client/assets/classDiagram-ZZMXUADV-QLbh_Nkf.js +0 -1
  361. package/dist/client/assets/classDiagram-v2-VYDZK3BY-QLbh_Nkf.js +0 -1
  362. package/dist/client/assets/comment-thread-store-CHvy8GF8.js +0 -1
  363. package/dist/client/assets/comment-threads-nJhK1yfc.js +0 -4
  364. package/dist/client/assets/cynefin-OW5HDTMX-e-Quc9Yl.js +0 -1
  365. package/dist/client/assets/dagre-D7FiCLLP.js +0 -1
  366. package/dist/client/assets/deferred-collab-D4cxEdad.css +0 -1
  367. package/dist/client/assets/deferred-git-BHKtkFYi.css +0 -1
  368. package/dist/client/assets/deferred-preview-BAXYgf4T.css +0 -1
  369. package/dist/client/assets/diagram-ATOU4E4O-B5uX-jVO.js +0 -3
  370. package/dist/client/assets/dist-B2ZNQifU.js +0 -1
  371. package/dist/client/assets/dist-B6QCMNze.js +0 -1
  372. package/dist/client/assets/dist-BIAv19LO.js +0 -1
  373. package/dist/client/assets/dist-BKYp1-dl.js +0 -13
  374. package/dist/client/assets/dist-BSTbcioM.js +0 -11
  375. package/dist/client/assets/dist-BTVg1m-V.js +0 -1
  376. package/dist/client/assets/dist-Bi9ZIYXq.js +0 -9
  377. package/dist/client/assets/dist-Bqo-XRVG.js +0 -1
  378. package/dist/client/assets/dist-CBsvKPcT.js +0 -1
  379. package/dist/client/assets/dist-CJBYh9Wy.js +0 -23
  380. package/dist/client/assets/dist-CRwfjtwz.js +0 -2
  381. package/dist/client/assets/dist-CX7Kc61C.js +0 -1
  382. package/dist/client/assets/dist-CYfPeupF.js +0 -1
  383. package/dist/client/assets/dist-CucpLxUY.js +0 -1
  384. package/dist/client/assets/dist-DHBMeCxC.js +0 -6
  385. package/dist/client/assets/dist-DLEg9d4u.js +0 -1
  386. package/dist/client/assets/dist-DYFBD-wW.js +0 -1
  387. package/dist/client/assets/dist-DugWGOjQ.js +0 -1
  388. package/dist/client/assets/dist-NNrRnB-f.js +0 -1
  389. package/dist/client/assets/dist-PUxZqhFe.js +0 -1
  390. package/dist/client/assets/dist-cYiJMWHJ.js +0 -1
  391. package/dist/client/assets/dist-iKC7go4m.js +0 -1
  392. package/dist/client/assets/document-formatter-6I63vstk.js +0 -1
  393. package/dist/client/assets/drawioEditor-DNTjsjzJ.js +0 -9
  394. package/dist/client/assets/editor-session-D8GGkJak.js +0 -14
  395. package/dist/client/assets/elk-276RUBZZ-B8LB3Pac.js +0 -27
  396. package/dist/client/assets/embedded-editor-base-elU0Avik.css +0 -1
  397. package/dist/client/assets/en-JTHJ2SIP-DBz9bRq4.js +0 -1
  398. package/dist/client/assets/eventmodeling-NTZA5JFV-Dxtv5D-P.js +0 -1
  399. package/dist/client/assets/excalidraw-element-link-BRZOTIeI.js +0 -7
  400. package/dist/client/assets/excalidraw-scene-6uROebca.js +0 -1
  401. package/dist/client/assets/excalidrawEditor-BCTFp_CV.css +0 -1
  402. package/dist/client/assets/excalidrawEditor-D0orhhku.js +0 -9
  403. package/dist/client/assets/export-page-CVJNMERq.js +0 -46
  404. package/dist/client/assets/exportDocument-Ba-n1X4U.css +0 -1
  405. package/dist/client/assets/exportDocument-DSshnmnZ.js +0 -2
  406. package/dist/client/assets/file-kind-BwMIcZbi.js +0 -1
  407. package/dist/client/assets/flowDiagram-HODETNUW-Bq4470NR.js +0 -1
  408. package/dist/client/assets/flowDiagram-KWPJA3E3-DQG9qGiU.js +0 -1
  409. package/dist/client/assets/ganttDiagram-FUAMR5RP-BQpsI7gQ.js +0 -292
  410. package/dist/client/assets/gitGraph-4MIJSDKK-ZaBIE4Lb.js +0 -1
  411. package/dist/client/assets/gitGraphDiagram-X574FWY7-wbs_2m9f.js +0 -106
  412. package/dist/client/assets/graphlib-C9Tl7QrK.js +0 -1
  413. package/dist/client/assets/image-I42VHMUI-B2-c_ifV.js +0 -1
  414. package/dist/client/assets/index-BCgNcVNs.css +0 -1
  415. package/dist/client/assets/index-BpmR5Qqk.js +0 -1140
  416. package/dist/client/assets/info-A6RAGUB7-BcGxhjED.js +0 -1
  417. package/dist/client/assets/lobby-presence-KJrYhMdN.js +0 -1
  418. package/dist/client/assets/mermaid.core-BeOUPE3Q.js +0 -10
  419. package/dist/client/assets/packet-AYTQ26CC-CqpSjTWl.js +0 -1
  420. package/dist/client/assets/pie-WAS4IAKB-Bg2eCNl5.js +0 -1
  421. package/dist/client/assets/preload-helper-BAlEavIC.js +0 -1
  422. package/dist/client/assets/preview-render-compiler-BmWQStaL.js +0 -43
  423. package/dist/client/assets/prod-CA0ie9yD.js +0 -145
  424. package/dist/client/assets/prod-yKJZ3E4s.js +0 -1
  425. package/dist/client/assets/quick-switcher-controller-B5vT9Vj5.js +0 -1
  426. package/dist/client/assets/radar-RG4KPBEZ-DxExotg6.js +0 -1
  427. package/dist/client/assets/railroad-74A4TZTK-FfHmeIQk.js +0 -1
  428. package/dist/client/assets/railroad-abnf-HS5TGJTU-CLkdDRsJ.js +0 -1
  429. package/dist/client/assets/railroad-ebnf-LZEXJU2U-B162zvcG.js +0 -1
  430. package/dist/client/assets/railroad-peg-WCYAUIDC-CGs5GeJ5.js +0 -1
  431. package/dist/client/assets/sequenceDiagram-PO4LG4MO-B-2QfXhV.js +0 -169
  432. package/dist/client/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
  433. package/dist/client/assets/sizeCapture-INFHLROL-DrzwYt5z.js +0 -1
  434. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-CLlwrdvU.js +0 -1
  435. package/dist/client/assets/swimlanesDiagram-TC7HE7FX-Bh4tmz27.js +0 -8
  436. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-xhehUG9e.js +0 -8
  437. package/dist/client/assets/treeView-Q6P3EWNA-Cccy0ngL.js +0 -1
  438. package/dist/client/assets/treemap-WGGIJYW6-sMRCjCtX.js +0 -1
  439. package/dist/client/assets/usecaseDiagram-POWQR4AR-DR2LHQYs.js +0 -328
  440. package/dist/client/assets/vault-api-client-NS_EVHJ3.js +0 -7
  441. package/dist/client/assets/wardley-WFR3VGLG-Y7xty_3m.js +0 -1
  442. package/dist/client/assets/workspace-sync-client-BrMtf6zN.js +0 -1
  443. package/dist/client/assets/xychartDiagram-PMCCYNJV-fRpZ1MA5.js +0 -7
  444. package/dist/client/assets/yjs-B41tM6Sz.js +0 -4
  445. package/dist/client/assets/yjs-provider-reset-guard-DpntzUDR.js +0 -1
  446. package/scripts/local-plantuml-compose.mjs +0 -92
  447. package/scripts/local-structurizr-compose.mjs +0 -101
@@ -1,6 +1,7 @@
1
1
  const MARKDOWN_FILE_EXTENSIONS = Object.freeze(['.md', '.markdown', '.mdx']);
2
2
  const HTML_FILE_EXTENSIONS = Object.freeze(['.html', '.htm']);
3
3
  const BASE_FILE_EXTENSION = '.base';
4
+ const CANVAS_FILE_EXTENSION = '.canvas';
4
5
  const EXCALIDRAW_FILE_EXTENSION = '.excalidraw';
5
6
  const DRAWIO_FILE_EXTENSION = '.drawio';
6
7
  const MERMAID_FILE_EXTENSIONS = Object.freeze(['.mmd', '.mermaid']);
@@ -10,6 +11,7 @@ const STRUCTURIZR_FILE_EXTENSIONS = Object.freeze([STRUCTURIZR_FILE_EXTENSION]);
10
11
  const PDF_FILE_EXTENSION = '.pdf';
11
12
  const IMAGE_ATTACHMENT_EXTENSIONS = Object.freeze(['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg']);
12
13
  const DIAGRAM_FILE_EXTENSIONS = Object.freeze([
14
+ CANVAS_FILE_EXTENSION,
13
15
  EXCALIDRAW_FILE_EXTENSION,
14
16
  DRAWIO_FILE_EXTENSION,
15
17
  ...MERMAID_FILE_EXTENSIONS,
@@ -24,7 +26,7 @@ const VAULT_FILE_EXTENSIONS = Object.freeze([
24
26
  PDF_FILE_EXTENSION,
25
27
  ...IMAGE_ATTACHMENT_EXTENSIONS,
26
28
  ]);
27
- const STRIP_VAULT_EXTENSION_PATTERN = /\.(?:md|markdown|mdx|html?|base|excalidraw|drawio|mmd|mermaid|puml|plantuml|dsl|pdf|png|jpe?g|webp|gif|svg)$/i;
29
+ const STRIP_VAULT_EXTENSION_PATTERN = /\.(?:md|markdown|mdx|html?|base|canvas|excalidraw|drawio|mmd|mermaid|puml|plantuml|dsl|pdf|png|jpe?g|webp|gif|svg)$/i;
28
30
 
29
31
  function normalizeFilePath(filePath) {
30
32
  return String(filePath ?? '').trim().toLowerCase();
@@ -37,6 +39,7 @@ function hasFileExtension(filePath, extensions) {
37
39
 
38
40
  export {
39
41
  BASE_FILE_EXTENSION,
42
+ CANVAS_FILE_EXTENSION,
40
43
  DIAGRAM_FILE_EXTENSIONS,
41
44
  DRAWIO_FILE_EXTENSION,
42
45
  EXCALIDRAW_FILE_EXTENSION,
@@ -64,6 +67,10 @@ export function getVaultFileKind(filePath) {
64
67
  return 'base';
65
68
  }
66
69
 
70
+ if (hasFileExtension(filePath, [CANVAS_FILE_EXTENSION])) {
71
+ return 'canvas';
72
+ }
73
+
67
74
  if (hasFileExtension(filePath, [EXCALIDRAW_FILE_EXTENSION])) {
68
75
  return 'excalidraw';
69
76
  }
@@ -129,6 +136,10 @@ export function isExcalidrawFilePath(filePath) {
129
136
  return getVaultFileKind(filePath) === 'excalidraw';
130
137
  }
131
138
 
139
+ export function isCanvasFilePath(filePath) {
140
+ return getVaultFileKind(filePath) === 'canvas';
141
+ }
142
+
132
143
  export function isBaseFilePath(filePath) {
133
144
  return getVaultFileKind(filePath) === 'base';
134
145
  }
@@ -160,6 +171,7 @@ export function isImageAttachmentFilePath(filePath) {
160
171
  export function isDiagramFilePath(filePath) {
161
172
  const kind = getVaultFileKind(filePath);
162
173
  return kind === 'excalidraw'
174
+ || kind === 'canvas'
163
175
  || kind === 'drawio'
164
176
  || kind === 'mermaid'
165
177
  || kind === 'plantuml'
@@ -11,8 +11,6 @@ import {
11
11
  createWorkspaceTree,
12
12
  deriveNextWorkspaceStateForApiMutation as deriveNextWorkspaceStateFromApiMutation,
13
13
  diffWorkspaceEntries,
14
- isIncrementalWorkspaceMutationAction,
15
- readWorkspacePathState as readWorkspacePathStateFromAdapter,
16
14
  } from '../domain/workspace-state.js';
17
15
 
18
16
  function createEventId() {
@@ -87,18 +85,6 @@ export class WorkspaceReconciliation {
87
85
  return this.workspaceTree;
88
86
  }
89
87
 
90
- isIncrementalApiAction(action) {
91
- return isIncrementalWorkspaceMutationAction(action);
92
- }
93
-
94
- async readWorkspacePathState(pathValue, {
95
- expectDirectory = null,
96
- } = {}) {
97
- return readWorkspacePathStateFromAdapter(this.workspaceStateAdapter, pathValue, {
98
- expectDirectory,
99
- });
100
- }
101
-
102
88
  async deriveNextWorkspaceStateForApiMutation(action, workspaceChange = {}) {
103
89
  return deriveNextWorkspaceStateFromApiMutation(this.workspaceStateAdapter, {
104
90
  action,
@@ -49,7 +49,6 @@ export class BacklinkIndex {
49
49
  /** @type {Set<string>} file path membership set */
50
50
  this._fileSet = new Set();
51
51
  this._wikiTargetIndex = createWikiTargetIndex(this._fileList);
52
- this._built = false;
53
52
  this._requestedBuildVersion = 0;
54
53
  this._completedBuildVersion = 0;
55
54
  this._buildPromise = null;
@@ -141,7 +140,7 @@ export class BacklinkIndex {
141
140
  this.rawTargetKeysBySource.clear();
142
141
  this.rawTargetSources.clear();
143
142
 
144
- const snapshot = workspaceState ?? await this._resolveWorkspaceState();
143
+ const snapshot = workspaceState ?? await this.vaultFileStore.scanWorkspaceState();
145
144
  this._fileList = Array.from(snapshot?.filePaths ?? snapshot?.markdownPaths ?? []);
146
145
  this._fileSet = new Set(this._fileList);
147
146
  this._sourceFileList = Array.from(
@@ -165,23 +164,9 @@ export class BacklinkIndex {
165
164
  }
166
165
  }
167
166
 
168
- this._built = true;
169
167
  console.log(`[backlinks] Index built: ${this._sourceFileList.length} markdown sources, ${this._fileList.length} targets, ${this.reverse.size} targets with backlinks`);
170
168
  }
171
169
 
172
- async _resolveWorkspaceState() {
173
- if (typeof this.vaultFileStore.scanWorkspaceState === 'function') {
174
- return this.vaultFileStore.scanWorkspaceState();
175
- }
176
-
177
- const tree = await this.vaultFileStore.tree();
178
- const filePaths = flattenTree(tree);
179
- return {
180
- filePaths,
181
- markdownPaths: filePaths.filter((filePath) => isMarkdownFilePath(filePath)),
182
- };
183
- }
184
-
185
170
  /**
186
171
  * Incrementally update the index when a file's content changes.
187
172
  * Call this after every persist / write.
@@ -469,13 +454,6 @@ export class BacklinkIndex {
469
454
  return results;
470
455
  }
471
456
 
472
- /**
473
- * Get the count of backlinks for a file (cheap — no I/O).
474
- */
475
- getBacklinkCount(filePath) {
476
- return this.reverse.get(filePath)?.size ?? 0;
477
- }
478
-
479
457
  // --- Private methods ---
480
458
 
481
459
  _indexFile(filePath, content, { targetPathAliases = new Map() } = {}) {
@@ -621,16 +599,3 @@ export class BacklinkIndex {
621
599
  }
622
600
  }
623
601
  }
624
-
625
- /** Flatten a vault tree into an array of file paths. */
626
- function flattenTree(nodes) {
627
- const files = [];
628
- for (const node of nodes) {
629
- if (node.type && node.type !== 'directory') {
630
- files.push(node.path);
631
- } else if (node.children) {
632
- files.push(...flattenTree(node.children));
633
- }
634
- }
635
- return files;
636
- }
@@ -26,17 +26,11 @@ function cloneSnapshotRowRecord(rowRecord) {
26
26
  };
27
27
  }
28
28
 
29
- function createWorkspaceFileSetSignature(fileEntries = []) {
30
- return fileEntries.join('\n');
31
- }
32
-
33
- function createRowCacheKey(filePath, workspaceState, fileSetSignature) {
29
+ function createRowMetadataSignature(filePath, workspaceState) {
34
30
  const metadata = workspaceState?.metadata?.get(filePath) ?? null;
35
31
  return [
36
- filePath,
37
32
  Number.isFinite(metadata?.mtimeMs) ? metadata.mtimeMs : '',
38
33
  Number.isFinite(metadata?.size) ? metadata.size : '',
39
- fileSetSignature,
40
34
  ].join('\0');
41
35
  }
42
36
 
@@ -139,6 +133,8 @@ export class BaseIndexSnapshotStore {
139
133
  this.indexSnapshot = null;
140
134
  this.lastWorkspaceState = null;
141
135
  this.rowRecordCache = new Map();
136
+ this.rowRecordCacheFileSetSignature = '';
137
+ this.rowRecordCacheGeneration = 0;
142
138
  }
143
139
 
144
140
  async getWorkspaceState() {
@@ -305,13 +301,16 @@ export class BaseIndexSnapshotStore {
305
301
  async buildIndexSnapshot(workspaceState = null) {
306
302
  const resolvedWorkspaceState = workspaceState ?? await this.getWorkspaceState();
307
303
  const fileEntries = listWorkspaceFilePaths(resolvedWorkspaceState);
308
- const fileSetSignature = createWorkspaceFileSetSignature(fileEntries);
304
+ const cacheGeneration = this.prepareRowRecordCache(fileEntries);
309
305
  const wikiTargetIndex = createWikiTargetIndex(fileEntries);
310
306
  const markdownContents = new Map();
307
+ // Keep reused rows available if another build replaces the shared cache during I/O.
308
+ const cachedRowRecords = new Map(fileEntries.map((filePath) => [
309
+ filePath, this.getCachedRowRecord(filePath, resolvedWorkspaceState, cacheGeneration),
310
+ ]));
311
311
 
312
312
  await mapWithConcurrency(resolvedWorkspaceState.markdownPaths ?? [], INDEX_READ_CONCURRENCY, async (filePath) => {
313
- const cacheKey = createRowCacheKey(filePath, resolvedWorkspaceState, fileSetSignature);
314
- if (!this.rowRecordCache.has(cacheKey)) {
313
+ if (!cachedRowRecords.get(filePath)) {
315
314
  markdownContents.set(filePath, await this.vaultFileStore.readMarkdownFile(filePath));
316
315
  }
317
316
  });
@@ -322,13 +321,16 @@ export class BaseIndexSnapshotStore {
322
321
  const rawTargetSourcesByKey = new Map();
323
322
  const nextRowRecordCache = new Map();
324
323
  fileEntries.forEach((filePath) => {
325
- const cacheKey = createRowCacheKey(filePath, resolvedWorkspaceState, fileSetSignature);
326
- const cachedRowRecord = this.rowRecordCache.get(cacheKey);
324
+ const cachedRowRecord = cachedRowRecords.get(filePath);
327
325
  const markdownContent = markdownContents.get(filePath) ?? null;
328
326
  const rowRecord = cachedRowRecord
329
327
  ? cloneSnapshotRowRecord(cachedRowRecord)
330
328
  : this.createSnapshotRow(filePath, resolvedWorkspaceState, wikiTargetIndex, markdownContent);
331
- nextRowRecordCache.set(cacheKey, cloneSnapshotRowRecord(rowRecord));
329
+ nextRowRecordCache.set(filePath, {
330
+ generation: cacheGeneration,
331
+ metadataSignature: createRowMetadataSignature(filePath, resolvedWorkspaceState),
332
+ rowRecord: cloneSnapshotRowRecord(rowRecord),
333
+ });
332
334
  rowsByPath.set(filePath, rowRecord.row);
333
335
  forwardLinksByPath.set(filePath, rowRecord.forwardLinks);
334
336
  rawTargetKeysBySourcePath.set(filePath, rowRecord.rawTargetKeys);
@@ -411,7 +413,7 @@ export class BaseIndexSnapshotStore {
411
413
  return pathValue && isWorkspaceFileEntry(entry);
412
414
  });
413
415
 
414
- const fileSetSignature = createWorkspaceFileSetSignature(snapshot.filePaths);
416
+ const cacheGeneration = this.prepareRowRecordCache(snapshot.filePaths);
415
417
  await mapWithConcurrency(filePathsToRefresh, INDEX_READ_CONCURRENCY, async (filePath) => {
416
418
  const markdownContent = isMarkdownFilePath(filePath)
417
419
  ? await this.vaultFileStore.readMarkdownFile(filePath)
@@ -419,11 +421,11 @@ export class BaseIndexSnapshotStore {
419
421
  const rowRecord = this.createSnapshotRow(filePath, workspaceState, snapshot.wikiTargetIndex, markdownContent, {
420
422
  targetPathAliases,
421
423
  });
422
- this.invalidateRowRecordCachePath(filePath);
423
- this.rowRecordCache.set(
424
- createRowCacheKey(filePath, workspaceState, fileSetSignature),
425
- cloneSnapshotRowRecord(rowRecord),
426
- );
424
+ this.rowRecordCache.set(filePath, {
425
+ generation: cacheGeneration,
426
+ metadataSignature: createRowMetadataSignature(filePath, workspaceState),
427
+ rowRecord: cloneSnapshotRowRecord(rowRecord),
428
+ });
427
429
  this.removeRawTargetSourceContributions(snapshot, filePath);
428
430
  snapshot.rowsByPath.set(filePath, rowRecord.row);
429
431
  snapshot.forwardLinksByPath.set(filePath, rowRecord.forwardLinks);
@@ -431,12 +433,27 @@ export class BaseIndexSnapshotStore {
431
433
  });
432
434
  }
433
435
 
436
+ prepareRowRecordCache(filePaths) {
437
+ const signature = JSON.stringify(filePaths);
438
+ if (signature !== this.rowRecordCacheFileSetSignature) {
439
+ // Link resolution depends on every target path, including previously missing files.
440
+ this.rowRecordCache.clear();
441
+ this.rowRecordCacheFileSetSignature = signature;
442
+ this.rowRecordCacheGeneration += 1;
443
+ }
444
+ return this.rowRecordCacheGeneration;
445
+ }
446
+
447
+ getCachedRowRecord(filePath, workspaceState, generation) {
448
+ const cached = this.rowRecordCache.get(filePath);
449
+ return cached?.generation === generation
450
+ && cached.metadataSignature === createRowMetadataSignature(filePath, workspaceState)
451
+ ? cached.rowRecord
452
+ : null;
453
+ }
454
+
434
455
  invalidateRowRecordCachePath(filePath) {
435
- Array.from(this.rowRecordCache.keys()).forEach((cacheKey) => {
436
- if (cacheKey === filePath || cacheKey.startsWith(`${filePath}\0`)) {
437
- this.rowRecordCache.delete(cacheKey);
438
- }
439
- });
456
+ this.rowRecordCache.delete(filePath);
440
457
  }
441
458
 
442
459
  async ensureIndexSnapshot({ basePath = '', sourcePath = '' } = {}) {
@@ -56,32 +56,6 @@ function sortRows(rows, sortChain = []) {
56
56
  });
57
57
  }
58
58
 
59
- function compareRowsBySortChain(left, right, sortChain = []) {
60
- for (const sortConfig of sortChain) {
61
- const delta = compareValues(left.rawCells[sortConfig.property], right.rawCells[sortConfig.property]);
62
- if (delta !== 0) {
63
- return sortConfig.direction === 'desc' ? -delta : delta;
64
- }
65
- }
66
-
67
- return String(left.file.path ?? '').localeCompare(String(right.file.path ?? ''));
68
- }
69
-
70
- function insertSortedBounded(rows, row, {
71
- limit,
72
- sortChain = [],
73
- }) {
74
- let insertIndex = rows.findIndex((existingRow) => compareRowsBySortChain(row, existingRow, sortChain) < 0);
75
- if (insertIndex === -1) {
76
- insertIndex = rows.length;
77
- }
78
-
79
- rows.splice(insertIndex, 0, row);
80
- if (rows.length > limit) {
81
- rows.pop();
82
- }
83
- }
84
-
85
59
  function pruneFilterNodeForProperty(filterNode, propertyId = '') {
86
60
  if (!propertyId || !filterNode) {
87
61
  return filterNode;
@@ -225,21 +199,12 @@ export class BaseQueryService {
225
199
  columns = [],
226
200
  definition,
227
201
  evaluatedPropertyIds,
228
- limit = null,
229
- maxRows = this.maxResultRows,
230
202
  snapshot,
231
- sortChain = [],
232
203
  search = '',
233
204
  thisFile,
234
205
  }) {
206
+ // ponytail: retain matching rows for one native sort; use bounded selection if heap profiles require it.
235
207
  const rows = [];
236
- const effectiveMaxRows = Number.isInteger(maxRows) && maxRows > 0 ? maxRows : Infinity;
237
- const effectiveLimit = Number.isInteger(limit) && limit > 0 ? limit : Infinity;
238
- const canBoundDuringCollection = Number.isFinite(Math.min(effectiveLimit, effectiveMaxRows))
239
- && sortChain.length > 0
240
- && !activeView.groupBy?.property
241
- && (activeView.summaries?.length ?? 0) === 0;
242
- const hardLimit = Math.min(effectiveLimit, effectiveMaxRows);
243
208
 
244
209
  const filePaths = snapshot.filePaths ?? [];
245
210
  for (let chunkStart = 0; chunkStart < filePaths.length; chunkStart += BASE_QUERY_ROW_CHUNK_SIZE) {
@@ -275,14 +240,6 @@ export class BaseQueryService {
275
240
  continue;
276
241
  }
277
242
 
278
- if (canBoundDuringCollection) {
279
- insertSortedBounded(rows, candidateRow, {
280
- limit: hardLimit,
281
- sortChain,
282
- });
283
- continue;
284
- }
285
-
286
243
  rows.push(candidateRow);
287
244
  }
288
245
 
@@ -390,10 +347,7 @@ export class BaseQueryService {
390
347
  let rows = await this.collectCandidateRows({
391
348
  ...context,
392
349
  astCache,
393
- limit: requestedLimit,
394
- maxRows: this.maxResultRows,
395
350
  search,
396
- sortChain,
397
351
  });
398
352
  rows = sortRows(rows, sortChain);
399
353
 
@@ -14,7 +14,21 @@ import {
14
14
  import { CollaborationDocumentStore } from './collaboration-document-store.js';
15
15
  import { logPerfEvent } from '../../config/perf-logging.js';
16
16
  import { populateCommentThreads, serializeCommentThreads } from '../../../domain/comment-threads.js';
17
- import { getVaultFileKind } from '../../../domain/file-kind.js';
17
+ import { getVaultFileKind, isCanvasFilePath } from '../../../domain/file-kind.js';
18
+ import {
19
+ buildCanvasRoomDocument,
20
+ CANVAS_EDGES_KEY,
21
+ CANVAS_EDGE_ORDER_KEY,
22
+ CANVAS_META_KEY,
23
+ CANVAS_NODES_KEY,
24
+ CANVAS_NODE_ORDER_KEY,
25
+ isCanvasRoomDocStructured,
26
+ mergeCanvasDocuments,
27
+ parseCanvasJson,
28
+ replaceCanvasRoomDocument,
29
+ serializeCanvasDocument,
30
+ serializeCanvasRoomDocument,
31
+ } from '../../../domain/canvas-room-codec.js';
18
32
  import {
19
33
  applySceneDiffToExcalidrawRoom,
20
34
  EXCALIDRAW_APP_STATE_KEY,
@@ -292,7 +306,28 @@ export class CollaborationRoom {
292
306
  if (snapshot) {
293
307
  snapshotExists = true;
294
308
  try {
295
- if (isExcalidrawRoom(this.name)) {
309
+ if (isCanvasFilePath(this.name)) {
310
+ const validationDoc = new Y.Doc({ gc: true });
311
+ try {
312
+ Y.applyUpdate(validationDoc, snapshot, 'hydrate');
313
+ const stored = serializeCanvasRoomDocument(validationDoc);
314
+ const content = await this.documentStore.readContent();
315
+ const meta = validationDoc.getMap(CANVAS_META_KEY);
316
+ if (meta.has('externalConflict')) {
317
+ let invalid = false;
318
+ try { parseCanvasJson(content); } catch { invalid = true; }
319
+ meta.set('externalConflict', { content, invalid });
320
+ } else {
321
+ const external = parseCanvasJson(content);
322
+ if (stored !== serializeCanvasDocument(external)) {
323
+ replaceCanvasRoomDocument(validationDoc, external);
324
+ }
325
+ }
326
+ Y.applyUpdate(this.doc, Y.encodeStateAsUpdate(validationDoc), 'hydrate');
327
+ } finally {
328
+ validationDoc.destroy();
329
+ }
330
+ } else if (isExcalidrawRoom(this.name)) {
296
331
  const validationDoc = new Y.Doc({ gc: true });
297
332
  try {
298
333
  Y.applyUpdate(validationDoc, snapshot, 'hydrate');
@@ -332,7 +367,13 @@ export class CollaborationRoom {
332
367
  const ytext = this.doc.getText('codemirror');
333
368
  const comments = this.doc.getArray('comments');
334
369
  this.doc.transact(() => {
335
- if (isExcalidrawRoom(this.name)) {
370
+ if (isCanvasFilePath(this.name)) {
371
+ try {
372
+ replaceCanvasRoomDocument(this.doc, parseCanvasJson(content));
373
+ } catch {
374
+ this.doc.getMap(CANVAS_META_KEY).set('invalidContent', true);
375
+ }
376
+ } else if (isExcalidrawRoom(this.name)) {
336
377
  const parsedScene = tryParseExcalidrawSceneJson(content);
337
378
  if (parsedScene) {
338
379
  migrateLegacyExcalidrawRoomData(this.doc, parsedScene);
@@ -346,7 +387,7 @@ export class CollaborationRoom {
346
387
  }, 'hydrate');
347
388
 
348
389
  const replacementSnapshot = Y.encodeStateAsUpdate(this.doc);
349
- if (snapshotNeedsReplacement) {
390
+ if (snapshotNeedsReplacement || isCanvasFilePath(this.name)) {
350
391
  await this.documentStore.writeSnapshot(replacementSnapshot);
351
392
  } else {
352
393
  void this.documentStore.writeSnapshot(replacementSnapshot).catch((error) => {
@@ -462,6 +503,13 @@ export class CollaborationRoom {
462
503
  this.contentDirty = true;
463
504
  };
464
505
 
506
+ if (isCanvasFilePath(this.name)) {
507
+ for (const key of [CANVAS_NODES_KEY, CANVAS_EDGES_KEY, CANVAS_NODE_ORDER_KEY, CANVAS_EDGE_ORDER_KEY, CANVAS_META_KEY]) {
508
+ this.doc.getMap(key).observeDeep((_events, transaction) => markFromTransaction(transaction));
509
+ }
510
+ return;
511
+ }
512
+
465
513
  if (isExcalidrawRoom(this.name)) {
466
514
  this.doc.getMap(EXCALIDRAW_ELEMENTS_KEY).observeDeep((_events, transaction) => {
467
515
  markFromTransaction(transaction);
@@ -482,6 +530,12 @@ export class CollaborationRoom {
482
530
 
483
531
  resetContentBaseline() {
484
532
  this.persistedContentBaseline = this.getPersistedContent();
533
+ if (isCanvasFilePath(this.name)) {
534
+ const conflict = this.doc.getMap(CANVAS_META_KEY).get('externalConflict');
535
+ if (conflict) {
536
+ this.persistedContentBaseline = conflict.invalid ? null : serializeCanvasDocument(parseCanvasJson(conflict.content));
537
+ }
538
+ }
485
539
  this.contentDirty = false;
486
540
  }
487
541
 
@@ -555,15 +609,38 @@ export class CollaborationRoom {
555
609
  return;
556
610
  }
557
611
 
558
- const content = this.getPersistedContent();
612
+ let content = this.getPersistedContent();
559
613
  if (content === null) {
560
- console.warn(`[room:${this.name}] Skipping persist because the Excalidraw scene is invalid`);
614
+ console.warn(`[room:${this.name}] Skipping persist because the document is invalid`);
561
615
  return;
562
616
  }
617
+ if (isCanvasFilePath(this.name) && content !== this.persistedContentBaseline && !this.doc.getMap(CANVAS_META_KEY).has('externalConflict')) {
618
+ const externalContent = await this.documentStore.readContent();
619
+ if (this.deleted || this.destroyed) return;
620
+ if (externalContent === null) {
621
+ this.markDeleted();
622
+ return;
623
+ }
624
+ let externalBaseline = null;
625
+ let invalid = false;
626
+ try { externalBaseline = serializeCanvasDocument(parseCanvasJson(externalContent)); } catch { invalid = true; }
627
+ content = this.getPersistedContent();
628
+ if (content === null) return;
629
+ // A filesystem observation may still be queued when the save timer fires.
630
+ if (externalBaseline !== this.persistedContentBaseline) {
631
+ this.persistedContentBaseline = externalBaseline;
632
+ if (externalBaseline !== content) {
633
+ this.doc.transact(() => {
634
+ this.doc.getMap(CANVAS_META_KEY).set('externalConflict', { content: externalContent, invalid });
635
+ }, 'workspace-reconcile');
636
+ }
637
+ }
638
+ }
563
639
  // Compare inline: refreshContentDirty() would serialize the document
564
640
  // a second time for the same check.
565
- const includeContent = content !== this.persistedContentBaseline;
566
- this.contentDirty = includeContent;
641
+ const conflict = isCanvasFilePath(this.name) && this.doc.getMap(CANVAS_META_KEY).has('externalConflict');
642
+ this.contentDirty = content !== this.persistedContentBaseline;
643
+ const includeContent = this.contentDirty && !conflict;
567
644
  const commentThreads = serializeCommentThreads(this.doc.getArray('comments'));
568
645
  await this.documentStore.persistState({
569
646
  commentThreads,
@@ -616,6 +693,46 @@ export class CollaborationRoom {
616
693
  }
617
694
 
618
695
  const comments = this.doc.getArray('comments');
696
+ if (isCanvasFilePath(this.name)) {
697
+ let external;
698
+ try {
699
+ external = parseCanvasJson(content);
700
+ } catch {
701
+ this.doc.transact(() => {
702
+ this.doc.getMap(CANVAS_META_KEY).set('externalConflict', { content, invalid: true });
703
+ }, 'workspace-reconcile');
704
+ this.persistedContentBaseline = null;
705
+ // Preserve the pending document in a sidecar while the invalid file remains untouched.
706
+ await this.persist();
707
+ return { ok: false, reason: 'invalid-canvas' };
708
+ }
709
+
710
+ const meta = this.doc.getMap(CANVAS_META_KEY);
711
+ const current = this.getPersistedContent();
712
+ const hasPendingChanges = current !== null && current !== this.persistedContentBaseline;
713
+ const reconciliation = hasPendingChanges && this.persistedContentBaseline !== null
714
+ ? mergeCanvasDocuments(parseCanvasJson(this.persistedContentBaseline), buildCanvasRoomDocument(this.doc), external)
715
+ : { conflict: hasPendingChanges, document: external };
716
+ const hadConflict = meta.has('externalConflict');
717
+ this.doc.transact(() => {
718
+ if (reconciliation.conflict || hadConflict) {
719
+ meta.set('externalConflict', { content, invalid: false });
720
+ } else {
721
+ replaceCanvasRoomDocument(this.doc, reconciliation.document);
722
+ meta.delete('invalidContent');
723
+ }
724
+ if (replaceCommentThreads) {
725
+ if (comments.length > 0) comments.delete(0, comments.length);
726
+ populateCommentThreads(comments, commentThreads);
727
+ }
728
+ }, 'workspace-reconcile');
729
+ this.persistedContentBaseline = serializeCanvasDocument(external);
730
+ this.refreshContentDirty();
731
+ if (this.contentDirty && !meta.has('externalConflict')) this.schedulePersist();
732
+ else await this.persist();
733
+ return { ok: true, highlightRange: null, conflict: meta.has('externalConflict') };
734
+ }
735
+
619
736
  if (isExcalidrawRoom(this.name)) {
620
737
  const parsedExcalidrawScene = tryParseExcalidrawSceneJson(content);
621
738
  if (!parsedExcalidrawScene) {
@@ -712,10 +829,6 @@ export class CollaborationRoom {
712
829
  }
713
830
  }
714
831
 
715
- unmarkDeleted() {
716
- this.deleted = false;
717
- }
718
-
719
832
  isDeleted() {
720
833
  return this.deleted;
721
834
  }
@@ -917,14 +1030,14 @@ export class CollaborationRoom {
917
1030
  }
918
1031
 
919
1032
  readEditableContent() {
920
- if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name)) {
1033
+ if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name) || isCanvasFilePath(this.name)) {
921
1034
  return null;
922
1035
  }
923
1036
  return this.doc.getText('codemirror').toString();
924
1037
  }
925
1038
 
926
1039
  applyExactTextChanges(changes, { origin = 'agent' } = {}) {
927
- if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name)) {
1040
+ if (!this.hydrated || this.deleted || this.destroyed || isExcalidrawRoom(this.name) || isCanvasFilePath(this.name)) {
928
1041
  throw new Error('The collaborative document is unavailable');
929
1042
  }
930
1043
  const ytext = this.doc.getText('codemirror');
@@ -962,6 +1075,14 @@ export class CollaborationRoom {
962
1075
  return null;
963
1076
  }
964
1077
 
1078
+ if (isCanvasFilePath(this.name)) {
1079
+ try {
1080
+ return isCanvasRoomDocStructured(this.doc) ? serializeCanvasRoomDocument(this.doc) : null;
1081
+ } catch {
1082
+ return null;
1083
+ }
1084
+ }
1085
+
965
1086
  if (!isExcalidrawRoom(this.name)) {
966
1087
  return this.doc.getText('codemirror').toString();
967
1088
  }
@@ -1027,7 +1148,20 @@ export class CollaborationRoom {
1027
1148
  const encoder = encoding.createEncoder();
1028
1149
  encoding.writeVarUint(encoder, MSG_AGENT_FLUSH_ACK);
1029
1150
  encoding.writeVarString(encoder, requestId);
1030
- sendMessage.call(this, ws, encoding.toUint8Array(encoder), this);
1151
+ const acknowledge = () => sendMessage.call(this, ws, encoding.toUint8Array(encoder), this);
1152
+ if (isCanvasFilePath(this.name)) {
1153
+ const available = () => this.hydrated && !this.deleted && !this.destroyed
1154
+ && this.documentStore?.hasPersistence() && this.getPersistedContent() !== null;
1155
+ if (available()) {
1156
+ void this.persist().then(() => {
1157
+ if (available()) acknowledge();
1158
+ }).catch((error) => {
1159
+ console.error(`[room:${this.name}] Failed to persist canvas before flush acknowledgement:`, error.message);
1160
+ });
1161
+ }
1162
+ } else {
1163
+ acknowledge();
1164
+ }
1031
1165
  break;
1032
1166
  }
1033
1167
 
@@ -1,3 +1,5 @@
1
+ import { getVaultFileKind } from '../../../domain/file-kind.js';
2
+
1
3
  export class RoomRegistry {
2
4
  constructor({ createRoom }) {
3
5
  this.createRoom = createRoom;
@@ -31,6 +33,10 @@ export class RoomRegistry {
31
33
  return false;
32
34
  }
33
35
 
36
+ const oldKind = getVaultFileKind(oldName);
37
+ const newKind = getVaultFileKind(newName);
38
+ if (oldKind !== newKind && [oldKind, newKind].includes('canvas')) return false;
39
+
34
40
  const room = this.rooms.get(oldName);
35
41
  if (!room) {
36
42
  return false;
@@ -61,12 +67,6 @@ export class RoomRegistry {
61
67
  return Array.from(this.rooms.entries());
62
68
  }
63
69
 
64
- async reloadAllFromDisk() {
65
- await Promise.allSettled(
66
- Array.from(this.rooms.values(), (room) => room.reloadFromDisk?.()),
67
- );
68
- }
69
-
70
70
  async reconcileWorkspaceChange(workspaceChange = {}) {
71
71
  const deletedPaths = new Set(workspaceChange.deletedPaths ?? []);
72
72
  const renamedPaths = Array.isArray(workspaceChange.renamedPaths) ? workspaceChange.renamedPaths : [];
@@ -128,7 +128,7 @@ export class RoomRegistry {
128
128
  }
129
129
 
130
130
  const result = await room.reloadFromDisk?.();
131
- if (result && result.ok === false && result.reason === 'invalid-excalidraw') {
131
+ if (result && result.ok === false && ['invalid-excalidraw', 'invalid-canvas'].includes(result.reason)) {
132
132
  reloadRequiredPaths.push(pathValue);
133
133
  } else if (result?.highlightRange) {
134
134
  highlightRanges.push({