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
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  isBaseFilePath,
3
+ isHtmlFilePath,
3
4
  isMarkdownFilePath,
4
5
  supportsBacklinksForFilePath,
5
6
  } from '../../domain/file-kind.js';
@@ -20,6 +21,7 @@ export class WorkspaceCoordinator {
20
21
  createEditorSession,
21
22
  getDisplayName,
22
23
  getFileList,
24
+ getVaultFileList = getFileList,
23
25
  getLineWrappingEnabled,
24
26
  getVimModeEnabled,
25
27
  getLocalUser,
@@ -51,6 +53,7 @@ export class WorkspaceCoordinator {
51
53
  onRenderBasePreview,
52
54
  onRenderExcalidrawPreview,
53
55
  onRenderDrawioPreview,
56
+ onRenderHtmlPreview,
54
57
  onRenderImagePreview,
55
58
  onRenderPdfPreview,
56
59
  onRenderStructurizrPreview,
@@ -72,6 +75,7 @@ export class WorkspaceCoordinator {
72
75
  this.createEditorSession = createEditorSession;
73
76
  this.getDisplayName = getDisplayName;
74
77
  this.getFileList = getFileList;
78
+ this.getVaultFileList = getVaultFileList;
75
79
  this.getLineWrappingEnabled = getLineWrappingEnabled;
76
80
  this.getVimModeEnabled = getVimModeEnabled ?? (() => false);
77
81
  this.getLocalUser = getLocalUser;
@@ -103,6 +107,7 @@ export class WorkspaceCoordinator {
103
107
  this.onRenderBasePreview = onRenderBasePreview;
104
108
  this.onRenderDrawioPreview = onRenderDrawioPreview;
105
109
  this.onRenderExcalidrawPreview = onRenderExcalidrawPreview;
110
+ this.onRenderHtmlPreview = onRenderHtmlPreview;
106
111
  this.onRenderImagePreview = onRenderImagePreview;
107
112
  this.onRenderPdfPreview = onRenderPdfPreview;
108
113
  this.onRenderStructurizrPreview = onRenderStructurizrPreview;
@@ -180,6 +185,7 @@ export class WorkspaceCoordinator {
180
185
  isDrawio = false,
181
186
  filePath,
182
187
  isExcalidraw = false,
188
+ isHtml = false,
183
189
  isImage = false,
184
190
  isPdf = false,
185
191
  supportsBacklinks,
@@ -187,6 +193,7 @@ export class WorkspaceCoordinator {
187
193
  if (isExcalidraw) this.onRenderExcalidrawPreview(filePath);
188
194
  if (isBase || isBaseFilePath(filePath)) this.onRenderBasePreview(filePath);
189
195
  if (isDrawio) this.onRenderDrawioPreview(filePath);
196
+ if (isHtml) this.onRenderHtmlPreview({ content: this.session?.getText?.() ?? '' });
190
197
  if (isImage) this.onRenderImagePreview(filePath);
191
198
  if (isPdf) this.onRenderPdfPreview(filePath);
192
199
  if (this.isStructurizrWorkspaceFile(filePath)) {
@@ -200,7 +207,14 @@ export class WorkspaceCoordinator {
200
207
 
201
208
  async openFile(filePath, { drawioMode = null } = {}) {
202
209
  if (!this.isTabActive()) {
203
- return;
210
+ return false;
211
+ }
212
+
213
+ if (!filePath || !this.getVaultFileList().includes(filePath)) {
214
+ this.cleanupSession();
215
+ this.stateStore.sessionLoadToken += 1;
216
+ this.onFileOpenError({ code: 'not-found', filePath });
217
+ return false;
204
218
  }
205
219
 
206
220
  const normalizedDrawioMode = drawioMode ?? null;
@@ -210,6 +224,7 @@ export class WorkspaceCoordinator {
210
224
  const isBase = this.isBaseFile(filePath);
211
225
  const isImage = this.isImageFile(filePath);
212
226
  const isPdf = this.isPdfFile(filePath);
227
+ const isHtml = isHtmlFilePath(filePath);
213
228
  const isMermaid = this.isMermaidFile(filePath);
214
229
  const isPlantUml = this.isPlantUmlFile(filePath);
215
230
  const isStructurizrWorkspace = this.isStructurizrWorkspaceFile(filePath);
@@ -221,7 +236,7 @@ export class WorkspaceCoordinator {
221
236
  ) {
222
237
  this.onUpdateActiveFile(filePath);
223
238
  this.onUpdateLobbyCurrentFile(filePath);
224
- return;
239
+ return true;
225
240
  }
226
241
 
227
242
  const loadToken = ++this.stateStore.sessionLoadToken;
@@ -252,7 +267,7 @@ export class WorkspaceCoordinator {
252
267
  session: null,
253
268
  supportsBacklinks: chromeState.supportsBacklinks,
254
269
  });
255
- return;
270
+ return true;
256
271
  }
257
272
 
258
273
  const EditorSession = await this.loadEditorSessionClass();
@@ -272,6 +287,7 @@ export class WorkspaceCoordinator {
272
287
 
273
288
  this.onContentChange({
274
289
  isBase,
290
+ isHtml,
275
291
  isMermaid,
276
292
  isPlantUml,
277
293
  isStructurizrWorkspace,
@@ -313,6 +329,7 @@ export class WorkspaceCoordinator {
313
329
  filePath,
314
330
  isBase,
315
331
  isExcalidraw,
332
+ isHtml,
316
333
  session,
317
334
  supportsBacklinks: chromeState.supportsBacklinks,
318
335
  });
@@ -426,6 +443,7 @@ export class WorkspaceCoordinator {
426
443
  session.ensureInitialContent?.();
427
444
  await readySession('post-initialize');
428
445
  }
446
+ return true;
429
447
  } catch (error) {
430
448
  console.error('[app] Failed to initialize editor:', error);
431
449
  session.destroy();
@@ -438,7 +456,8 @@ export class WorkspaceCoordinator {
438
456
  return;
439
457
  }
440
458
 
441
- this.onFileOpenError();
459
+ this.onFileOpenError({ code: 'load-failed', filePath });
460
+ return false;
442
461
  }
443
462
  }
444
463
  }
@@ -1,11 +1,40 @@
1
1
  import {
2
2
  isBaseFilePath,
3
3
  isDiagramFilePath,
4
+ isHtmlFilePath,
4
5
  isMarkdownFilePath,
5
6
  isStructurizrFilePath,
6
7
  } from '../../domain/file-kind.js';
8
+ import { canFormatDocument } from '../domain/document-formatter.js';
9
+ import { setDiagramActionButtonIcon } from '../domain/diagram-action-icons.js';
7
10
  import { resolveApiUrl } from '../domain/runtime-paths.js';
8
11
 
12
+ const HTML_PREVIEW_CSP = "default-src 'none'; base-uri about:; form-action 'none'; object-src 'none'; frame-src 'none'; worker-src 'none'; connect-src 'none'; style-src 'unsafe-inline'; img-src data: blob:; font-src data:; media-src data: blob:";
13
+
14
+ function createHtmlPreviewDocument(content, allowScripts = false) {
15
+ const scriptSource = allowScripts ? "'unsafe-inline'" : "'none'";
16
+ return `<meta http-equiv="Content-Security-Policy" content="${HTML_PREVIEW_CSP}; script-src ${scriptSource};"><base href="about:srcdoc">${String(content ?? '')}`;
17
+ }
18
+
19
+ function hasHtmlScripts(content) {
20
+ const preview = new DOMParser().parseFromString(content, 'text/html');
21
+ if (preview.scripts.length > 0) return true;
22
+ return [...preview.querySelectorAll('*')].some((element) => [...element.attributes].some(({ name, value }) => (
23
+ (name.startsWith('on') && name in element)
24
+ || ((name === 'href' || name === 'xlink:href') && /^\s*javascript:/iu.test(value))
25
+ )));
26
+ }
27
+
28
+ function syncFormatDocumentButton(button, filePath, isPlantUml) {
29
+ if (!button) return;
30
+ const actionLabel = isPlantUml ? 'Indent PlantUML document' : 'Format document';
31
+ button.classList.toggle('hidden', !canFormatDocument(filePath));
32
+ button.setAttribute('aria-label', actionLabel);
33
+ button.setAttribute('title', actionLabel);
34
+ const label = button.querySelector('.ui-action-label');
35
+ if (label) label.textContent = isPlantUml ? 'Indent' : 'Format';
36
+ }
37
+
9
38
  export class WorkspacePreviewController {
10
39
  constructor({
11
40
  backlinksPanel,
@@ -43,6 +72,14 @@ export class WorkspacePreviewController {
43
72
  updateTheme() {},
44
73
  };
45
74
  this.elements = elements;
75
+ this.htmlPreviewShell = null;
76
+ if (this.elements.htmlPreviewMaximizeButton) {
77
+ this.elements.htmlPreviewMaximizeButton.addEventListener('click', () => {
78
+ const isMaximized = this.htmlPreviewShell?.classList.contains('is-maximized');
79
+ this.setHtmlPreviewMaximized(!isMaximized);
80
+ });
81
+ setDiagramActionButtonIcon(this.elements.htmlPreviewMaximizeButton, 'maximize');
82
+ }
46
83
  this.excalidrawEmbed = excalidrawEmbed;
47
84
  this.getDisplayName = getDisplayName;
48
85
  this.getSession = getSession;
@@ -91,13 +128,29 @@ export class WorkspacePreviewController {
91
128
  return source;
92
129
  }
93
130
 
131
+ setHtmlPreviewMaximized(maximized) {
132
+ const isMaximized = Boolean(maximized && this.htmlPreviewShell);
133
+ this.htmlPreviewShell?.classList.toggle('is-maximized', isMaximized);
134
+ globalThis.document?.body?.classList.toggle('html-preview-maximized-open', isMaximized);
135
+
136
+ const button = this.elements.htmlPreviewMaximizeButton;
137
+ if (button) {
138
+ setDiagramActionButtonIcon(button, isMaximized ? 'restore' : 'maximize');
139
+ button.title = isMaximized ? 'Restore HTML preview' : 'Maximize HTML preview';
140
+ button.setAttribute('aria-label', button.title);
141
+ }
142
+ }
143
+
94
144
  resetPreviewMode() {
145
+ this.setHtmlPreviewMaximized(false);
146
+ this.htmlPreviewShell = null;
95
147
  this.pdfPreview.cancel();
96
148
  this.elements.previewContent?.classList.remove('is-drawio-file-preview');
97
149
  this.elements.previewContent?.classList.remove('is-excalidraw-file-preview');
98
150
  this.elements.previewContent?.classList.remove('is-base-file-preview');
99
151
  this.elements.previewContent?.classList.remove('is-image-file-preview');
100
152
  this.elements.previewContent?.classList.remove('is-pdf-file-preview');
153
+ this.elements.previewContent?.classList.remove('is-html-file-preview');
101
154
  this.elements.previewContent?.classList.remove('is-mermaid-file-preview');
102
155
  this.elements.previewContent?.classList.remove('is-plantuml-file-preview');
103
156
  this.elements.previewContent?.classList.remove('is-structurizr-file-preview');
@@ -110,6 +163,7 @@ export class WorkspacePreviewController {
110
163
  const isBase = this.isBaseFile(filePath);
111
164
  const isImage = this.isImageFile(filePath);
112
165
  const isPdf = this.isPdfFile(filePath);
166
+ const isHtml = isHtmlFilePath(filePath);
113
167
  const isMarkdown = isMarkdownFilePath(filePath);
114
168
  const isMermaid = this.isMermaidFile(filePath);
115
169
  const isPlantUml = this.isPlantUmlFile(filePath);
@@ -120,9 +174,11 @@ export class WorkspacePreviewController {
120
174
  this.backlinksPanel.setDisplayMode?.(usesHeaderBacklinks ? 'header' : 'dock');
121
175
 
122
176
  this.elements.editorFindButton?.classList.toggle('hidden', !isMarkdown);
177
+ syncFormatDocumentButton(this.elements.editorFormatButton, filePath, isPlantUml);
123
178
  this.elements.markdownToolbar?.classList.toggle('hidden', !isMarkdown);
124
179
  this.elements.exportMenuGroup?.classList.toggle('hidden', !isMarkdown);
125
- this.elements.outlineToggle?.classList.toggle('hidden', isDiagramFile || isImage || isPdf || isBase);
180
+ this.elements.htmlPreviewMaximizeButton?.classList.toggle('hidden', !isHtml);
181
+ this.elements.outlineToggle?.classList.toggle('hidden', isDiagramFile || isImage || isPdf || isHtml || isBase);
126
182
  this.elements.previewContent?.classList.toggle('is-mermaid-file-preview', isMermaid);
127
183
  this.elements.previewContent?.classList.toggle('is-plantuml-file-preview', isPlantUml);
128
184
  this.elements.previewContent?.classList.toggle('is-structurizr-file-preview', isStructurizr);
@@ -132,7 +188,7 @@ export class WorkspacePreviewController {
132
188
  this.backlinksPanel.clear();
133
189
  }
134
190
 
135
- if ((isDrawio && drawioMode !== 'text') || isExcalidraw || isImage || isPdf || (isBase && preferPreviewForBase)) {
191
+ if ((isDrawio && drawioMode !== 'text') || isExcalidraw || isHtml || isImage || isPdf || (isBase && preferPreviewForBase)) {
136
192
  this.layoutController.setView('preview', { persist: false });
137
193
  this.outlineController.close();
138
194
  this.backlinksPanel.clear();
@@ -292,6 +348,68 @@ export class WorkspacePreviewController {
292
348
  this.schedulePreviewLayoutSyncCallback({ delayMs: 0 });
293
349
  }
294
350
 
351
+ renderHtmlFilePreview({ content = '' } = {}) {
352
+ const previewElement = this.elements.previewContent;
353
+ if (!previewElement) {
354
+ return;
355
+ }
356
+
357
+ const wasMaximized = this.htmlPreviewShell?.classList.contains('is-maximized') ?? false;
358
+ this.videoEmbed?.detachForCommit();
359
+ this.drawioEmbed.detachForCommit();
360
+ this.excalidrawEmbed.detachForCommit();
361
+ this.resetPreviewMode();
362
+ previewElement.classList.add('is-html-file-preview');
363
+ const renderHost = this.previewRenderer.ensureRenderHost();
364
+ this.previewRenderer.normalizePreviewChildren(renderHost);
365
+
366
+ const source = String(content ?? '');
367
+ const iframe = document.createElement('iframe');
368
+ iframe.className = 'html-file-preview-frame';
369
+ iframe.title = 'HTML preview';
370
+ iframe.referrerPolicy = 'no-referrer';
371
+ iframe.setAttribute('allow', "camera 'none'; microphone 'none'; geolocation 'none'; clipboard-read 'none'; clipboard-write 'none'");
372
+ iframe.setAttribute('sandbox', '');
373
+ // ponytail: full iframe replacement resets script consent whenever the content changes.
374
+ iframe.srcdoc = createHtmlPreviewDocument(source);
375
+
376
+ const shell = document.createElement('div');
377
+ shell.className = 'html-file-preview-shell';
378
+
379
+ if (hasHtmlScripts(source)) {
380
+ const scriptGate = document.createElement('div');
381
+ scriptGate.className = 'html-file-preview-script-gate';
382
+ scriptGate.textContent = 'Scripts are disabled by default. Run them only if you trust this HTML file.';
383
+
384
+ const runScriptsButton = document.createElement('button');
385
+ runScriptsButton.type = 'button';
386
+ runScriptsButton.className = 'ui-button ui-button--secondary ui-button--compact';
387
+ runScriptsButton.textContent = 'Run scripts';
388
+ runScriptsButton.addEventListener('click', () => {
389
+ iframe.setAttribute('sandbox', 'allow-scripts');
390
+ iframe.srcdoc = createHtmlPreviewDocument(source, true);
391
+ scriptGate.remove();
392
+ });
393
+ scriptGate.append(runScriptsButton);
394
+ shell.append(scriptGate);
395
+ }
396
+ shell.append(iframe);
397
+ this.htmlPreviewShell = shell;
398
+ this.setHtmlPreviewMaximized(wasMaximized);
399
+
400
+ if (renderHost) {
401
+ renderHost.replaceChildren(shell);
402
+ renderHost.style.minHeight = '';
403
+ }
404
+
405
+ previewElement.dataset.renderPhase = 'ready';
406
+ this.outlineController.close();
407
+ this.backlinksPanel.clear();
408
+ this.scrollSyncController.setLargeDocumentMode(false);
409
+ this.scrollSyncController.invalidatePreviewBlocks();
410
+ this.schedulePreviewLayoutSyncCallback({ delayMs: 0 });
411
+ }
412
+
295
413
  async renderBaseFilePreview(filePath, { source = null } = {}) {
296
414
  const previewElement = this.elements.previewContent;
297
415
  if (!previewElement) {
@@ -143,6 +143,13 @@ export class WorkspaceRouteController {
143
143
  return;
144
144
  }
145
145
  this.revealEditorMatch(route);
146
+ if (route.elementId) {
147
+ this.excalidrawEmbed?.openElement(
148
+ route.filePath,
149
+ route.elementId,
150
+ route.elementType,
151
+ );
152
+ }
146
153
  this.requestPreviewRouteAnchor?.(route.anchor ?? null, route.filePath);
147
154
  }
148
155
 
@@ -285,8 +292,11 @@ export class WorkspaceRouteController {
285
292
  this.fileHistoryView?.hide?.();
286
293
  this.clearStaticPreviewDocument?.();
287
294
  this.syncMainChrome({ mode: 'editor' });
288
- await this.workspaceCoordinator.openFile(filePath, options);
295
+ const didOpen = await this.workspaceCoordinator.openFile(filePath, options);
289
296
  this.setSession(this.workspaceCoordinator.getSession());
297
+ if (didOpen === false) {
298
+ return false;
299
+ }
290
300
 
291
301
  if (shouldRevealInTree) {
292
302
  this.revealFileInTree(filePath, { clearSearch: true });
@@ -0,0 +1,93 @@
1
+ Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
2
+
3
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
4
+ This license is copied below, and is also available with a FAQ at:
5
+ https://scripts.sil.org/OFL
6
+
7
+
8
+ -----------------------------------------------------------
9
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10
+ -----------------------------------------------------------
11
+
12
+ PREAMBLE
13
+ The goals of the Open Font License (OFL) are to stimulate worldwide
14
+ development of collaborative font projects, to support the font creation
15
+ efforts of academic and linguistic communities, and to provide a free and
16
+ open framework in which fonts may be shared and improved in partnership
17
+ with others.
18
+
19
+ The OFL allows the licensed fonts to be used, studied, modified and
20
+ redistributed freely as long as they are not sold by themselves. The
21
+ fonts, including any derivative works, can be bundled, embedded,
22
+ redistributed and/or sold with any software provided that any reserved
23
+ names are not used by derivative works. The fonts and derivatives,
24
+ however, cannot be released under any other type of license. The
25
+ requirement for fonts to remain under this license does not apply
26
+ to any document created using the fonts or their derivatives.
27
+
28
+ DEFINITIONS
29
+ "Font Software" refers to the set of files released by the Copyright
30
+ Holder(s) under this license and clearly marked as such. This may
31
+ include source files, build scripts and documentation.
32
+
33
+ "Reserved Font Name" refers to any names specified as such after the
34
+ copyright statement(s).
35
+
36
+ "Original Version" refers to the collection of Font Software components as
37
+ distributed by the Copyright Holder(s).
38
+
39
+ "Modified Version" refers to any derivative made by adding to, deleting,
40
+ or substituting -- in part or in whole -- any of the components of the
41
+ Original Version, by changing formats or by porting the Font Software to a
42
+ new environment.
43
+
44
+ "Author" refers to any designer, engineer, programmer, technical
45
+ writer or other person who contributed to the Font Software.
46
+
47
+ PERMISSION & CONDITIONS
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
50
+ redistribute, and sell modified and unmodified copies of the Font
51
+ Software, subject to the following conditions:
52
+
53
+ 1) Neither the Font Software nor any of its individual components,
54
+ in Original or Modified Versions, may be sold by itself.
55
+
56
+ 2) Original or Modified Versions of the Font Software may be bundled,
57
+ redistributed and/or sold with any software, provided that each copy
58
+ contains the above copyright notice and this license. These can be
59
+ included either as stand-alone text files, human-readable headers or
60
+ in the appropriate machine-readable metadata fields within text or
61
+ binary files as long as those fields can be easily viewed by the user.
62
+
63
+ 3) No Modified Version of the Font Software may use the Reserved Font
64
+ Name(s) unless explicit written permission is granted by the corresponding
65
+ Copyright Holder. This restriction only applies to the primary font name as
66
+ presented to the users.
67
+
68
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69
+ Software shall not be used to promote, endorse or advertise any
70
+ Modified Version, except to acknowledge the contribution(s) of the
71
+ Copyright Holder(s) and the Author(s) or with their explicit written
72
+ permission.
73
+
74
+ 5) The Font Software, modified or unmodified, in part or in whole,
75
+ must be distributed entirely under this license, and must not be
76
+ distributed under any other license. The requirement for fonts to
77
+ remain under this license does not apply to any document created
78
+ using the Font Software.
79
+
80
+ TERMINATION
81
+ This license becomes null and void if any of the above conditions are
82
+ not met.
83
+
84
+ DISCLAIMER
85
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93
+ OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -1,5 +1,6 @@
1
1
  import { PdfPreviewController } from '../application/pdf-preview-controller.js';
2
2
  import { PreviewRenderer } from '../application/preview-renderer.js';
3
+ import { renderWebMcpDiagram } from '../application/webmcp-diagram-renderer.js';
3
4
  import { ensureQuickSwitcherInstance, toggleQuickSwitcherInstance } from '../application/quick-switcher-loader.js';
4
5
  import { WorkspaceRouteController } from '../application/workspace-route-controller.js';
5
6
  import { WikiLinkFileController } from '../application/wiki-link-file-controller.js';
@@ -18,6 +19,7 @@ import { uiFeatureSidebarMethods } from '../application/app-shell/ui-feature-sid
18
19
  import { uiFeatureTabActivityMethods } from '../application/app-shell/ui-feature-tab-activity.js';
19
20
  import { uiFeatureToolbarMethods } from '../application/app-shell/ui-feature-toolbar.js';
20
21
  import { workspaceFeature } from '../application/app-shell/workspace-feature.js';
22
+ import { agentConnectionApiClient } from '../infrastructure/agent-connection-api-client.js';
21
23
  import { LOBBY_CHAT_MESSAGE_MAX_LENGTH, LobbyPresence } from '../infrastructure/lobby-presence.js';
22
24
  import { BrowserPreferencesPort } from '../infrastructure/browser-preferences-port.js';
23
25
  import { BrowserNotificationPort } from '../infrastructure/browser-notification-port.js';
@@ -35,7 +37,9 @@ import {
35
37
  } from '../infrastructure/runtime-config.js';
36
38
  import { TabActivityLock } from '../infrastructure/tab-activity-lock.js';
37
39
  import { vaultApiClient } from '../infrastructure/vault-api-client.js';
40
+ import { WebMcpToolRegistry } from '../infrastructure/webmcp-tool-registry.js';
38
41
  import { WorkspaceSyncClient } from '../infrastructure/workspace-sync-client.js';
42
+ import { AgentConnectionController } from '../presentation/agent-connection-controller.js';
39
43
  import { BacklinksPanel } from '../presentation/backlinks-panel.js';
40
44
  import { CommentOverviewController } from '../presentation/comment-overview-controller.js';
41
45
  import { CommentUiController } from '../presentation/comment-ui-controller.js';
@@ -166,8 +170,69 @@ export class CollabMdAppShell {
166
170
 
167
171
  this.toastController = new ToastController(this.elements.toastContainer);
168
172
  this.chatToastController = new ToastController(this.elements.chatToastContainer);
173
+ this.agentConnectionController = new AgentConnectionController({
174
+ apiClient: agentConnectionApiClient,
175
+ closeToolbarMenu: () => this.closeToolbarOverflowMenu(),
176
+ content: this.elements.agentConnectionContent,
177
+ dialog: this.elements.agentConnectionDialog,
178
+ runtimeConfig: this.runtimeConfig,
179
+ toastController: this.toastController,
180
+ trigger: this.elements.connectAgentButton,
181
+ });
182
+ const callAgentTool = (...args) => this.vaultApiClient.callAgentTool(...args);
183
+ this.webMcpTools = new WebMcpToolRegistry({
184
+ acknowledgeToolCall: ({ input, name, preparation, result, signal }) => {
185
+ if (
186
+ name !== 'edit_excalidraw'
187
+ || input.path !== this.currentFilePath
188
+ ) {
189
+ return null;
190
+ }
191
+ return this.excalidrawEmbed?.waitForAgentPaint(input.path, result.revision, {
192
+ afterRevision: preparation?.revision,
193
+ signal,
194
+ });
195
+ },
196
+ callTool: (name, input, options) => name === 'render_diagram'
197
+ ? renderWebMcpDiagram(input, {
198
+ callTool: callAgentTool,
199
+ getMermaid: () => this.previewRenderer.mermaidHydrator.ensureMermaid(),
200
+ signal: options?.signal,
201
+ })
202
+ : callAgentTool(name, input, options),
203
+ getActiveContext: () => ({
204
+ activeDiagramPath: this.isExcalidrawFile(this.currentFilePath)
205
+ ? this.currentFilePath
206
+ : null,
207
+ activePath: this.currentFilePath,
208
+ }),
209
+ getIsTabActive: () => this.isTabActive,
210
+ onDidMutate: () => {
211
+ this.toastController.show('Agent-assisted Vault change applied. Review it before committing.');
212
+ },
213
+ prepareToolCall: async ({ input, name, signal }) => {
214
+ if (
215
+ ![
216
+ 'edit_excalidraw',
217
+ 'inspect_excalidraw',
218
+ 'read_document',
219
+ 'render_excalidraw',
220
+ 'verify_excalidraw',
221
+ ].includes(name)
222
+ || input.path !== this.currentFilePath
223
+ ) {
224
+ return null;
225
+ }
226
+ const preparation = await this.excalidrawEmbed?.flushPendingAgentWrites(input.path, { signal });
227
+ if (['timeout', 'unavailable'].includes(preparation?.status)) {
228
+ throw new Error('The active Excalidraw editor did not confirm its latest collaboration update');
229
+ }
230
+ return preparation;
231
+ },
232
+ });
169
233
  this.fileExplorer = new FileExplorerController({
170
234
  mobileBreakpointQuery: this.mobileBreakpointQuery,
235
+ onDirectoryExport: (directoryPath, format) => this.handleDirectoryExportRequest(directoryPath, format),
171
236
  onFileDelete: () => this.navigation.navigateToFile(null),
172
237
  onFileSelect: (filePath) => this.workspaceRouteController.handleFileSelection(filePath, {
173
238
  closeSidebarOnMobile: true,
@@ -200,7 +265,9 @@ export class CollabMdAppShell {
200
265
  onResetFile: (filePath, { scope }) => this.openGitResetDialog(filePath, { scope }),
201
266
  onSelectCommit: (hash, { path }) => this.handleGitCommitSelection(hash, { closeSidebarOnMobile: true, path }),
202
267
  onSelectDiff: (filePath, { scope }) => this.handleGitDiffSelection(filePath, { closeSidebarOnMobile: true, scope }),
268
+ onStageAll: () => this.stageAllGitFiles(),
203
269
  onStageFile: (filePath, { scope }) => this.stageGitFile(filePath, { scope }),
270
+ onUnstageAll: () => this.unstageAllGitFiles(),
204
271
  onUnstageFile: (filePath, { scope }) => this.unstageGitFile(filePath, { scope }),
205
272
  onViewAllDiff: () => this.handleGitDiffSelection(null, { closeSidebarOnMobile: true, scope: 'all' }),
206
273
  searchInput: this.elements.gitSearchInput,
@@ -208,7 +275,11 @@ export class CollabMdAppShell {
208
275
  });
209
276
  this.outlineController = new OutlineController({
210
277
  mobileBreakpointQuery: this.mobileBreakpointQuery,
211
- onNavigateToHeading: ({ sourceLine }) => {
278
+ onNavigateToHeading: ({ headingId, sourceLine }) => {
279
+ const heading = document.getElementById(headingId);
280
+ if (this.elements.previewContent?.contains(heading)) {
281
+ this.unfoldPreviewHeading(heading);
282
+ }
212
283
  if (!Number.isFinite(sourceLine)) return;
213
284
  this.scrollSyncController.suspendSync(250);
214
285
  this.session?.scrollToLine(sourceLine, 0);
@@ -254,6 +325,7 @@ export class CollabMdAppShell {
254
325
  this.excalidrawEmbed.reconcileEmbeds(this.elements.previewContent, { isLargeDocument: stats.isLargeDocument });
255
326
  this.scrollSyncController.setLargeDocumentMode(stats.isLargeDocument);
256
327
  this.syncPreviewCodeCopyButtons();
328
+ this.syncPreviewHeadingFoldButtons();
257
329
  this.syncPreviewHeadingLinkButtons();
258
330
  this.applyPendingPreviewRouteAnchor({ behavior: 'auto', clearMissing: true });
259
331
  this.schedulePreviewLayoutSync({ delayMs: 0 });
@@ -301,6 +373,7 @@ export class CollabMdAppShell {
301
373
  headerPanelElement: this.elements.backlinksHeaderPanel,
302
374
  inlinePanelElement: this.elements.backlinksInlinePanel,
303
375
  loadBacklinks: (filePath, options = {}) => this.vaultApiClient.readBacklinks(filePath, options),
376
+ onBeforeToggle: () => this.scrollSyncController.suspendSync(250),
304
377
  onFileSelect: (filePath) => this.workspaceRouteController.handleFileSelection(filePath, {
305
378
  closeSidebarOnMobile: true,
306
379
  }),
@@ -309,6 +382,11 @@ export class CollabMdAppShell {
309
382
  this.excalidrawEmbed = new ExcalidrawEmbedController({
310
383
  getLocalUser: () => this.lobby.getLocalUser(),
311
384
  getTheme: () => this.themeController.getTheme(),
385
+ onOpenElement: ({ elementId, elementType, filePath } = {}) => {
386
+ if (filePath && elementId) {
387
+ this.navigation.navigateToFile(filePath, { elementId, elementType });
388
+ }
389
+ },
312
390
  onOpenFile: (filePath) => filePath && this.navigation.navigateToFile(filePath),
313
391
  onStopFollowing: () => this.stopFollowingUser(),
314
392
  onToggleQuickSwitcher: () => {
@@ -467,6 +545,7 @@ export class CollabMdAppShell {
467
545
  }),
468
546
  getDisplayName: (filePath) => this.getDisplayName(filePath),
469
547
  getFileList: () => this.fileExplorer.flatDocumentFiles,
548
+ getVaultFileList: () => this.fileExplorer.flatFiles,
470
549
  getLineWrappingEnabled: () => this.getStoredLineWrapping(),
471
550
  getVimModeEnabled: () => this.getStoredVimMode(),
472
551
  getLocalUser: () => this.lobby.getLocalUser(),
@@ -500,8 +579,16 @@ export class CollabMdAppShell {
500
579
  this.clearInitialFileBootstrap();
501
580
  },
502
581
  onConnectionChange: (state) => this.handleConnectionChange(state),
503
- onContentChange: ({ isBase, isMermaid, isPlantUml, isStructurizrWorkspace }) => {
582
+ onContentChange: ({ isBase, isHtml, isMermaid, isPlantUml, isStructurizrWorkspace }) => {
583
+ void this.webMcpTools.refresh();
504
584
  this.handleCommentEditorContentChange();
585
+ if (isHtml) {
586
+ this.workspacePreviewController.renderHtmlFilePreview({
587
+ content: this.session?.getText?.() ?? '',
588
+ });
589
+ return;
590
+ }
591
+
505
592
  if (isBase) {
506
593
  this.scheduleBaseFilePreview(this.currentFilePath, {
507
594
  source: this.session?.getText?.() ?? '',
@@ -524,10 +611,11 @@ export class CollabMdAppShell {
524
611
  },
525
612
  onCommentsChange: (threads) => this.handleCommentThreadsChange(threads),
526
613
  onFileAwarenessChange: (users) => this.updateFileAwareness(users),
527
- onFileOpenError: () => {
528
- this.showEditorLoadError();
614
+ onFileOpenError: ({ code } = {}) => {
615
+ const notFound = code === 'not-found';
616
+ this.showEditorLoadError(notFound ? 'File not found' : 'Failed to load file');
529
617
  this.syncWrapToggle();
530
- this.toastController.show('Failed to initialize editor');
618
+ this.toastController.show(notFound ? 'File not found' : 'Failed to initialize editor');
531
619
  },
532
620
  onFileOpenReady: () => {
533
621
  this.hideEditorLoading();
@@ -545,6 +633,7 @@ export class CollabMdAppShell {
545
633
  onRenderDrawioPreview: (filePath) => this.workspacePreviewController.renderDrawioFilePreview(filePath),
546
634
  onRenderBasePreview: (filePath) => this.renderBaseFilePreview(filePath),
547
635
  onRenderExcalidrawPreview: (filePath) => this.workspacePreviewController.renderExcalidrawFilePreview(filePath),
636
+ onRenderHtmlPreview: (options) => this.workspacePreviewController.renderHtmlFilePreview(options),
548
637
  onRenderImagePreview: (filePath) => this.workspacePreviewController.renderImageFilePreview(filePath),
549
638
  onRenderPdfPreview: (filePath) => this.workspacePreviewController.renderPdfFilePreview(filePath),
550
639
  onRenderStructurizrPreview: (filePath, options) => this.workspacePreviewController.renderStructurizrFilePreview(filePath, options),
@@ -561,6 +650,7 @@ export class CollabMdAppShell {
561
650
  });
562
651
  this.syncCommentChrome(filePath);
563
652
  this.syncFileHistoryButton({ filePath, mode: 'editor' });
653
+ this.syncReviewFileChangesButton({ filePath, mode: 'editor' });
564
654
  if (this.elements.activeFileName) {
565
655
  this.elements.activeFileName.textContent = displayName;
566
656
  }
@@ -626,7 +716,10 @@ export class CollabMdAppShell {
626
716
  }
627
717
 
628
718
  get session() { return this._session; }
629
- set session(value) { this._session = value; }
719
+ set session(value) {
720
+ this._session = value;
721
+ void this.webMcpTools?.refresh();
722
+ }
630
723
 
631
724
  publishFileOpenPerf() {
632
725
  if (typeof window === 'undefined') {