collabmd 0.1.47 → 0.1.49

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 (305) hide show
  1. package/README.md +70 -11
  2. package/bin/collabmd.js +3 -0
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-C-nmgL5g.js +1 -0
  4. package/dist/client/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
  5. package/dist/client/assets/abnfDiagram-VCTEODGH-CdVZqicp.js +1 -0
  6. package/dist/client/assets/{architectureDiagram-5GKGNRK7-I39sYjHI.js → architectureDiagram-5GKGNRK7-wUo0bXif.js} +3 -3
  7. package/dist/client/assets/babel-CY5KOv-I.js +16 -0
  8. package/dist/client/assets/{blockDiagram-NRAW4CY4-C6DtJy5Y.js → blockDiagram-I7D4REHJ-BRSK3m49.js} +4 -4
  9. package/dist/client/assets/browser-utils-DbXSMI-6.js +1 -0
  10. package/dist/client/assets/{c4Diagram-UCG6FXSJ-CtWtxS9_.js → c4Diagram-7LVT6UL2-yD2poxqw.js} +1 -1
  11. package/dist/client/assets/channel-Fa4GS_-F.js +1 -0
  12. package/dist/client/assets/chunk-2E4U76K2-BPnTT-J3.js +2 -0
  13. package/dist/client/assets/{chunk-TEH6E4GO-DVayPj-q.js → chunk-4HAMMTFA-DStbIfJ1.js} +20 -20
  14. package/dist/client/assets/{chunk-75Z2AOVW-CdFSaPjz.js → chunk-75Z2AOVW-C5pGd3W9.js} +1 -1
  15. package/dist/client/assets/{chunk-CLGD4ZFX-DQLgbQrv.js → chunk-CLGD4ZFX-BMeArk03.js} +1 -1
  16. package/dist/client/assets/chunk-DU6HZSFF-Zkp69c6c.js +127 -0
  17. package/dist/client/assets/{chunk-F27PBJKO-CNHIFhjo.js → chunk-F27PBJKO-D4xNct1r.js} +1 -1
  18. package/dist/client/assets/{chunk-GMAD6QVW-CbcBqPM5.js → chunk-GMAD6QVW-NZ6WpDb8.js} +1 -1
  19. package/dist/client/assets/{chunk-OBVCFTLP-BJR7u1jh.js → chunk-GVQU2GXP-D8SDprfX.js} +1 -1
  20. package/dist/client/assets/{chunk-G27WJ6UU-D9-eg537.js → chunk-IMKFNOWR-D8jEuU3Q.js} +2 -2
  21. package/dist/client/assets/{chunk-JQ64N6SF-DSFNH4bh.js → chunk-L3NEJ4N5-aijKP-eh.js} +1 -1
  22. package/dist/client/assets/chunk-OSK3NFVY-CCbLQAMa.js +10 -0
  23. package/dist/client/assets/{chunk-P2QGCYS3-BRpqY32H.js → chunk-P2QGCYS3-Oag_FdCq.js} +1 -1
  24. package/dist/client/assets/{chunk-POPQ4Y6H-Cb4SlVZF.js → chunk-POPQ4Y6H-CYnpIgXT.js} +1 -1
  25. package/dist/client/assets/{chunk-PWAF6VOD-Cz8IwBB5.js → chunk-PWAF6VOD-JSNrcBmP.js} +1 -1
  26. package/dist/client/assets/{chunk-RM4UPSZO-CWRwxNWJ.js → chunk-RM4UPSZO-DOWllDY8.js} +4 -4
  27. package/dist/client/assets/{chunk-RHFEMEQ7-CWY8cf4H.js → chunk-SHT3W25Y-BiQGljao.js} +5 -5
  28. package/dist/client/assets/{chunk-SVP7TREG-CyHOmcac.js → chunk-SVP7TREG-DB485R5x.js} +1 -1
  29. package/dist/client/assets/{chunk-LCL6LL3I-DmDkVukh.js → chunk-TICWLB2K-8rAVvoS3.js} +4 -4
  30. package/dist/client/assets/{chunk-CKBBP62Z-DG26UiBv.js → chunk-TLUHSLCS-DTY5v0aj.js} +2 -2
  31. package/dist/client/assets/classDiagram-ZZMXUADV-BsQWoR3Q.js +1 -0
  32. package/dist/client/assets/classDiagram-v2-VYDZK3BY-BsQWoR3Q.js +1 -0
  33. package/dist/client/assets/{comment-thread-store-CdcwrObc.js → comment-thread-store-CX98zR6q.js} +1 -1
  34. package/dist/client/assets/comment-threads-BnRwo5B9.js +4 -0
  35. package/dist/client/assets/{cynefinDiagram-5FMLGOSQ-CdTPi2yO.js → cynefinDiagram-5FMLGOSQ-rTz9RhFH.js} +1 -1
  36. package/dist/client/assets/{dagre-3AP2YEHR-5gtJtd0O.js → dagre-GXQ25YYZ-Cr67wLpQ.js} +2 -2
  37. package/dist/client/assets/{diagram-S7CK7UJ4-BudWz9WU.js → diagram-S7CK7UJ4-DywERe__.js} +2 -2
  38. package/dist/client/assets/{diagram-UQ7AKVKN-3v4rbH-s.js → diagram-UQ7AKVKN-CNYlXtu4.js} +1 -1
  39. package/dist/client/assets/diagram-VSXAHHWV-0H1a61Bn.js +3 -0
  40. package/dist/client/assets/{diagram-VX7I27RA-C_-rj0sw.js → diagram-VX7I27RA-CsJbsx5F.js} +1 -1
  41. package/dist/client/assets/{diagram-Z3DM3KII-B4yxavgj.js → diagram-Z3DM3KII-D0mLxEgI.js} +1 -1
  42. package/dist/client/assets/dist--hk9I5HQ.js +1 -0
  43. package/dist/client/assets/{dist-DutPuFmC.js → dist-B1XEa-Zs.js} +1 -1
  44. package/dist/client/assets/dist-Bd1JucQF.js +1 -0
  45. package/dist/client/assets/{dist-DZAAWTG-.js → dist-C0G3AaXG.js} +1 -1
  46. package/dist/client/assets/dist-ChRoo3IB.js +9 -0
  47. package/dist/client/assets/dist-Dm4w5UId.js +1 -0
  48. package/dist/client/assets/{dist-B_yQaEv_.js → dist-DpYDHR9p.js} +1 -1
  49. package/dist/client/assets/{dist-CietwTVS.js → dist-DzNmC81X.js} +1 -1
  50. package/dist/client/assets/{dist-DDUn5zTz.js → dist-GvvCNBe4.js} +1 -1
  51. package/dist/client/assets/dist-JaU3aRlD.js +19 -0
  52. package/dist/client/assets/{dist-Bw3VIE_v.js → dist-TW8iFRyW.js} +1 -1
  53. package/dist/client/assets/{dist-Dir5dDKZ.js → dist-jVU5Be5P.js} +1 -1
  54. package/dist/client/assets/document-formatter-rDDjRfZ2.js +2 -0
  55. package/dist/client/assets/drawioEditor-JubEEha7.js +9 -0
  56. package/dist/client/assets/ebnfDiagram-PWID7BFC-HeTxHpCU.js +1 -0
  57. package/dist/client/assets/editor-session-Bk6oIvSr.js +54 -0
  58. package/dist/client/assets/embedded-editor-base-BlCgz6mw.css +1 -0
  59. package/dist/client/assets/{erDiagram-SSCWMZ5O-C-iy6VkX.js → erDiagram-RLTQ6QDP-CbrDdd5P.js} +2 -2
  60. package/dist/client/assets/{es-CAsWR6hG.js → es-Bfdp096f.js} +13 -13
  61. package/dist/client/assets/estree-CuT_pB8K.js +44 -0
  62. package/dist/client/assets/excalidraw-element-link-YLIaTnVF.js +7 -0
  63. package/dist/client/assets/{excalidraw-scene-BOben2gr.js → excalidraw-scene-6uROebca.js} +1 -1
  64. package/dist/client/assets/{excalidraw-editor-BlcN6umJ.css → excalidrawEditor-BbSbI80a.css} +1 -1
  65. package/dist/client/assets/excalidrawEditor-dBMbRX_S.js +9 -0
  66. package/dist/client/assets/export-page-CRRQ2NEl.js +57 -0
  67. package/dist/client/assets/exportDocument-BlQRd9_m.js +2 -0
  68. package/dist/client/assets/exportDocument-CNSbjZwu.css +1 -0
  69. package/dist/client/assets/{file-icon-svg-CQAjlWjK.js → file-icon-svg-Y_kpF957.js} +1 -1
  70. package/dist/client/assets/file-kind-BwMIcZbi.js +1 -0
  71. package/dist/client/assets/file-search-DDLyyLDU.js +1 -0
  72. package/dist/client/assets/flowDiagram-HODETNUW-D5Gy0wmg.js +1 -0
  73. package/dist/client/assets/{ganttDiagram-EL5Y4UJY-DtKHAbez.js → ganttDiagram-EL5Y4UJY-BHgOYiZz.js} +1 -1
  74. package/dist/client/assets/{gitGraphDiagram-WWUBYQGX-oue8fQ5o.js → gitGraphDiagram-WWUBYQGX-Dl__X3Sk.js} +1 -1
  75. package/dist/client/assets/html-Cdnr2qzU.js +25 -0
  76. package/dist/client/assets/image-ZVKINSPA-DgzW5zAy.js +1 -0
  77. package/dist/client/assets/index-D3RER1SZ.js +1023 -0
  78. package/dist/client/assets/index-DREVKl_K.css +1 -0
  79. package/dist/client/assets/{infoDiagram-RXCK75RN-BMzo6KIn.js → infoDiagram-27XIBGKW-DBpoANC9.js} +1 -1
  80. package/dist/client/assets/{ishikawaDiagram-5VMMS53U-BIM3h287.js → ishikawaDiagram-5VMMS53U-BMPC6hfp.js} +1 -1
  81. package/dist/client/assets/{journeyDiagram-EYS64GPL-mF6Lh8O-.js → journeyDiagram-3NMN7TZE-B1sApUmM.js} +2 -2
  82. package/dist/client/assets/{kanban-definition-3QL26DDD-DLN2NyoR.js → kanban-definition-UXKFOSKX-C9yP4td1.js} +4 -4
  83. package/dist/client/assets/{line-BfTWJmgf.js → line-BFl3ujec.js} +1 -1
  84. package/dist/client/assets/markdown-CByV-4CU.js +70 -0
  85. package/dist/client/assets/{mermaid.core-CLZBlpIW.js → mermaid.core-BrY09czX.js} +5 -5
  86. package/dist/client/assets/mermaid.core-DfcNfOTv.js +1 -0
  87. package/dist/client/assets/{mindmap-definition-FBJOCRG2-CRyHaHTk.js → mindmap-definition-YA3MSWOX-BUQHcYbK.js} +8 -8
  88. package/dist/client/assets/pegDiagram-XKGWAZYB-Bi2Iml7Z.js +1 -0
  89. package/dist/client/assets/{pieDiagram-E7YTZNPT-B5OZPb88.js → pieDiagram-E7YTZNPT-_gYXnMoi.js} +1 -1
  90. package/dist/client/assets/preview-render-compiler-CfxJYldJ.js +41 -0
  91. package/dist/client/assets/preview-render-compiler-Cu8_i9iS.js +1 -0
  92. package/dist/client/assets/{preview-render-worker-BmN79bVc.js → preview-render-worker-c4Yi93qW.js} +41 -35
  93. package/dist/client/assets/prod-BiJL30sl.js +1 -0
  94. package/dist/client/assets/prod-qAk7rHa4.js +177 -0
  95. package/dist/client/assets/{quadrantDiagram-AXDQQJYC-Drrw14YH.js → quadrantDiagram-AXDQQJYC-DwexhEhd.js} +1 -1
  96. package/dist/client/assets/quick-switcher-controller-BoIK_wuG.js +1 -0
  97. package/dist/client/assets/railroadDiagram-O6MQD6OU-BVA5UbMu.js +1 -0
  98. package/dist/client/assets/{requirementDiagram-EFPCY7ZU-CRZG6mRB.js → requirementDiagram-BXWQKSXE-C4cKwiIw.js} +2 -2
  99. package/dist/client/assets/runtime-config-DcmnGcXU.js +1 -0
  100. package/dist/client/assets/{sankeyDiagram-P5KCCOFB-DvarEJpo.js → sankeyDiagram-P5KCCOFB-B5HHkRT2.js} +1 -1
  101. package/dist/client/assets/{sequenceDiagram-WJ2MYXX4-B4oWlb-w.js → sequenceDiagram-WJ2MYXX4-BX6jqJFD.js} +6 -6
  102. package/dist/client/assets/standalone-6z5x8CWe.js +29 -0
  103. package/dist/client/assets/{stateDiagram-HBIQ2CUA-qbHIIqRZ.js → stateDiagram-D77RDMKH-CmqxyRGx.js} +1 -1
  104. package/dist/client/assets/stateDiagram-v2-MP3YSRHH-zoLLQVyh.js +1 -0
  105. package/dist/client/assets/{swimlanes-XN3QIQJK-xB6CtUGj.js → swimlanes-42K2YHIH-Bmgb9Zld.js} +1 -1
  106. package/dist/client/assets/swimlanesDiagram-VR7AAH4N-DS-KQN37.js +8 -0
  107. package/dist/client/assets/{timeline-definition-24CTP7MA-Lj_yTNlY.js → timeline-definition-24CTP7MA-BA-lVH6P.js} +1 -1
  108. package/dist/client/assets/vault-api-client-iZLhMJKe.js +6 -0
  109. package/dist/client/assets/{vennDiagram-4TSXK5OY-BekRp5Y0.js → vennDiagram-4TSXK5OY-DNdUC_Xj.js} +1 -1
  110. package/dist/client/assets/{wardleyDiagram-VM6X3IG4-kdnV_Hdm.js → wardleyDiagram-VM6X3IG4-C2oY-YbF.js} +1 -1
  111. package/dist/client/assets/wiki-link-resolver-DFIwErjc.js +1 -0
  112. package/dist/client/assets/{xychartDiagram-S5SC5T6Z-DufGwNSB.js → xychartDiagram-S5SC5T6Z-CoIR8CBX.js} +1 -1
  113. package/dist/client/assets/yaml-9ltHPDNO.js +154 -0
  114. package/dist/client/assets/{yjs-provider-reset-guard-DE0vINDP.js → yjs-provider-reset-guard-9ul1qF6k.js} +1 -1
  115. package/dist/client/drawio-editor.html +11 -3
  116. package/dist/client/excalidraw-editor.html +45 -2
  117. package/dist/client/export-document.html +3 -3
  118. package/dist/client/index.html +106 -52
  119. package/integrations/pi/index.ts +94 -0
  120. package/package.json +41 -29
  121. package/src/client/app/drawio-editor.html +2 -2
  122. package/src/client/app/excalidraw-editor.html +2 -2
  123. package/src/client/app/export-document.html +1 -1
  124. package/src/client/app/index.html +88 -50
  125. package/src/client/app/main-entry.js +15 -1
  126. package/src/client/application/app-shell/chat-feature.js +7 -22
  127. package/src/client/application/app-shell/export-feature.js +17 -1
  128. package/src/client/application/app-shell/git-feature.js +51 -14
  129. package/src/client/application/app-shell/presence-feature.js +8 -25
  130. package/src/client/application/app-shell/ui-feature-identity.js +13 -0
  131. package/src/client/application/app-shell/ui-feature-shell.js +199 -99
  132. package/src/client/application/app-shell/ui-feature-sidebar.js +43 -7
  133. package/src/client/application/app-shell/ui-feature-tab-activity.js +19 -6
  134. package/src/client/application/app-shell/ui-feature-toolbar.js +16 -129
  135. package/src/client/application/app-shell-elements.js +8 -0
  136. package/src/client/application/preview-render-compiler.js +1 -87
  137. package/src/client/application/preview-render-scheduler.js +8 -24
  138. package/src/client/application/preview-renderer.js +2 -2
  139. package/src/client/application/webmcp-diagram-renderer.js +47 -0
  140. package/src/client/application/workspace-coordinator.js +23 -4
  141. package/src/client/application/workspace-preview-controller.js +120 -2
  142. package/src/client/application/workspace-route-controller.js +11 -1
  143. package/src/client/assets/vendor/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  144. package/src/client/assets/vendor/jetbrains-mono/OFL.txt +93 -0
  145. package/src/client/bootstrap/collabmd-app-shell.js +99 -6
  146. package/src/client/domain/document-formatter.js +193 -0
  147. package/src/client/domain/excalidraw-element-link.js +73 -0
  148. package/src/client/domain/excalidraw-scene.js +21 -0
  149. package/src/client/domain/file-search.js +73 -0
  150. package/src/client/domain/git-labels.js +5 -0
  151. package/src/client/domain/hash-routes.js +8 -0
  152. package/src/client/domain/room.js +1 -5
  153. package/src/client/domain/runtime-paths.js +5 -0
  154. package/src/client/domain/vault-paths.js +6 -4
  155. package/src/client/domain/wiki-link-completions.js +20 -20
  156. package/src/client/drawio-editor.js +8 -3
  157. package/src/client/excalidraw-editor.js +287 -16
  158. package/src/client/export/export-host.js +59 -36
  159. package/src/client/export/export-page.js +14 -4
  160. package/src/client/export/export-pipeline.js +270 -42
  161. package/src/client/infrastructure/agent-connection-api-client.js +23 -0
  162. package/src/client/infrastructure/auth-client.js +3 -13
  163. package/src/client/infrastructure/editor-session.js +15 -0
  164. package/src/client/infrastructure/editor-view-adapter.js +73 -14
  165. package/src/client/infrastructure/excalidraw-room-client.js +80 -1
  166. package/src/client/infrastructure/git-api-client.js +39 -33
  167. package/src/client/infrastructure/lobby-presence.js +2 -5
  168. package/src/client/infrastructure/runtime-config.js +11 -1
  169. package/src/client/infrastructure/tab-activity-lock.js +2 -5
  170. package/src/client/infrastructure/vault-api-client.js +33 -26
  171. package/src/client/infrastructure/webmcp-tool-registry.js +283 -0
  172. package/src/client/infrastructure/workspace-sync-client.js +6 -4
  173. package/src/client/presentation/agent-connection-controller.js +255 -0
  174. package/src/client/presentation/backlinks-panel.js +3 -0
  175. package/src/client/presentation/bases-preview-controller.js +59 -26
  176. package/src/client/presentation/comment-ui/comment-ui-card.js +4 -2
  177. package/src/client/presentation/create-menu-presenter.js +19 -16
  178. package/src/client/presentation/excalidraw-embed-controller.js +164 -4
  179. package/src/client/presentation/file-action-controller.js +15 -2
  180. package/src/client/presentation/file-explorer-controller.js +3 -0
  181. package/src/client/presentation/file-explorer-view.js +71 -12
  182. package/src/client/presentation/file-history-view-controller.js +19 -12
  183. package/src/client/presentation/file-tree-state.js +1 -11
  184. package/src/client/presentation/git-diff-view-controller.js +70 -53
  185. package/src/client/presentation/git-panel-controller.js +86 -32
  186. package/src/client/presentation/image-lightbox-controller.js +20 -16
  187. package/src/client/presentation/layout-controller.js +3 -1
  188. package/src/client/presentation/quick-switcher-controller.js +74 -232
  189. package/src/client/presentation/quick-switcher-text-search.js +10 -14
  190. package/src/client/styles/components/navigation.css +1 -2
  191. package/src/client/styles/components/scrollbars.css +10 -0
  192. package/src/client/styles/export-document.css +44 -29
  193. package/src/client/styles/features/agent-connection.css +202 -0
  194. package/src/client/styles/features/collaboration-chat.css +8 -1
  195. package/src/client/styles/features/collaboration-dialogs.css +16 -1
  196. package/src/client/styles/features/collaboration-presence.css +30 -5
  197. package/src/client/styles/features/diff-toolbar.css +1 -1
  198. package/src/client/styles/features/media-lightbox.css +12 -3
  199. package/src/client/styles/features/preview-markdown.css +54 -0
  200. package/src/client/styles/features/quick-switcher.css +20 -11
  201. package/src/client/styles/foundation/themes.css +2 -0
  202. package/src/client/styles/foundation/tokens.css +8 -0
  203. package/src/client/styles/layout/editor-page.css +25 -11
  204. package/src/client/styles/layout/responsive.css +2 -20
  205. package/src/client/styles/layout/shell.css +77 -24
  206. package/src/client/styles/layout/sidebar.css +7 -4
  207. package/src/client/styles/layout/view-modes.css +2 -0
  208. package/src/client/styles/overrides/codemirror.css +31 -19
  209. package/src/client/styles/primitives/controls.css +21 -54
  210. package/src/client/styles/style.css +1 -0
  211. package/src/client/styles/surfaces/excalidraw-editor.css +42 -0
  212. package/src/domain/agent-tool-definitions.js +796 -0
  213. package/src/domain/collabmd-content-capabilities.js +149 -0
  214. package/src/domain/collaboration-protocol.js +2 -0
  215. package/src/domain/comment-threads.js +3 -5
  216. package/src/domain/diagram-source.js +50 -0
  217. package/src/domain/editable-content-revision.js +10 -0
  218. package/src/domain/editable-text.js +3 -0
  219. package/src/domain/exact-text-edits.js +69 -0
  220. package/src/domain/excalidraw-agent-scene.js +522 -0
  221. package/src/domain/excalidraw-agent-verification.js +460 -0
  222. package/src/domain/excalidraw-room-codec.js +1 -5
  223. package/src/domain/file-kind.js +12 -1
  224. package/src/domain/video-embed.js +76 -0
  225. package/src/server/application/agent-connection-service.js +178 -0
  226. package/src/server/application/agent-content-service.js +773 -0
  227. package/src/server/application/workspace-reconciliation.js +5 -7
  228. package/src/server/config/env.js +51 -1
  229. package/src/server/create-app-server.js +36 -0
  230. package/src/server/domain/bases/base-query-service.js +1 -5
  231. package/src/server/domain/collaboration/collaboration-room.js +121 -25
  232. package/src/server/domain/collaboration/protocol.js +4 -0
  233. package/src/server/domain/hosted-workspace.js +21 -0
  234. package/src/server/domain/markdown-reference-extractor.js +15 -1
  235. package/src/server/domain/ripgrep-search-service.js +110 -37
  236. package/src/server/infrastructure/git/git-service.js +19 -1
  237. package/src/server/infrastructure/git/history-service.js +1 -1
  238. package/src/server/infrastructure/git/local-exclude.js +25 -0
  239. package/src/server/infrastructure/git/parsers.js +19 -17
  240. package/src/server/infrastructure/git/path-utils.js +0 -16
  241. package/src/server/infrastructure/git/status-service.js +1 -1
  242. package/src/server/infrastructure/git/untracked-files.js +12 -21
  243. package/src/server/infrastructure/http/create-agent-api-handler.js +171 -0
  244. package/src/server/infrastructure/http/create-git-api-command-handler.js +32 -0
  245. package/src/server/infrastructure/http/create-request-handler.js +28 -0
  246. package/src/server/infrastructure/http/create-static-handler.js +6 -0
  247. package/src/server/infrastructure/mcp/create-agent-mcp-handler.js +199 -0
  248. package/src/server/infrastructure/persistence/agent-connection-store.js +120 -0
  249. package/src/server/infrastructure/persistence/path-utils.js +10 -4
  250. package/src/server/infrastructure/persistence/pull-backup-store.js +2 -27
  251. package/src/server/infrastructure/persistence/vault-file-store.js +11 -2
  252. package/src/server/shared/agent-tool-image.js +22 -0
  253. package/src/server/shared/agent-tool-rate-limiter.js +20 -0
  254. package/src/server/startup/git-remote-bootstrap.js +5 -33
  255. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js +0 -1
  256. package/dist/client/assets/abnfDiagram-VCTEODGH-BNDLzJ7L.js +0 -1
  257. package/dist/client/assets/browser-utils--H_DkyEF.js +0 -1
  258. package/dist/client/assets/channel-CaoKA_We.js +0 -1
  259. package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +0 -2
  260. package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +0 -127
  261. package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +0 -10
  262. package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +0 -1
  263. package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +0 -1
  264. package/dist/client/assets/comment-threads-9J6Em-_y.js +0 -4
  265. package/dist/client/assets/comment-ui-shared-DWkk9Vh3.js +0 -7
  266. package/dist/client/assets/diagram-VSXAHHWV-CQRVEZR7.js +0 -3
  267. package/dist/client/assets/dist-73RPdcyU.js +0 -1
  268. package/dist/client/assets/dist-CH-sQu3r.js +0 -1
  269. package/dist/client/assets/drawio-editor-BjrxTe3l.js +0 -9
  270. package/dist/client/assets/drawioEditor-DUVZjSSr.js +0 -2
  271. package/dist/client/assets/ebnfDiagram-PWID7BFC-OXa8VEp1.js +0 -1
  272. package/dist/client/assets/editor-session-DfZuRgB_.js +0 -54
  273. package/dist/client/assets/embedded-editor-base-DvMynhKu.css +0 -1
  274. package/dist/client/assets/excalidraw-editor-D7pnUCLH.js +0 -9
  275. package/dist/client/assets/excalidraw-mermaid-stub-BNckbX2n.js +0 -1
  276. package/dist/client/assets/excalidraw-mermaid-stub-DE5FTiZB.js +0 -1
  277. package/dist/client/assets/excalidrawEditor-B0jOK3lv.js +0 -2
  278. package/dist/client/assets/export-page-Bs3xE1fg.js +0 -57
  279. package/dist/client/assets/exportDocument-Dg9MjkIk.js +0 -2
  280. package/dist/client/assets/exportDocument-PnYU3v1s.css +0 -1
  281. package/dist/client/assets/file-kind-BbqgGzpc.js +0 -1
  282. package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +0 -1
  283. package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +0 -1
  284. package/dist/client/assets/index-BIpgxyGZ.css +0 -1
  285. package/dist/client/assets/index-Z5sI0Bj-.js +0 -2
  286. package/dist/client/assets/main-Dwnj9Gaq.js +0 -903
  287. package/dist/client/assets/pegDiagram-XKGWAZYB-B31fKPR2.js +0 -1
  288. package/dist/client/assets/preview-render-compiler-BApvlLLo.js +0 -35
  289. package/dist/client/assets/preview-render-compiler-BQ_3h9vD.js +0 -1
  290. package/dist/client/assets/preview-render-profile-CE-5rVTC.js +0 -1
  291. package/dist/client/assets/prod-BiYPMR1i.js +0 -177
  292. package/dist/client/assets/prod-VxdGZ5Ly.js +0 -1
  293. package/dist/client/assets/quick-switcher-controller-ButWPmCI.js +0 -12
  294. package/dist/client/assets/railroadDiagram-O6MQD6OU-BPifP0MB.js +0 -1
  295. package/dist/client/assets/runtime-config-BLrEKVO1.js +0 -1
  296. package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +0 -1
  297. package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +0 -8
  298. package/dist/client/assets/vault-api-client-_LpV1aIn.js +0 -6
  299. package/dist/client/assets/vault-utils-wdQ0RNR9.js +0 -1
  300. package/src/client/app/drawio-editor-entry.js +0 -1
  301. package/src/client/app/excalidraw-editor-entry.js +0 -1
  302. package/src/client/excalidraw-mermaid-stub.js +0 -7
  303. package/src/client/main.js +0 -16
  304. /package/dist/client/assets/{drawio-editor-UQQ8XHou.css → drawioEditor-UQQ8XHou.css} +0 -0
  305. /package/dist/client/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
