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
@@ -8,12 +8,6 @@ const REVISION_SCHEMA = {
8
8
  type: 'string',
9
9
  };
10
10
 
11
- const DOCUMENT_SCHEMA = objectSchema({
12
- kind: { type: 'string' },
13
- mtimeMs: { minimum: 0, type: 'number' },
14
- path: { type: 'string' },
15
- size: { minimum: 0, type: 'number' },
16
- });
17
11
  const WORKSPACE_ENTRY_SCHEMA = objectSchema({
18
12
  agentEditable: { type: 'boolean' },
19
13
  embeddable: { type: 'boolean' },
@@ -208,6 +202,12 @@ const EXCALIDRAW_SUMMARY_ELEMENT_SCHEMA = {
208
202
  },
209
203
  endElementId: { type: 'string' },
210
204
  containerId: { type: 'string' },
205
+ fontFamily: {
206
+ description: 'Excalidraw font-family identifier. Standard Excalifont is 5; legacy Virgil is 1.',
207
+ minimum: 1,
208
+ type: 'integer',
209
+ },
210
+ fontName: { type: 'string' },
211
211
  fontSize: { exclusiveMinimum: 0, type: 'number' },
212
212
  height: { minimum: 0, type: 'number' },
213
213
  id: { type: 'string' },
@@ -242,7 +242,16 @@ const EXCALIDRAW_INSPECTION_PROPERTIES = {
242
242
  bounds: EXCALIDRAW_BOUNDS_SCHEMA,
243
243
  elementCount: { minimum: 0, type: 'integer' },
244
244
  elements: { items: EXCALIDRAW_SUMMARY_ELEMENT_SCHEMA, type: 'array' },
245
+ layout: objectSchema({
246
+ boundText: objectSchema({
247
+ misaligned: { minimum: 0, type: 'integer' },
248
+ outsideContainer: { minimum: 0, type: 'integer' },
249
+ staleHeight: { minimum: 0, type: 'integer' },
250
+ total: { minimum: 0, type: 'integer' },
251
+ }),
252
+ }),
245
253
  truncated: { type: 'boolean' },
254
+ valid: { type: 'boolean' },
246
255
  warnings: { items: EXCALIDRAW_WARNING_SCHEMA, type: 'array' },
247
256
  };
248
257
  const EXCALIDRAW_INSPECTION_SCHEMA = objectSchema(EXCALIDRAW_INSPECTION_PROPERTIES);
@@ -262,11 +271,6 @@ const EXCALIDRAW_RENDER_RESULT_PROPERTIES = {
262
271
  warnings: { items: { type: 'string' }, type: 'array' },
263
272
  width: { minimum: 1, type: 'integer' },
264
273
  };
265
- const EXCALIDRAW_RENDER_OUTPUT_PROPERTIES = {
266
- ...EXCALIDRAW_RENDER_RESULT_PROPERTIES,
267
- path: { type: 'string' },
268
- revision: REVISION_SCHEMA,
269
- };
270
274
  const EXCALIDRAW_RENDER_INPUT_PROPERTIES = {
271
275
  format: {
272
276
  description: 'Image format. PNG is most widely supported by MCP clients.',
@@ -285,6 +289,10 @@ const EXCALIDRAW_RENDER_INPUT_PROPERTIES = {
285
289
  minLength: 1,
286
290
  type: 'string',
287
291
  },
292
+ render: {
293
+ description: 'Return an image render. Set false for a compact structural and layout verification response.',
294
+ type: 'boolean',
295
+ },
288
296
  scale: {
289
297
  description: 'Requested output scale; automatically reduced when needed to stay within 4096 pixels.',
290
298
  maximum: 4,
@@ -309,11 +317,29 @@ const EXCALIDRAW_INLINE_VERIFICATION_SCHEMA = objectSchema({
309
317
  inspection: EXCALIDRAW_INSPECTION_SCHEMA,
310
318
  ...EXCALIDRAW_RENDER_RESULT_PROPERTIES,
311
319
  }, ['inspection']);
320
+ const EXCALIDRAW_COMPACT_VERIFICATION_PROPERTIES = {
321
+ elementCount: { minimum: 0, type: 'integer' },
322
+ format: { enum: ['png', 'svg'], type: 'string' },
323
+ inspection: EXCALIDRAW_INSPECTION_SCHEMA,
324
+ layout: EXCALIDRAW_INSPECTION_PROPERTIES.layout,
325
+ path: { type: 'string' },
326
+ revision: REVISION_SCHEMA,
327
+ valid: { type: 'boolean' },
328
+ };
329
+ const EXCALIDRAW_VERIFY_OUTPUT_SCHEMA = {
330
+ oneOf: [
331
+ objectSchema(EXCALIDRAW_COMPACT_VERIFICATION_PROPERTIES),
332
+ objectSchema({
333
+ ...EXCALIDRAW_COMPACT_VERIFICATION_PROPERTIES,
334
+ ...EXCALIDRAW_RENDER_RESULT_PROPERTIES,
335
+ }),
336
+ ],
337
+ };
312
338
 
313
339
  export const AGENT_TOOL_DEFINITIONS = Object.freeze([
314
340
  {
315
341
  annotations: { idempotentHint: true, readOnlyHint: true },
316
- description: 'List readable CollabMD Vault documents by path and kind.',
342
+ description: 'List current Vault files and directories, including binary metadata and agent capability flags.',
317
343
  inputSchema: objectSchema({
318
344
  cursor: {
319
345
  description: 'Path from the previous nextCursor; omit for the first page.',
@@ -326,7 +352,7 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
326
352
  uniqueItems: true,
327
353
  },
328
354
  limit: {
329
- description: 'Maximum documents to return.',
355
+ description: 'Maximum entries to return.',
330
356
  maximum: 200,
331
357
  minimum: 1,
332
358
  type: 'integer',
@@ -335,34 +361,10 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
335
361
  description: 'Optional Vault directory or path prefix.',
336
362
  type: 'string',
337
363
  },
338
- }, []),
339
- method: 'listDocuments',
340
- name: 'list_documents',
341
- outputSchema: objectSchema({
342
- documents: { items: DOCUMENT_SCHEMA, type: 'array' },
343
- nextCursor: { type: ['string', 'null'] },
344
- truncated: { type: 'boolean' },
345
- }),
346
- scope: 'vault:read',
347
- untrustedContentHint: true,
348
- webMcp: true,
349
- },
350
- {
351
- annotations: { idempotentHint: true, readOnlyHint: true },
352
- description: 'List current Vault files and directories, including binary metadata and agent capability flags.',
353
- inputSchema: objectSchema({
354
- cursor: {
355
- description: 'Path from the previous nextCursor; omit for the first page.',
356
- type: 'string',
357
- },
358
- limit: {
359
- description: 'Maximum entries to return.',
360
- maximum: 200,
361
- minimum: 1,
362
- type: 'integer',
363
- },
364
- prefix: {
365
- description: 'Optional Vault directory or path prefix.',
364
+ pathQuery: {
365
+ description: 'Optional case-insensitive substring to match anywhere in an entry path.',
366
+ maxLength: 500,
367
+ minLength: 1,
366
368
  type: 'string',
367
369
  },
368
370
  }, []),
@@ -388,12 +390,32 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
388
390
  minimum: 1,
389
391
  type: 'integer',
390
392
  },
393
+ maxSnippetsPerFile: {
394
+ description: 'Maximum matching snippets returned per document.',
395
+ maximum: 10,
396
+ minimum: 1,
397
+ type: 'integer',
398
+ },
399
+ kinds: {
400
+ description: 'Optional CollabMD content kinds to include.',
401
+ items: { type: 'string' },
402
+ type: 'array',
403
+ uniqueItems: true,
404
+ },
405
+ prefix: {
406
+ description: 'Optional Vault directory or path prefix.',
407
+ type: 'string',
408
+ },
391
409
  query: {
392
410
  description: 'Literal case-insensitive text to find; regular expressions are not supported.',
393
411
  maxLength: 500,
394
412
  minLength: 2,
395
413
  type: 'string',
396
414
  },
415
+ wholeWord: {
416
+ description: 'Match only when the literal query is bounded by non-word characters.',
417
+ type: 'boolean',
418
+ },
397
419
  }, ['query']),
398
420
  method: 'searchVault',
399
421
  name: 'search_vault',
@@ -507,6 +529,65 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
507
529
  untrustedContentHint: true,
508
530
  webMcp: true,
509
531
  },
532
+ {
533
+ annotations: { idempotentHint: true, readOnlyHint: true },
534
+ description: 'Run a Base query and return filtered rows so you can verify filters and expected output.',
535
+ inputSchema: objectSchema({
536
+ limit: {
537
+ description: 'Maximum rows to return.',
538
+ maximum: 200,
539
+ minimum: 1,
540
+ type: 'integer',
541
+ },
542
+ path: {
543
+ description: 'Vault-relative .base path.',
544
+ maxLength: 1024,
545
+ minLength: 1,
546
+ type: 'string',
547
+ },
548
+ search: {
549
+ description: 'Optional case-insensitive row search across visible columns.',
550
+ maxLength: 500,
551
+ type: 'string',
552
+ },
553
+ view: {
554
+ description: 'Optional Base view name.',
555
+ maxLength: 200,
556
+ type: 'string',
557
+ },
558
+ }, ['path']),
559
+ method: 'queryBase',
560
+ name: 'query_base',
561
+ outputSchema: objectSchema({
562
+ columns: {
563
+ items: objectSchema({
564
+ id: { type: 'string' },
565
+ label: { type: 'string' },
566
+ }),
567
+ type: 'array',
568
+ },
569
+ path: { type: 'string' },
570
+ rows: {
571
+ items: objectSchema({
572
+ cells: {
573
+ additionalProperties: { type: 'string' },
574
+ type: 'object',
575
+ },
576
+ path: { type: 'string' },
577
+ }),
578
+ type: 'array',
579
+ },
580
+ totalRows: { minimum: 0, type: 'integer' },
581
+ truncated: { type: 'boolean' },
582
+ view: objectSchema({
583
+ name: { type: 'string' },
584
+ type: { type: 'string' },
585
+ }),
586
+ }),
587
+ scope: 'vault:read',
588
+ untrustedContentHint: true,
589
+ webMcp: true,
590
+ },
510
591
  {
511
592
  annotations: { idempotentHint: true, readOnlyHint: true },
512
593
  description: 'Render one standalone or fenced Mermaid/PlantUML diagram. Markdown with multiple diagrams requires the opening fence startLine. Mermaid rendering requires WebMCP.',
@@ -539,7 +620,7 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
539
620
 
540
621
  {
541
622
  annotations: { idempotentHint: true, readOnlyHint: true },
542
- description: 'Inspect an Excalidraw scene structurally. Returns paint order, geometry, bindings, bounds, occlusion, clipping, and validity warnings.',
623
+ description: 'Inspect an Excalidraw scene structurally. Returns paint order, geometry, text style, bindings, bounds, layout diagnostics, occlusion, clipping, and validity warnings.',
543
624
  inputSchema: objectSchema({
544
625
  path: {
545
626
  description: 'Vault-relative .excalidraw path.',
@@ -557,19 +638,7 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
557
638
  },
558
639
  {
559
640
  annotations: { idempotentHint: true, readOnlyHint: true },
560
- description: 'Render supported basic elements as PNG or SVG. Returns renderer metadata and warns when preview is not pixel-identical to Excalidraw.',
561
- inputSchema: objectSchema(EXCALIDRAW_RENDER_INPUT_PROPERTIES, ['path']),
562
- method: 'renderExcalidraw',
563
- name: 'render_excalidraw',
564
- outputSchema: objectSchema(EXCALIDRAW_RENDER_OUTPUT_PROPERTIES),
565
- resultKind: 'image',
566
- scope: 'vault:read',
567
- untrustedContentHint: true,
568
- webMcp: true,
569
- },
570
- {
571
- annotations: { idempotentHint: true, readOnlyHint: true },
572
- description: 'Inspect and render one Excalidraw revision in a single operation.',
641
+ description: 'Verify one Excalidraw revision with compact structural and layout diagnostics; render is optional.',
573
642
  inputSchema: objectSchema({
574
643
  ...EXCALIDRAW_RENDER_INPUT_PROPERTIES,
575
644
  inspectOcclusion: {
@@ -579,11 +648,8 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
579
648
  }, ['path']),
580
649
  method: 'verifyExcalidraw',
581
650
  name: 'verify_excalidraw',
582
- outputSchema: objectSchema({
583
- ...EXCALIDRAW_RENDER_OUTPUT_PROPERTIES,
584
- inspection: EXCALIDRAW_INSPECTION_SCHEMA,
585
- }),
586
- resultKind: 'image',
651
+ outputSchema: EXCALIDRAW_VERIFY_OUTPUT_SCHEMA,
652
+ resultKind: 'optional-image',
587
653
  scope: 'vault:read',
588
654
  untrustedContentHint: true,
589
655
  webMcp: true,
@@ -634,14 +700,14 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
634
700
  path: { type: 'string' },
635
701
  revision: REVISION_SCHEMA,
636
702
  verification: EXCALIDRAW_INLINE_VERIFICATION_SCHEMA,
637
- }),
703
+ }, ['elementCount', 'path', 'revision']),
638
704
  resultKind: 'optional-image',
639
705
  scope: 'vault:edit',
640
706
  webMcp: true,
641
707
  },
642
708
  {
643
709
  annotations: { destructiveHint: false, idempotentHint: false, readOnlyHint: false },
644
- description: 'Create, update, replace, translate, reorder, or delete elements in an existing .excalidraw scene when its revision still matches.',
710
+ description: 'Create, update, replace, translate, reorder, or delete elements in an existing .excalidraw scene when its revision still matches. Bound text whose font, size, line height, or content changes reflows automatically.',
645
711
  inputSchema: objectSchema({
646
712
  create: {
647
713
  items: EXCALIDRAW_ELEMENT_INPUT_SCHEMA,
@@ -655,6 +721,11 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
655
721
  type: 'array',
656
722
  uniqueItems: true,
657
723
  },
724
+ normalizeTextPlacement: {
725
+ description: 'Normalize every bound text label to its container center and current line-height metrics. This can be the only edit operation.',
726
+ enum: [true],
727
+ type: 'boolean',
728
+ },
658
729
  path: {
659
730
  description: 'Vault-relative .excalidraw path returned by read_document.',
660
731
  maxLength: 1024,
@@ -690,6 +761,11 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
690
761
  elementCount: { minimum: 0, type: 'integer' },
691
762
  path: { type: 'string' },
692
763
  reordered: { minimum: 0, type: 'integer' },
764
+ reflowed: {
765
+ description: 'Number of bound text labels whose position or height was normalized.',
766
+ minimum: 0,
767
+ type: 'integer',
768
+ },
693
769
  replaced: { minimum: 0, type: 'integer' },
694
770
  revision: REVISION_SCHEMA,
695
771
  translated: {
@@ -699,7 +775,7 @@ export const AGENT_TOOL_DEFINITIONS = Object.freeze([
699
775
  },
700
776
  updated: { minimum: 0, type: 'integer' },
701
777
  verification: EXCALIDRAW_INLINE_VERIFICATION_SCHEMA,
702
- }, ['created', 'deleted', 'elementCount', 'path', 'reordered', 'replaced', 'revision', 'translated', 'updated']),
778
+ }, ['created', 'deleted', 'elementCount', 'path', 'reordered', 'reflowed', 'replaced', 'revision', 'translated', 'updated']),
703
779
  resultKind: 'optional-image',
704
780
  scope: 'vault:edit',
705
781
  webMcp: true,
@@ -15,11 +15,11 @@ import {
15
15
 
16
16
  const CAPABILITIES = Object.freeze({
17
17
  base: {
18
- agentCreatable: false,
19
- agentEditable: false,
18
+ agentCreatable: true,
19
+ agentEditable: true,
20
20
  editable: true,
21
21
  extensions: [BASE_FILE_EXTENSION],
22
- guide: 'YAML Base definition. Embed a file with ![[query.base]] or an inline query with a fenced base block. Agent writes are disabled until Base validation is shared.',
22
+ guide: 'YAML Base definition. Embed a file with ![[query.base]] or an inline query with a fenced base block. Create and edit with create_document and apply_text_edits. After writing, use query_base to inspect filtered rows.',
23
23
  examples: ['```base\nfilters:\n and: []\n```', '![[tasks.base]]'],
24
24
  },
25
25
  drawio: {
@@ -35,7 +35,7 @@ const CAPABILITIES = Object.freeze({
35
35
  agentEditable: true,
36
36
  editable: true,
37
37
  extensions: [EXCALIDRAW_FILE_EXTENSION],
38
- guide: 'Excalidraw scene JSON managed by the canvas editor. Use create_excalidraw and edit_excalidraw rather than raw text edits. Element order is back-to-front; create supports beforeElementId and afterElementId, while edit supports relationship-aware translation, reorder, same-ID replace, and same-revision verification. Container or group translation also moves bound text and grouped members. Standalone auto-resizing text recalculates its bounds when text metrics change. Line, arrow, and freedraw dimensions are derived from points. Creation and editing support inline inspection and optional rendering; remote fallback renders report preview-not-pixel-identical. Supported agent element types: rectangle, ellipse, diamond, text, arrow, line, and freedraw. Embed with ![[drawing.excalidraw]].',
38
+ guide: 'Excalidraw scene JSON managed by the canvas editor. Use create_excalidraw and edit_excalidraw rather than raw text edits. Element order is back-to-front; create supports beforeElementId and afterElementId, while edit supports relationship-aware translation, reorder, same-ID verification, and bound-text placement normalization. Container or group translation also moves bound text and grouped members. Standalone auto-resizing text recalculates its bounds when text metrics change; bound text whose font, size, line height, or content changes is re-centered and remeasured vertically. Line, arrow, and freedraw dimensions are derived from points. Creation and editing support inline inspection and optional rendering; verify_excalidraw can return compact layout diagnostics without an image. Remote fallback renders report preview-not-pixel-identical. Supported agent element types: rectangle, ellipse, diamond, text, arrow, line, and freedraw. Embed with ![[drawing.excalidraw]].',
39
39
  examples: ['![[drawing.excalidraw]]'],
40
40
  },
41
41
  html: {
@@ -14,6 +14,18 @@ const ELEMENT_TYPES = new Set([
14
14
  ]);
15
15
 
16
16
  const LINEAR_TYPES = new Set(['arrow', 'freedraw', 'line']);
17
+ // Matches Excalidraw's DEFAULT_FONT_FAMILY (Excalifont).
18
+ const DEFAULT_TEXT_FONT_FAMILY = 5;
19
+ const TEXT_LAYOUT_CONTAINER_TYPES = new Set(['diamond', 'ellipse', 'rectangle']);
20
+ const TEXT_METRIC_FIELDS = new Set([
21
+ 'autoResize',
22
+ 'containerId',
23
+ 'fontFamily',
24
+ 'fontSize',
25
+ 'lineHeight',
26
+ 'text',
27
+ ]);
28
+ const TEXT_GEOMETRY_FIELDS = new Set(['height', 'width', 'x', 'y']);
17
29
 
18
30
  function invalid(message) {
19
31
  const error = new Error(message);
@@ -186,7 +198,7 @@ function addFreeDrawElementFields(element, raw) {
186
198
  function addTextElementFields(element, raw, { fontSize, text }) {
187
199
  element.autoResize = raw.autoResize ?? true;
188
200
  element.containerId = raw.containerId ?? null;
189
- element.fontFamily = raw.fontFamily ?? 1;
201
+ element.fontFamily = raw.fontFamily ?? DEFAULT_TEXT_FONT_FAMILY;
190
202
  element.fontSize = fontSize;
191
203
  element.lineHeight = raw.lineHeight ?? 1.25;
192
204
  element.originalText = raw.originalText ?? text;
@@ -341,6 +353,66 @@ function resolveTranslationIds(elements, requestedIds) {
341
353
  return [...resolved];
342
354
  }
343
355
 
356
+ function textHeight(element) {
357
+ const text = String(element.text ?? '');
358
+ const lineCount = Math.max(1, text.split('\n').length);
359
+ const fontSize = requireNumber(element.fontSize ?? 20, `Element ${element.id} fontSize`);
360
+ const lineHeight = requireNumber(element.lineHeight ?? 1.25, `Element ${element.id} lineHeight`);
361
+ return lineCount * fontSize * lineHeight;
362
+ }
363
+
364
+ function sameNumber(left, right) {
365
+ return Math.abs(left - right) < 0.001;
366
+ }
367
+
368
+ function reflowBoundText(elements, ids, now, alreadyVersionedIds) {
369
+ const activeById = new Map(
370
+ elements.filter((element) => !element.isDeleted).map((element) => [element.id, element]),
371
+ );
372
+ let reflowed = 0;
373
+
374
+ ids.forEach((id) => {
375
+ const text = activeById.get(id);
376
+ if (text?.type !== 'text' || !text.containerId) return;
377
+
378
+ const container = activeById.get(text.containerId);
379
+ if (
380
+ !container
381
+ || !TEXT_LAYOUT_CONTAINER_TYPES.has(container.type)
382
+ || Number(container.angle ?? 0) !== 0
383
+ ) {
384
+ return;
385
+ }
386
+
387
+ const width = requireNumber(text.width, `Element ${id} width`);
388
+ const height = textHeight(text);
389
+ const x = requireNumber(container.x, `Element ${text.containerId} x`)
390
+ + ((requireNumber(container.width, `Element ${text.containerId} width`) - width) / 2);
391
+ const y = requireNumber(container.y, `Element ${text.containerId} y`)
392
+ + ((requireNumber(container.height, `Element ${text.containerId} height`) - height) / 2);
393
+
394
+ if (
395
+ sameNumber(text.x, x)
396
+ && sameNumber(text.y, y)
397
+ && sameNumber(text.height, height)
398
+ ) {
399
+ return;
400
+ }
401
+
402
+ const positioned = { ...text, height, x, y };
403
+ const next = alreadyVersionedIds.has(id)
404
+ ? positioned
405
+ : bumpElementVersion(positioned, now, 'bound-text-layout');
406
+ const elementIndex = elements.indexOf(text);
407
+ elements[elementIndex] = next;
408
+ activeById.set(id, next);
409
+ alreadyVersionedIds.add(id);
410
+ reflowed += 1;
411
+ });
412
+
413
+ return reflowed;
414
+ }
415
+
344
416
  export function createAgentExcalidrawScene(rawElements) {
345
417
  if (!Array.isArray(rawElements) || rawElements.length < 1 || rawElements.length > 200) {
346
418
  throw invalid('Excalidraw scene must contain 1 to 200 elements');
@@ -372,6 +444,10 @@ export function createAgentExcalidrawScene(rawElements) {
372
444
  }
373
445
 
374
446
  export function applyAgentExcalidrawEdits(scene, edits = {}) {
447
+ return applyAgentExcalidrawEditsWithSummary(scene, edits).scene;
448
+ }
449
+
450
+ export function applyAgentExcalidrawEditsWithSummary(scene, edits = {}) {
375
451
  requireObject(scene, 'Excalidraw scene');
376
452
  if (scene.type !== 'excalidraw' || !Array.isArray(scene.elements)) {
377
453
  throw invalid('Document is not a valid Excalidraw scene');
@@ -383,10 +459,14 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
383
459
  const remove = edits.delete ?? [];
384
460
  const reorder = edits.reorder ?? [];
385
461
  const translate = edits.translate ?? null;
462
+ const normalizeTextPlacement = edits.normalizeTextPlacement;
386
463
  const operations = [create, update, replace, remove, reorder];
387
464
  if (!operations.every(Array.isArray)) {
388
465
  throw invalid('Excalidraw edit operations must be arrays');
389
466
  }
467
+ if (normalizeTextPlacement !== undefined && normalizeTextPlacement !== true) {
468
+ throw invalid('normalizeTextPlacement must be true when provided');
469
+ }
390
470
  let translatedIds = [];
391
471
  let translateDx = 0;
392
472
  let translateDy = 0;
@@ -405,7 +485,11 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
405
485
  throw invalid('Translate operation must move elements');
406
486
  }
407
487
  }
408
- const operationCount = operations.reduce((count, entries) => count + entries.length, translatedIds.length);
488
+ const normalizationOperationCount = normalizeTextPlacement ? 1 : 0;
489
+ const operationCount = operations.reduce(
490
+ (count, entries) => count + entries.length,
491
+ translatedIds.length + normalizationOperationCount,
492
+ );
409
493
  if (operationCount < 1) {
410
494
  throw invalid('Excalidraw edits must include at least one operation');
411
495
  }
@@ -417,6 +501,7 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
417
501
  let elements = scene.elements.map((element) => ({ ...element }));
418
502
  const byId = new Map(elements.map((element) => [element.id, element]));
419
503
  const alreadyVersionedIds = new Set();
504
+ const autoReflowIds = new Set();
420
505
  const createdElements = create.map((raw) => {
421
506
  const element = normalizeElement(raw, now);
422
507
  if (byId.has(element.id)) throw invalid(`Excalidraw element already exists: ${element.id}`);
@@ -447,8 +532,7 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
447
532
  const resizesStandaloneText = current.type === 'text'
448
533
  && !raw.containerId
449
534
  && raw.autoResize !== false
450
- && ['autoResize', 'fontFamily', 'fontSize', 'lineHeight', 'text']
451
- .some((field) => Object.hasOwn(set, field));
535
+ && [...TEXT_METRIC_FIELDS].some((field) => Object.hasOwn(set, field));
452
536
  if (resizesStandaloneText) {
453
537
  delete raw.width;
454
538
  delete raw.height;
@@ -457,6 +541,12 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
457
541
  elements[elements.indexOf(current)] = next;
458
542
  byId.set(id, next);
459
543
  alreadyVersionedIds.add(id);
544
+ const changesTextMetrics = current.type === 'text'
545
+ && [...TEXT_METRIC_FIELDS].some((field) => Object.hasOwn(set, field));
546
+ const changesTextGeometry = [...TEXT_GEOMETRY_FIELDS].some((field) => Object.hasOwn(set, field));
547
+ if (changesTextMetrics && !changesTextGeometry) {
548
+ autoReflowIds.add(id);
549
+ }
460
550
  });
461
551
  replace.forEach((operation) => {
462
552
  requireObject(operation, 'Replace operation');
@@ -481,7 +571,10 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
481
571
  });
482
572
  if (translatedIds.length > 0) {
483
573
  translatedIds = resolveTranslationIds(elements, translatedIds);
484
- const expandedOperationCount = operations.reduce((count, entries) => count + entries.length, translatedIds.length);
574
+ const expandedOperationCount = operations.reduce(
575
+ (count, entries) => count + entries.length,
576
+ translatedIds.length + normalizationOperationCount,
577
+ );
485
578
  if (expandedOperationCount > 200) {
486
579
  throw invalid('Excalidraw edits cannot exceed 200 operations including related translations');
487
580
  }
@@ -515,8 +608,17 @@ export function applyAgentExcalidrawEdits(scene, edits = {}) {
515
608
  const id = String(operation.id ?? '').trim();
516
609
  moveElement(elements, id, operation, `Reorder ${id}`);
517
610
  });
611
+ const reflowIds = normalizeTextPlacement
612
+ ? elements
613
+ .filter((element) => element.type === 'text' && !element.isDeleted && element.containerId)
614
+ .map((element) => element.id)
615
+ : [...autoReflowIds];
616
+ const reflowed = reflowBoundText(elements, reflowIds, now, alreadyVersionedIds);
518
617
  validateUniqueIds(elements);
519
618
  elements = normalizeElementOrder(elements, now, alreadyVersionedIds);
520
619
  refreshArrowBindings(elements);
521
- return { ...scene, elements };
620
+ return {
621
+ reflowed,
622
+ scene: { ...scene, elements },
623
+ };
522
624
  }
@@ -5,6 +5,19 @@ const RENDERED_TYPES = new Set([...BASIC_SHAPE_TYPES, ...LINEAR_TYPES, 'text']);
5
5
  const MAX_SUMMARY_ELEMENTS = 500;
6
6
  const MAX_WARNINGS = 200;
7
7
  const MAX_RENDER_DIMENSION = 4096;
8
+ const BOUND_TEXT_CENTER_TOLERANCE = 2;
9
+
10
+ const FONT_FAMILY_NAMES = new Map([
11
+ [1, 'Virgil'],
12
+ [2, 'Helvetica'],
13
+ [3, 'Cascadia'],
14
+ [5, 'Excalifont'],
15
+ [6, 'Nunito'],
16
+ [7, 'Lilita One'],
17
+ [8, 'Comic Shanns'],
18
+ [9, 'Liberation Sans'],
19
+ [10, 'Assistant'],
20
+ ]);
8
21
 
9
22
  function finiteNumber(value, fallback = 0) {
10
23
  const number = Number(value);
@@ -182,6 +195,9 @@ function summarizeElement(element, paintOrder, activeElements) {
182
195
  if (elementBehind?.id) summary.inFrontOf = String(elementBehind.id);
183
196
  if (element?.type === 'text') summary.text = String(element.text ?? '');
184
197
  if (element?.type === 'text') {
198
+ const fontFamily = finiteNumber(element.fontFamily, 5);
199
+ summary.fontFamily = fontFamily;
200
+ summary.fontName = FONT_FAMILY_NAMES.get(fontFamily) ?? `Unknown (${fontFamily})`;
185
201
  summary.fontSize = finiteNumber(element.fontSize, 20);
186
202
  summary.lineHeight = finiteNumber(element.lineHeight, 1.25);
187
203
  if (element.containerId) summary.containerId = String(element.containerId);
@@ -209,6 +225,78 @@ function textOverflowWarning(element, bounds, id) {
209
225
  : null;
210
226
  }
211
227
 
228
+ function expectedTextHeight(element) {
229
+ const lines = String(element?.text ?? '').split('\n');
230
+ return Math.max(1, lines.length)
231
+ * finiteNumber(element?.fontSize, 20)
232
+ * finiteNumber(element?.lineHeight, 1.25);
233
+ }
234
+
235
+ function collectBoundTextLayout(elements) {
236
+ const activeById = new Map(elements.map((element) => [String(element.id), element]));
237
+ const layout = {
238
+ boundText: {
239
+ misaligned: 0,
240
+ outsideContainer: 0,
241
+ staleHeight: 0,
242
+ total: 0,
243
+ },
244
+ };
245
+ const warnings = [];
246
+
247
+ elements.forEach((element) => {
248
+ if (element?.type !== 'text' || !element.containerId) return;
249
+ const container = activeById.get(String(element.containerId));
250
+ if (!container || !BASIC_SHAPE_TYPES.has(container.type) || finiteNumber(container.angle) !== 0) {
251
+ return;
252
+ }
253
+ const textBounds = elementBounds(element);
254
+ const containerBounds = elementBounds(container);
255
+ if (!textBounds || !containerBounds) return;
256
+
257
+ const id = String(element.id ?? '');
258
+ const containerId = String(container.id ?? '');
259
+ const textCenterX = textBounds.x + (textBounds.width / 2);
260
+ const textCenterY = textBounds.y + (textBounds.height / 2);
261
+ const containerCenterX = containerBounds.x + (containerBounds.width / 2);
262
+ const containerCenterY = containerBounds.y + (containerBounds.height / 2);
263
+ const offsetX = textCenterX - containerCenterX;
264
+ const offsetY = textCenterY - containerCenterY;
265
+ const centered = Math.abs(offsetX) <= BOUND_TEXT_CENTER_TOLERANCE
266
+ && Math.abs(offsetY) <= BOUND_TEXT_CENTER_TOLERANCE;
267
+
268
+ layout.boundText.total += 1;
269
+ if (!centered) {
270
+ layout.boundText.misaligned += 1;
271
+ warnings.push(warning(
272
+ 'bound-text-not-centered',
273
+ `Bound text ${id} is offset ${Math.round(offsetX)} horizontally and ${Math.round(offsetY)} vertically from container ${containerId}.`,
274
+ [id, containerId],
275
+ ));
276
+ }
277
+
278
+ if (!boxContains(containerBounds, textBounds)) {
279
+ layout.boundText.outsideContainer += 1;
280
+ warnings.push(warning(
281
+ 'bound-text-outside-container',
282
+ `Bound text ${id} extends outside container ${containerId}.`,
283
+ [id, containerId],
284
+ ));
285
+ }
286
+
287
+ if (Math.abs(textBounds.height - expectedTextHeight(element)) > BOUND_TEXT_CENTER_TOLERANCE) {
288
+ layout.boundText.staleHeight += 1;
289
+ warnings.push(warning(
290
+ 'bound-text-height-stale',
291
+ `Bound text ${id} has height ${Math.round(textBounds.height)} but its current text metrics require ${Math.round(expectedTextHeight(element))}.`,
292
+ [id, containerId],
293
+ ));
294
+ }
295
+ });
296
+
297
+ return { layout, warnings };
298
+ }
299
+
212
300
  function boundEndpointWarning(element, binding, endpointName, activeById) {
213
301
  if (!binding?.elementId || !LINEAR_TYPES.has(element?.type) || !Array.isArray(element.points)) {
214
302
  return null;
@@ -336,7 +424,11 @@ export function inspectAgentExcalidrawScene(scene = {}, {
336
424
  const activeElements = (Array.isArray(scene?.elements) ? scene.elements : [])
337
425
  .filter((element) => element && !element.isDeleted);
338
426
  const boxes = activeElements.map(elementBounds).filter(Boolean);
339
- const warnings = collectWarnings(activeElements, { inspectOcclusion });
427
+ const boundTextLayout = collectBoundTextLayout(activeElements);
428
+ const warnings = [
429
+ ...collectWarnings(activeElements, { inspectOcclusion }),
430
+ ...boundTextLayout.warnings,
431
+ ].slice(0, MAX_WARNINGS);
340
432
  return {
341
433
  bounds: mergeBounds(boxes),
342
434
  elementCount: activeElements.length,
@@ -348,6 +440,8 @@ export function inspectAgentExcalidrawScene(scene = {}, {
348
440
  truncated: (!includeElements && activeElements.length > 0)
349
441
  || activeElements.length > MAX_SUMMARY_ELEMENTS
350
442
  || warnings.length >= MAX_WARNINGS,
443
+ layout: boundTextLayout.layout,
444
+ valid: warnings.length === 0,
351
445
  warnings,
352
446
  };
353
447
  }