@@ -0,0 +1,193 @@
1
+ import { getVaultFileKind } from '../../domain/file-kind.js';
2
+
3
+ const FORMATTABLE_FILE_KINDS = new Set(['base', 'html', 'markdown', 'mermaid', 'plantuml']);
4
+ const PLANTUML_BLOCK_OPENERS = [
5
+ [/^if\b.*\bthen\b/iu, 'endif'],
6
+ [/^while\b/iu, 'endwhile'],
7
+ [/^repeat\b(?!\s+while\b)/iu, 'repeat while'],
8
+ [/^switch\b/iu, 'endswitch'],
9
+ [/^fork\b(?!\s+again\b)/iu, 'end fork'],
10
+ [/^split\b(?!\s+again\b)/iu, 'end split'],
11
+ [/^(?:alt|opt|loop|par|critical|group|box|ref\s+over)\b/iu, 'end'],
12
+ [/^break\s+\S/iu, 'end'],
13
+ ];
14
+ const PLANTUML_MIDDLE_PATTERN = /^(?:else(?:if)?|and|fork\s+again|split\s+again|case|option)\b/iu;
15
+
16
+ function getPlantUmlOpaqueBlock(trimmedLine) {
17
+ if (trimmedLine.startsWith("/'")) {
18
+ return trimmedLine.slice(2).includes("'/")
19
+ ? { oneLine: true }
20
+ : { end: (line) => line.includes("'/") };
21
+ }
22
+ const tripleQuoteCount = trimmedLine.split('"""').length - 1;
23
+ if (tripleQuoteCount % 2 === 1) return { end: (line) => line.includes('"""') };
24
+ if (/^<style>.*<\/style>\s*$/iu.test(trimmedLine)) return { oneLine: true };
25
+ if (/^<style>\s*$/iu.test(trimmedLine)) return { end: (line) => /<\/style>/iu.test(line) };
26
+ if (/^!(?:if|ifdef|ifndef)\b/iu.test(trimmedLine)) {
27
+ let depth = 1;
28
+ return { end: (line) => {
29
+ if (/^!(?:if|ifdef|ifndef)\b/iu.test(line)) depth += 1;
30
+ if (/^!endif\b/iu.test(line)) depth -= 1;
31
+ return depth === 0;
32
+ } };
33
+ }
34
+ if (/^!(?:while|foreach)\b/iu.test(trimmedLine)) {
35
+ const endPattern = /^!while\b/iu.test(trimmedLine) ? /^!endwhile\b/iu : /^!endfor\b/iu;
36
+ return { end: (line) => endPattern.test(line) };
37
+ }
38
+ if (/^!(?:definelong|procedure|function)\b/iu.test(trimmedLine)) {
39
+ return { end: (line) => /^!end(?:definelong|procedure|function)\b/iu.test(line) };
40
+ }
41
+ if (/^!\w+/u.test(trimmedLine)) return { oneLine: true };
42
+ if (/^(?:[hr]?note|legend)\b(?!.*:\s*\S)/iu.test(trimmedLine)) {
43
+ return { end: (line) => /^(?:end\s+note|endlegend)\b/iu.test(line) };
44
+ }
45
+ if (/^(?:title|header|footer|caption)\s*$/iu.test(trimmedLine)) {
46
+ const blockName = trimmedLine.toLowerCase();
47
+ return { end: (line) => line.toLowerCase().replace(/\s/gu, '') === `end${blockName}` };
48
+ }
49
+ if (/^(?:json|yaml|salt|sprite)\b.*\{\s*$/iu.test(trimmedLine)) {
50
+ return { braceDepth: 1 };
51
+ }
52
+ return null;
53
+ }
54
+
55
+ function countPlantUmlBraces(line) {
56
+ let count = 0;
57
+ let escaped = false;
58
+ let quoted = false;
59
+ for (const character of line) {
60
+ if (escaped) {
61
+ escaped = false;
62
+ } else if (character === '\\') {
63
+ escaped = true;
64
+ } else if (character === '"') {
65
+ quoted = !quoted;
66
+ } else if (!quoted && character === '{') {
67
+ count += 1;
68
+ } else if (!quoted && character === '}') {
69
+ count -= 1;
70
+ }
71
+ }
72
+ return count;
73
+ }
74
+
75
+ function getPlantUmlCloser(trimmedLine) {
76
+ if (/^\}\s*$/u.test(trimmedLine)) return '}';
77
+ if (/^endif\b/iu.test(trimmedLine)) return 'endif';
78
+ if (/^endwhile\b/iu.test(trimmedLine)) return 'endwhile';
79
+ if (/^repeat\s+while\b/iu.test(trimmedLine)) return 'repeat while';
80
+ if (/^endswitch\b/iu.test(trimmedLine)) return 'endswitch';
81
+ if (/^end\s+fork\b/iu.test(trimmedLine)) return 'end fork';
82
+ if (/^end\s+split\b/iu.test(trimmedLine)) return 'end split';
83
+ if (/^end(?:\s+\w+)?\s*$/iu.test(trimmedLine)) return 'end';
84
+ return null;
85
+ }
86
+
87
+ function getPlantUmlOpener(trimmedLine) {
88
+ if (/\{\s*$/u.test(trimmedLine)) return '}';
89
+ return PLANTUML_BLOCK_OPENERS.find(([pattern]) => pattern.test(trimmedLine))?.[1] ?? null;
90
+ }
91
+
92
+ function indentPlantUml(source) {
93
+ const parts = String(source ?? '').split(/(\r\n|\n|\r)/u);
94
+ const stack = [];
95
+ let opaqueBlock = null;
96
+
97
+ for (let index = 0; index < parts.length; index += 2) {
98
+ const line = parts[index];
99
+ const content = line.replace(/^[\t ]*/u, '');
100
+ const trimmedLine = content.trimEnd();
101
+
102
+ if (opaqueBlock) {
103
+ if (opaqueBlock.braceDepth) {
104
+ opaqueBlock.braceDepth += countPlantUmlBraces(trimmedLine);
105
+ if (opaqueBlock.braceDepth <= 0) opaqueBlock = null;
106
+ } else if (opaqueBlock.end(trimmedLine)) {
107
+ opaqueBlock = null;
108
+ }
109
+ continue;
110
+ }
111
+
112
+ const nextOpaqueBlock = getPlantUmlOpaqueBlock(trimmedLine);
113
+ if (nextOpaqueBlock) {
114
+ opaqueBlock = nextOpaqueBlock.oneLine ? null : nextOpaqueBlock;
115
+ continue;
116
+ }
117
+ if (!trimmedLine) continue;
118
+
119
+ const closer = getPlantUmlCloser(trimmedLine);
120
+ const closesCurrentBlock = closer && stack.at(-1) === closer;
121
+ const isMiddle = PLANTUML_MIDDLE_PATTERN.test(trimmedLine) && stack.length > 0;
122
+ const opener = getPlantUmlOpener(trimmedLine);
123
+
124
+ if (stack.length > 0 || closesCurrentBlock || isMiddle || opener) {
125
+ const depth = Math.max(0, stack.length - (closesCurrentBlock || isMiddle ? 1 : 0));
126
+ parts[index] = `${' '.repeat(depth)}${content}`;
127
+ }
128
+ if (closesCurrentBlock) stack.pop();
129
+ if (opener) stack.push(opener);
130
+ }
131
+
132
+ return parts.join('');
133
+ }
134
+
135
+ export function canFormatDocument(filePath) {
136
+ return FORMATTABLE_FILE_KINDS.has(getVaultFileKind(filePath));
137
+ }
138
+
139
+ async function formatWithPrettier(source, parser) {
140
+ let pluginImport = import('prettier/plugins/markdown');
141
+ if (parser === 'yaml') pluginImport = import('prettier/plugins/yaml');
142
+ if (parser === 'html') pluginImport = import('prettier/plugins/html');
143
+
144
+ const [{ format }, plugin] = await Promise.all([
145
+ import('prettier/standalone'),
146
+ pluginImport,
147
+ ]);
148
+ const plugins = [plugin.default];
149
+
150
+ if (parser === 'mdx') {
151
+ const [babel, estree] = await Promise.all([
152
+ import('prettier/plugins/babel'),
153
+ import('prettier/plugins/estree'),
154
+ ]);
155
+ plugins.push(babel.default, estree.default);
156
+ }
157
+
158
+ return format(source, {
159
+ parser,
160
+ plugins,
161
+ proseWrap: 'preserve',
162
+ });
163
+ }
164
+
165
+ async function formatMermaid(source) {
166
+ const [{ default: mermaid }, { formatMermaid }] = await Promise.all([
167
+ import('mermaid'),
168
+ import('mermaid-formatter'),
169
+ ]);
170
+ if (!await mermaid.parse(source, { suppressErrors: true })) {
171
+ throw new Error('Mermaid syntax is invalid');
172
+ }
173
+
174
+ const formatted = formatMermaid(source, { indentSize: 2 });
175
+ if (!await mermaid.parse(formatted, { suppressErrors: true })) {
176
+ throw new Error('The formatter produced invalid Mermaid syntax');
177
+ }
178
+ return formatted;
179
+ }
180
+
181
+ export async function formatDocumentText(filePath, source) {
182
+ const kind = getVaultFileKind(filePath);
183
+
184
+ if (kind === 'mermaid') return formatMermaid(source);
185
+ if (kind === 'plantuml') return indentPlantUml(source);
186
+ if (kind === 'base') return formatWithPrettier(source, 'yaml');
187
+ if (kind === 'html') return formatWithPrettier(source, 'html');
188
+ if (kind === 'markdown') {
189
+ const parser = String(filePath).toLowerCase().endsWith('.mdx') ? 'mdx' : 'markdown';
190
+ return formatWithPrettier(source, parser);
191
+ }
192
+ return null;
193
+ }
@@ -0,0 +1,73 @@
1
+ import { createFileRouteHash, getHashParamsFromRaw } from './hash-routes.js';
2
+ import { normalizeVaultPathInput } from './vault-paths.js';
3
+
4
+ const MAX_ELEMENT_ID_LENGTH = 256;
5
+ const ELEMENT_ID_PATTERN = /^[A-Za-z0-9_-]+$/u;
6
+
7
+ function normalizeElementId(value) {
8
+ const normalized = String(value ?? '').trim();
9
+ return normalized.length <= MAX_ELEMENT_ID_LENGTH && ELEMENT_ID_PATTERN.test(normalized)
10
+ ? normalized
11
+ : '';
12
+ }
13
+
14
+ function normalizeUrlPath(value) {
15
+ const normalized = String(value ?? '').trim().replace(/\/+$/u, '');
16
+ return normalized || '/';
17
+ }
18
+
19
+ export function createExcalidrawElementLink(filePath, elementId, {
20
+ appUrl,
21
+ elementType = 'element',
22
+ } = {}) {
23
+ const normalizedFilePath = normalizeVaultPathInput(filePath);
24
+ const normalizedElementId = normalizeElementId(elementId);
25
+ if (!normalizedFilePath || !normalizedElementId || !appUrl) {
26
+ return '';
27
+ }
28
+
29
+ let url;
30
+ try {
31
+ url = new URL(appUrl);
32
+ } catch {
33
+ return '';
34
+ }
35
+
36
+ url.hash = createFileRouteHash(normalizedFilePath, {
37
+ elementId: normalizedElementId,
38
+ elementType,
39
+ });
40
+ return url.toString();
41
+ }
42
+
43
+ export function parseExcalidrawElementLink(link, {
44
+ appPath = '/',
45
+ origin = '',
46
+ } = {}) {
47
+ let url;
48
+ try {
49
+ url = new URL(String(link ?? ''), origin || 'http://collabmd.invalid');
50
+ } catch {
51
+ return null;
52
+ }
53
+
54
+ if (origin && url.origin !== origin) {
55
+ return null;
56
+ }
57
+ if (normalizeUrlPath(url.pathname) !== normalizeUrlPath(appPath)) {
58
+ return null;
59
+ }
60
+
61
+ const params = getHashParamsFromRaw(url.hash);
62
+ const filePath = normalizeVaultPathInput(params.get('file'));
63
+ const elementId = normalizeElementId(params.get('element'));
64
+ if (!filePath || !elementId) {
65
+ return null;
66
+ }
67
+
68
+ return {
69
+ elementId,
70
+ elementType: params.get('elementType') === 'group' ? 'group' : 'element',
71
+ filePath,
72
+ };
73
+ }
@@ -63,6 +63,27 @@ export function sceneToInitialData(parsedScene, { theme = 'dark' } = {}) {
63
63
  };
64
64
  }
65
65
 
66
+ export function createExcalidrawExportOptions(scene, {
67
+ padding = 24,
68
+ scale = 1,
69
+ } = {}) {
70
+ return {
71
+ appState: {
72
+ exportBackground: true,
73
+ exportScale: scale,
74
+ exportWithDarkMode: false,
75
+ gridSize: scene.appState?.gridSize ?? null,
76
+ theme: 'light',
77
+ viewBackgroundColor: scene.appState?.viewBackgroundColor ?? '#ffffff',
78
+ },
79
+ elements: Array.isArray(scene.elements)
80
+ ? scene.elements.filter((element) => element && !element.isDeleted)
81
+ : [],
82
+ exportPadding: padding,
83
+ files: scene.files || null,
84
+ };
85
+ }
86
+
66
87
  export function buildStoredScene(elements, appState, files) {
67
88
  return normalizeScene({
68
89
  elements: elements.filter((element) => !element.isDeleted),
@@ -0,0 +1,73 @@
1
+ import { stripVaultFileExtension } from '../../domain/file-kind.js';
2
+
3
+ function createRangeIndices(start, length) {
4
+ return Array.from({ length }, (_, index) => start + index);
5
+ }
6
+
7
+ function findFuzzyMatch(text, query) {
8
+ const indices = [];
9
+ let queryIndex = 0;
10
+ let score = 0;
11
+ let consecutiveBonus = 0;
12
+
13
+ for (let index = 0; index < text.length && queryIndex < query.length; index += 1) {
14
+ if (/\s/u.test(query[queryIndex]) && /[\s/\\_-]/u.test(text[index])) {
15
+ queryIndex += 1;
16
+ consecutiveBonus = 0;
17
+ continue;
18
+ }
19
+
20
+ if (text[index] !== query[queryIndex]) {
21
+ if (queryIndex > 0) score -= 0.25;
22
+ consecutiveBonus = 0;
23
+ continue;
24
+ }
25
+
26
+ queryIndex += 1;
27
+ indices.push(index);
28
+ consecutiveBonus += 1;
29
+ score += consecutiveBonus;
30
+
31
+ if (index === 0 || /[/\-_ ]/u.test(text[index - 1])) score += 5;
32
+ }
33
+
34
+ return queryIndex === query.length && score > 0 ? { indices, score } : null;
35
+ }
36
+
37
+ export function createFileSearchEntry(filePath) {
38
+ const displayName = stripVaultFileExtension(filePath);
39
+ const fileName = displayName.split('/').pop() || displayName;
40
+ const rawFileName = String(filePath ?? '').split('/').pop() || String(filePath ?? '');
41
+
42
+ return {
43
+ displayName,
44
+ fileName,
45
+ filePath,
46
+ lowerDisplayName: displayName.toLowerCase(),
47
+ lowerFileName: fileName.toLowerCase(),
48
+ lowerPath: String(filePath).toLowerCase(),
49
+ lowerRawFileName: rawFileName.toLowerCase(),
50
+ };
51
+ }
52
+
53
+ export function findFileSearchMatch(entry, query) {
54
+ const fileNameStart = entry.displayName.length - entry.fileName.length;
55
+ const searches = [
56
+ [entry.lowerFileName, fileNameStart, 100],
57
+ [entry.lowerDisplayName, 0, 50],
58
+ [entry.lowerRawFileName, fileNameStart, 40],
59
+ [entry.lowerPath, 0, 25],
60
+ ];
61
+
62
+ for (const [text, offset, baseScore] of searches) {
63
+ const index = text.indexOf(query);
64
+ if (index >= 0) {
65
+ return {
66
+ indices: createRangeIndices(index + offset, query.length),
67
+ score: baseScore + (1 / text.length),
68
+ };
69
+ }
70
+ }
71
+
72
+ return findFuzzyMatch(entry.lowerDisplayName, query);
73
+ }
@@ -0,0 +1,5 @@
1
+ export function commitButtonLabel(count) {
2
+ return count > 0
3
+ ? `Commit ${count} file${count === 1 ? '' : 's'}`
4
+ : 'Commit included files';
5
+ }
@@ -38,6 +38,8 @@ export function createFileRouteHash(filePath, {
38
38
  anchor = null,
39
39
  column = null,
40
40
  drawioMode = null,
41
+ elementId = null,
42
+ elementType = null,
41
43
  line = null,
42
44
  matchLength = null,
43
45
  } = {}) {
@@ -51,6 +53,12 @@ export function createFileRouteHash(filePath, {
51
53
  if (anchor) {
52
54
  params.set('anchor', String(anchor).trim());
53
55
  }
56
+ if (elementId) {
57
+ params.set('element', String(elementId).trim());
58
+ }
59
+ if (elementType === 'group') {
60
+ params.set('elementType', 'group');
61
+ }
54
62
  if (line != null) {
55
63
  params.set('line', String(Math.max(1, Math.round(Number(line) || 1))));
56
64
  }
@@ -47,11 +47,7 @@ export function generatePeerId() {
47
47
  }
48
48
 
49
49
  function generateUserId() {
50
- if (globalThis.crypto?.randomUUID) {
51
- return globalThis.crypto.randomUUID();
52
- }
53
-
54
- return `${generatePeerId()}-${Date.now().toString(36)}`;
50
+ return globalThis.crypto?.randomUUID?.() ?? `${generatePeerId()}-${Date.now().toString(36)}`;
55
51
  }
56
52
 
57
53
  // A stable peer ID for this browser tab, shared across lobby and per-file sessions.
@@ -60,6 +60,11 @@ function applyBasePath(basePath, pathValue) {
60
60
 
61
61
  export function getClientRuntimeConfig() {
62
62
  const rawConfig = {
63
+ agentAccess: {
64
+ enabled: false,
65
+ endpoint: '',
66
+ managed: false,
67
+ },
63
68
  auth: {
64
69
  enabled: false,
65
70
  implemented: true,
@@ -8,10 +8,12 @@ import {
8
8
  } from '../../domain/file-kind.js';
9
9
 
10
10
  export function normalizeVaultPathInput(value) {
11
- const segments = String(value ?? '')
12
- .trim()
13
- .replace(/\\/g, '/')
14
- .replace(/^\/+/u, '')
11
+ const normalized = String(value ?? '').trim().replace(/\\/g, '/');
12
+ if (!normalized || normalized.startsWith('/')) {
13
+ return '';
14
+ }
15
+
16
+ const segments = normalized
15
17
  .split('/')
16
18
  .map((segment) => segment.trim())
17
19
  .filter(Boolean);
@@ -1,3 +1,7 @@
1
+ import { createFileSearchEntry, findFileSearchMatch } from './file-search.js';
2
+
3
+ const MAX_VISIBLE_RESULTS = 30;
4
+
1
5
  /**
2
6
  * CodeMirror autocomplete source for [[wiki-links]].
3
7
  *
@@ -29,31 +33,28 @@ export function wikiLinkCompletions(getFileList) {
29
33
  return null;
30
34
  }
31
35
 
32
- const query = afterOpen.toLowerCase();
36
+ const query = afterOpen.trim().toLowerCase().replace(/\s+/gu, ' ');
33
37
  const from = line.from + openIndex + 2;
34
- const files = getFileList();
38
+ const entries = getFileList().map((filePath) => createFileSearchEntry(filePath));
39
+ const matches = query
40
+ ? entries
41
+ .map((entry) => ({ entry, match: findFileSearchMatch(entry, query) }))
42
+ .filter(({ match }) => match)
43
+ .sort((left, right) => right.match.score - left.match.score
44
+ || left.entry.lowerPath.localeCompare(right.entry.lowerPath))
45
+ : entries.map((entry) => ({ entry, match: null }));
35
46
 
36
- // Build completion options: show file paths without .md extension
37
- const options = files
38
- .map((filePath) => {
39
- const label = filePath.replace(/\.md$/i, '');
40
- // Match against full path and just the filename
41
- const fileName = label.split('/').pop();
42
- return { filePath, label, fileName };
43
- })
44
- .filter(({ label, fileName }) =>
45
- label.toLowerCase().includes(query) || fileName.toLowerCase().includes(query),
46
- )
47
- .map(({ label, fileName }) => ({
48
- label,
49
- // Show just the filename as detail when in a subdirectory
50
- detail: label.includes('/') ? ` ${fileName}` : undefined,
47
+ const options = matches
48
+ .slice(0, MAX_VISIBLE_RESULTS)
49
+ .map(({ entry }) => ({
50
+ label: entry.filePath,
51
+ displayLabel: entry.filePath.split('/').pop(),
52
+ detail: entry.displayName.slice(0, -entry.fileName.length - 1) || undefined,
51
53
  apply: (view, completion, from, to) => {
52
54
  // Replace from the query start to cursor, and also consume any trailing `]]`
53
- const docText = view.state.doc.toString();
54
55
  let end = to;
55
56
  // If there's already a `]]` right after cursor, consume it
56
- if (docText.slice(to, to + 2) === ']]') {
57
+ if (view.state.sliceDoc(to, to + 2) === ']]') {
57
58
  end = to + 2;
58
59
  }
59
60
  view.dispatch({
@@ -62,7 +63,6 @@ export function wikiLinkCompletions(getFileList) {
62
63
  });
63
64
  },
64
65
  type: 'text',
65
- boost: label.toLowerCase().startsWith(query) ? 1 : 0,
66
66
  }));
67
67
 
68
68
  if (options.length === 0) {
@@ -155,8 +155,13 @@ function teardownDrawioFrame() {
155
155
  }
156
156
 
157
157
  function buildDrawioFrameUrl() {
158
- const baseUrl = runtimeConfig.drawioBaseUrl || 'https://embed.diagrams.net';
159
- const url = new URL(baseUrl);
158
+ const fallbackUrl = 'https://embed.diagrams.net';
159
+ let url;
160
+ try {
161
+ url = new URL(runtimeConfig.drawioBaseUrl || fallbackUrl);
162
+ } catch {
163
+ url = new URL(fallbackUrl);
164
+ }
160
165
  url.searchParams.set('embed', '1');
161
166
  url.searchParams.set('proto', 'json');
162
167
  url.searchParams.set('spin', '1');
@@ -396,7 +401,7 @@ function handleLeaseState(nextState) {
396
401
  state.canClaim = Boolean(nextState?.canClaim);
397
402
 
398
403
  if (state.isEditor) {
399
- state.bannerText = 'Editing';
404
+ state.bannerText = 'Changes save automatically.';
400
405
  } else if (nextState?.hasHealthyHolder) {
401
406
  const holderName = nextState.holderName || 'Another user';
402
407
  state.bannerText = `${holderName} is editing this diagram. Read-only mode. Updates appear after they save.`;