collabmd 0.1.44 → 0.1.46

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 (291) hide show
  1. package/README.md +39 -19
  2. package/bin/collabmd.js +27 -1
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CYM5nxUi.js +1 -0
  4. package/dist/client/assets/browser-utils--H_DkyEF.js +1 -0
  5. package/dist/client/assets/chunk-ERSWUTIN-hHdvnhaY.js +41 -0
  6. package/dist/client/assets/{chunk-CZQZEIFA-DT3N9fo7.js → chunk-YGJVY4SA-CjSe7Bx7.js} +2 -2
  7. package/dist/client/assets/comment-thread-store-CdcwrObc.js +1 -0
  8. package/dist/client/assets/comment-threads-9J6Em-_y.js +4 -0
  9. package/dist/client/assets/comment-ui-shared-BC4pt4w8.js +7 -0
  10. package/dist/client/assets/dist-B5HTH2BO.js +1 -0
  11. package/dist/client/assets/{dist-DhLvC8DS.js → dist-B5Jf1SLZ.js} +2 -2
  12. package/dist/client/assets/{dist-CnL7Y2sM.js → dist-BDt3rz7l.js} +1 -1
  13. package/dist/client/assets/dist-BEwK4csK.js +1 -0
  14. package/dist/client/assets/dist-BKW4PALF.js +1 -0
  15. package/dist/client/assets/dist-BWcHHOx-.js +1 -0
  16. package/dist/client/assets/{dist-CYZmbokb.js → dist-BalScOwZ.js} +9 -9
  17. package/dist/client/assets/dist-Bf8f4HmM.js +6 -0
  18. package/dist/client/assets/dist-BjHJDtyU.js +1 -0
  19. package/dist/client/assets/dist-Bm6pf9Bl.js +1 -0
  20. package/dist/client/assets/dist-BoVBdSjk.js +1 -0
  21. package/dist/client/assets/dist-CC5IrQMG.js +1 -0
  22. package/dist/client/assets/{dist-C11hHqv_.js → dist-CCP_AKPG.js} +12 -12
  23. package/dist/client/assets/dist-CZgOmxK6.js +1 -0
  24. package/dist/client/assets/{dist-D2AQ-76g.js → dist-Cqhv5LAk.js} +1 -1
  25. package/dist/client/assets/{dist-MvcV4190.js → dist-D-Z6FLem.js} +1 -1
  26. package/dist/client/assets/dist-DLMiIsNC.js +11 -0
  27. package/dist/client/assets/{dist-3bgCp7iY.js → dist-DZKu9Cs8.js} +1 -1
  28. package/dist/client/assets/dist-DaYdhcVs.js +1 -0
  29. package/dist/client/assets/dist-FWJsgGYI.js +1 -0
  30. package/dist/client/assets/dist-Kh2COra_.js +1 -0
  31. package/dist/client/assets/{dist-JYEDRrPT.js → dist-PDZ3bSqm.js} +1 -1
  32. package/dist/client/assets/{dist-Drp8uu5J.js → dist-TjMh8n1u.js} +1 -1
  33. package/dist/client/assets/{dist-DGb27Dl6.js → dist-dtAdgL39.js} +1 -1
  34. package/dist/client/assets/dist-jv4WdPnK.js +9 -0
  35. package/dist/client/assets/{dist-DK5Gs2wa.js → dist-rGBmqxC7.js} +1 -1
  36. package/dist/client/assets/{dist-DCzuX1AF.js → dist-shrl6K_0.js} +1 -1
  37. package/dist/client/assets/dist-tOaegDYS2.js +1 -0
  38. package/dist/client/assets/dist-ule2n6ak.js +1 -0
  39. package/dist/client/assets/dist-xElaxbia.js +1 -0
  40. package/dist/client/assets/drawio-editor-FzY1cVw8.js +9 -0
  41. package/dist/client/assets/drawioEditor-BjiKJqlc.js +2 -0
  42. package/dist/client/assets/editor-session-Cm9ekeNo.js +54 -0
  43. package/dist/client/assets/embedded-editor-base-CwTkk911.css +1 -0
  44. package/dist/client/assets/{en-GADW4C6J-DQ6zyCEM.js → en-7NFCYGKX-BrgYZAEe.js} +1 -1
  45. package/dist/client/assets/{preview-render-profile-BZzGSg6K.js → es-DXGV3RHd.js} +13 -13
  46. package/dist/client/assets/excalidraw-editor-B46zsTFI.js +9 -0
  47. package/dist/client/assets/excalidraw-editor-Bt7gMSoh.css +1 -0
  48. package/dist/client/assets/excalidraw-scene-BOben2gr.js +1 -0
  49. package/dist/client/assets/excalidrawEditor-CT2pHq7e.js +2 -0
  50. package/dist/client/assets/export-page-A7NHawJY.js +39 -0
  51. package/dist/client/assets/exportDocument-B2L8fe34.css +1 -0
  52. package/dist/client/assets/exportDocument-BaqcOAAW.js +2 -0
  53. package/dist/client/assets/file-icon-svg-CQAjlWjK.js +1 -0
  54. package/dist/client/assets/file-kind-BbqgGzpc.js +1 -0
  55. package/dist/client/assets/image-QXRYHUNP-SWEV8H0J.js +1 -0
  56. package/dist/client/assets/index-ClbjMBVt.js +2 -0
  57. package/dist/client/assets/index-Pum8ET-5.css +1 -0
  58. package/dist/client/assets/main-B3uPyqic.js +893 -0
  59. package/dist/client/assets/modulepreload-polyfill-P2Xu9kJm.js +1 -0
  60. package/dist/client/assets/pdf-BL9Pr2D5.js +54 -0
  61. package/dist/client/assets/pdf.worker-CLesOks4.mjs +64857 -0
  62. package/dist/client/assets/pdf_viewer-FVkkThnz.js +551 -0
  63. package/dist/client/assets/preview-diagram-utils-txBCoW8d.js +1 -0
  64. package/dist/client/assets/{preview-render-compiler-BSaQO_p3.js → preview-render-compiler-BD-XhkS2.js} +2 -2
  65. package/dist/client/assets/preview-render-compiler-BKedaMxx.js +1 -0
  66. package/dist/client/assets/preview-render-profile-CE-5rVTC.js +1 -0
  67. package/dist/client/assets/{preview-render-worker-B42LWvrD.js → preview-render-worker-CiPqc9n6.js} +20 -20
  68. package/dist/client/assets/prod-Dy20X7eT.js +1 -0
  69. package/dist/client/assets/prod-hnwh7wRM.js +177 -0
  70. package/dist/client/assets/quick-switcher-controller-fqOYR7qR.js +12 -0
  71. package/dist/client/assets/runtime-config-BLrEKVO1.js +1 -0
  72. package/dist/client/assets/vault-api-client-_LpV1aIn.js +6 -0
  73. package/dist/client/assets/{yjs-provider-reset-guard-Cox4nxwu.js → yjs-provider-reset-guard-DE0vINDP.js} +1 -1
  74. package/dist/client/drawio-editor.html +3 -2
  75. package/dist/client/excalidraw-editor.html +3 -2
  76. package/dist/client/export-document.html +4 -3
  77. package/dist/client/index.html +109 -27
  78. package/docker-compose.yml +42 -0
  79. package/package.json +26 -15
  80. package/scripts/local-structurizr-compose.mjs +101 -0
  81. package/src/client/app/drawio-editor-entry.js +0 -3
  82. package/src/client/app/drawio-editor.html +1 -0
  83. package/src/client/app/excalidraw-editor-entry.js +0 -3
  84. package/src/client/app/excalidraw-editor.html +1 -0
  85. package/src/client/app/export-document-entry.js +0 -3
  86. package/src/client/app/export-document.html +1 -0
  87. package/src/client/app/index.html +106 -24
  88. package/src/client/app/main-entry.js +0 -5
  89. package/src/client/application/app-shell/chat-feature.js +180 -124
  90. package/src/client/application/app-shell/comments-feature.js +20 -11
  91. package/src/client/application/app-shell/git-feature.js +16 -9
  92. package/src/client/application/app-shell/presence-feature.js +18 -11
  93. package/src/client/application/app-shell/ui-feature-shell.js +78 -17
  94. package/src/client/application/app-shell/ui-feature-sidebar.js +74 -1
  95. package/src/client/application/app-shell/ui-feature-tab-activity.js +2 -2
  96. package/src/client/application/app-shell/ui-feature-toolbar.js +2 -52
  97. package/src/client/application/app-shell/workspace-feature.js +27 -84
  98. package/src/client/application/app-shell-elements.js +9 -1
  99. package/src/client/application/diagram-chrome.js +161 -166
  100. package/src/client/application/diagram-preview-export.js +7 -34
  101. package/src/client/application/diagram-preview-hydrator.js +1 -19
  102. package/src/client/application/markdown-frontmatter.js +0 -2
  103. package/src/client/application/mermaid-preview-hydrator.js +1 -14
  104. package/src/client/application/pdf-preview-controller.js +992 -0
  105. package/src/client/application/plantuml-preview-hydrator.js +0 -10
  106. package/src/client/application/preview-diagram-utils.js +31 -2
  107. package/src/client/application/preview-render-compiler.js +2 -1
  108. package/src/client/application/preview-renderer.js +2 -2
  109. package/src/client/application/quick-switcher-loader.js +3 -1
  110. package/src/client/application/structurizr-preview-controller.js +395 -0
  111. package/src/client/application/workspace-coordinator.js +25 -3
  112. package/src/client/application/workspace-preview-controller.js +91 -5
  113. package/src/client/bootstrap/collabmd-app-shell.js +155 -43
  114. package/src/client/browser-utils.js +44 -0
  115. package/src/client/domain/excalidraw-collaboration.js +0 -2
  116. package/src/client/domain/room.js +38 -0
  117. package/src/client/domain/runtime-paths.js +26 -5
  118. package/src/client/domain/structurizr-language.js +99 -0
  119. package/src/client/domain/vault-paths.js +48 -0
  120. package/src/client/excalidraw-editor.js +833 -51
  121. package/src/client/export/export-pipeline.js +6 -34
  122. package/src/client/infrastructure/auth-client.js +4 -10
  123. package/src/client/infrastructure/browser-notification-port.js +33 -20
  124. package/src/client/infrastructure/browser-preferences-port.js +46 -9
  125. package/src/client/infrastructure/comment-thread-store.js +34 -13
  126. package/src/client/infrastructure/editor-session.js +10 -0
  127. package/src/client/infrastructure/editor-view-adapter.js +133 -5
  128. package/src/client/infrastructure/excalidraw-room-client.js +103 -14
  129. package/src/client/infrastructure/git-api-client.js +5 -0
  130. package/src/client/infrastructure/lobby-presence.js +1 -0
  131. package/src/client/infrastructure/vault-api-client.js +51 -0
  132. package/src/client/infrastructure/workspace-sync-client.js +13 -1
  133. package/src/client/presentation/comment-overview-controller.js +18 -53
  134. package/src/client/presentation/comment-ui/comment-ui-card.js +1 -12
  135. package/src/client/presentation/comment-ui/comment-ui-layout.js +242 -219
  136. package/src/client/presentation/comment-ui/comment-ui-render.js +32 -45
  137. package/src/client/presentation/comment-ui/comment-ui-shared.js +68 -13
  138. package/src/client/presentation/comment-ui-controller.js +5 -1
  139. package/src/client/presentation/drawio-embed-controller.js +9 -102
  140. package/src/client/presentation/drawio-viewer.js +118 -0
  141. package/src/client/presentation/excalidraw-embed-controller.js +74 -8
  142. package/src/client/presentation/file-action-controller.js +134 -0
  143. package/src/client/presentation/file-explorer-controller.js +33 -3
  144. package/src/client/presentation/file-explorer-view.js +59 -34
  145. package/src/client/presentation/file-icon-svg.js +40 -0
  146. package/src/client/presentation/file-tree-state.js +12 -4
  147. package/src/client/presentation/git-diff-view-controller.js +731 -3
  148. package/src/client/presentation/outline-controller.js +86 -0
  149. package/src/client/presentation/quick-switcher-controller.js +257 -74
  150. package/src/client/presentation/quick-switcher-text-search.js +3 -3
  151. package/src/client/presentation/toast-controller.js +3 -0
  152. package/src/client/styles/components/feedback.css +6 -0
  153. package/src/client/styles/components/navigation.css +11 -1
  154. package/src/client/styles/features/collaboration-chat.css +49 -53
  155. package/src/client/styles/features/collaboration-presence.css +9 -7
  156. package/src/client/styles/features/comment-card.css +25 -11
  157. package/src/client/styles/features/comment-overlays.css +0 -4
  158. package/src/client/styles/features/comment-overview.css +44 -21
  159. package/src/client/styles/features/comments-drawer.css +2 -100
  160. package/src/client/styles/features/diagram-preview.css +81 -18
  161. package/src/client/styles/features/diff-special.css +309 -0
  162. package/src/client/styles/features/embedded-preview.css +8 -33
  163. package/src/client/styles/features/quick-switcher.css +8 -0
  164. package/src/client/styles/foundation/themes.css +6 -0
  165. package/src/client/styles/foundation/tokens.css +1 -0
  166. package/src/client/styles/layout/editor-page.css +40 -0
  167. package/src/client/styles/layout/responsive.css +31 -1
  168. package/src/client/styles/layout/shell.css +383 -7
  169. package/src/client/styles/layout/sidebar.css +47 -15
  170. package/src/client/styles/layout/view-modes.css +1 -0
  171. package/src/client/styles/overrides/codemirror.css +217 -15
  172. package/src/client/styles/style.css +1 -0
  173. package/src/client/styles/surfaces/excalidraw-editor.css +294 -0
  174. package/src/domain/comment-threads.js +63 -5
  175. package/src/domain/excalidraw-room-codec.js +6 -4
  176. package/src/domain/file-kind.js +35 -3
  177. package/src/server/application/workspace-reconciliation.js +1 -1
  178. package/src/server/config/env.js +79 -0
  179. package/src/server/create-app-server.js +14 -3
  180. package/src/server/domain/bases/base-definition.js +1 -1
  181. package/src/server/domain/bases/base-expression-runtime.js +1 -4
  182. package/src/server/domain/bases/base-index-snapshot-store.js +1 -4
  183. package/src/server/domain/bases/base-query-service.js +1 -77
  184. package/src/server/domain/bases/base-transform.js +1 -4
  185. package/src/server/domain/collaboration/collaboration-room.js +55 -21
  186. package/src/server/domain/comment-overview.js +25 -8
  187. package/src/server/domain/docx-exporter.js +24 -33
  188. package/src/server/domain/ripgrep-search-service.js +7 -1
  189. package/src/server/domain/workspace-state.js +32 -11
  190. package/src/server/infrastructure/git/diff-service.js +29 -13
  191. package/src/server/infrastructure/git/git-service.js +61 -10
  192. package/src/server/infrastructure/git/history-service.js +96 -29
  193. package/src/server/infrastructure/git/image-mime.js +14 -0
  194. package/src/server/infrastructure/git/path-utils.js +1 -1
  195. package/src/server/infrastructure/git/responses.js +0 -95
  196. package/src/server/infrastructure/git/untracked-files.js +28 -1
  197. package/src/server/infrastructure/github/github-app-client.js +22 -15
  198. package/src/server/infrastructure/http/create-git-api-query-handler.js +31 -1
  199. package/src/server/infrastructure/http/create-request-handler.js +18 -31
  200. package/src/server/infrastructure/http/create-static-handler.js +5 -2
  201. package/src/server/infrastructure/http/create-structurizr-api-handler.js +145 -0
  202. package/src/server/infrastructure/http/create-vault-api-command-handler.js +70 -8
  203. package/src/server/infrastructure/http/create-vault-api-query-handler.js +51 -3
  204. package/src/server/infrastructure/http/http-errors.js +7 -1
  205. package/src/server/infrastructure/http/http-request-helpers.js +22 -0
  206. package/src/server/infrastructure/persistence/path-utils.js +1 -1
  207. package/src/server/infrastructure/persistence/vault-file-store.js +3 -0
  208. package/src/server/infrastructure/structurizr/structurizr-embed.css +43 -0
  209. package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +374 -0
  210. package/src/server/infrastructure/websocket/attach-collaboration-gateway.js +4 -22
  211. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-CbSISC1w.js +0 -1
  212. package/dist/client/assets/bases-preview-controller-2pLHk0uk.js +0 -143
  213. package/dist/client/assets/browser-utils-CKtI_rZl.js +0 -1
  214. package/dist/client/assets/button-BCEiw4Rw.js +0 -1
  215. package/dist/client/assets/chunk-AXR3VHVW-0GTk_evH.js +0 -41
  216. package/dist/client/assets/comment-threads-D-iKphIp.js +0 -4
  217. package/dist/client/assets/diagram-action-icons-aa_KOv9h.js +0 -36
  218. package/dist/client/assets/dist-BH87JoHx.js +0 -11
  219. package/dist/client/assets/dist-BIkPRZO7.js +0 -6
  220. package/dist/client/assets/dist-BqCsFpx4.js +0 -1
  221. package/dist/client/assets/dist-C2JHCt8U.js +0 -1
  222. package/dist/client/assets/dist-CZjTtmTu.js +0 -1
  223. package/dist/client/assets/dist-Cig4Ov_X.js +0 -1
  224. package/dist/client/assets/dist-CqQEC8gR.js +0 -1
  225. package/dist/client/assets/dist-D4Rzqod1.js +0 -1
  226. package/dist/client/assets/dist-D5sn-mwk.js +0 -9
  227. package/dist/client/assets/dist-D7G-n87v.js +0 -1
  228. package/dist/client/assets/dist-DRqOrNgN.js +0 -1
  229. package/dist/client/assets/dist-DetkMS_4.js +0 -1
  230. package/dist/client/assets/dist-Dp6FVkQ1.js +0 -1
  231. package/dist/client/assets/dist-DtbjNB28.js +0 -1
  232. package/dist/client/assets/dist-DyrYcvpo2.js +0 -1
  233. package/dist/client/assets/dist-GrygD2zE.js +0 -1
  234. package/dist/client/assets/dist-HmEpWUow.js +0 -1
  235. package/dist/client/assets/dist-RTa81Km7.js +0 -1
  236. package/dist/client/assets/drawio-editor-DDvFoarP.js +0 -9
  237. package/dist/client/assets/drawio-embed-controller-BD1GTRwn.js +0 -1
  238. package/dist/client/assets/drawioEditor-Bu5grlH5.js +0 -2
  239. package/dist/client/assets/editor-session-DGlpiAsK.js +0 -16
  240. package/dist/client/assets/embedded-editor-base-C9roKYpW.css +0 -1
  241. package/dist/client/assets/excalidraw-editor-BHu6k8d4.js +0 -9
  242. package/dist/client/assets/excalidraw-editor-Cr_184EF.css +0 -1
  243. package/dist/client/assets/excalidraw-embed-controller-y2fenN_g.js +0 -1
  244. package/dist/client/assets/excalidraw-embed-reconciler-DGiagExg.js +0 -1
  245. package/dist/client/assets/excalidraw-scene-BvsQ6mLP.js +0 -176
  246. package/dist/client/assets/excalidrawEditor-4vFE--Uw.js +0 -2
  247. package/dist/client/assets/export-page-Cby8JzPO.js +0 -39
  248. package/dist/client/assets/exportDocument-C9v-bc7I.css +0 -1
  249. package/dist/client/assets/exportDocument-CRHCfsdo.js +0 -2
  250. package/dist/client/assets/file-history-view-controller-BDjEV9xJ.js +0 -112
  251. package/dist/client/assets/file-kind-BKPOIRPE.js +0 -1
  252. package/dist/client/assets/git-diff-view-controller-DgdM1aqb.js +0 -150
  253. package/dist/client/assets/git-panel-controller-BDTR2HVp.js +0 -207
  254. package/dist/client/assets/image-XGD7JQR6-XDUWHRpO.js +0 -1
  255. package/dist/client/assets/index-7xOyXDhP.css +0 -1
  256. package/dist/client/assets/index-Bz1KuQ6y.js +0 -2
  257. package/dist/client/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  258. package/dist/client/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  259. package/dist/client/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  260. package/dist/client/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  261. package/dist/client/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  262. package/dist/client/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  263. package/dist/client/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  264. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  265. package/dist/client/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  266. package/dist/client/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  267. package/dist/client/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  268. package/dist/client/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  269. package/dist/client/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  270. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  271. package/dist/client/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  272. package/dist/client/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  273. package/dist/client/assets/main-Ci07m9oP.js +0 -152
  274. package/dist/client/assets/preview-diagram-utils-n_bbJA9V.js +0 -1
  275. package/dist/client/assets/preview-render-compiler-csGM5ZFz.js +0 -1
  276. package/dist/client/assets/quick-switcher-controller-CoiYvllm.js +0 -12
  277. package/dist/client/assets/room-CDrmIdDt.js +0 -1
  278. package/dist/client/assets/runtime-config-CDgeuPWN.js +0 -1
  279. package/dist/client/assets/runtime-config-loader-BHGniHP5.js +0 -1
  280. package/dist/client/assets/runtime-paths-DvpihCEq.js +0 -1
  281. package/dist/client/assets/segmented-control-DJrHSz8M.js +0 -1
  282. package/dist/client/assets/vault-api-client-sLB2bo56.js +0 -1
  283. package/dist/client/assets/vault-paths-CVkuh0j-.js +0 -5
  284. package/src/client/bootstrap/lazy-controller-feature.js +0 -433
  285. package/src/client/infrastructure/backlinks-api-client.js +0 -16
  286. package/src/client/infrastructure/plantuml-api-client.js +0 -19
  287. package/src/client/infrastructure/runtime-config-loader.js +0 -56
  288. package/src/server/domain/collaboration/room-persistence-controller.js +0 -80
  289. package/src/server/infrastructure/git/command-runner.js +0 -49
  290. package/src/server/infrastructure/git/errors.js +0 -8
  291. package/src/server/infrastructure/http/create-esm-proxy-handler.js +0 -130
@@ -15,12 +15,12 @@
15
15
  document.documentElement.setAttribute('data-initial-file-requested', 'true');
16
16
  }
17
17
  </script>
18
- <script type="module" crossorigin src="./assets/index-Bz1KuQ6y.js"></script>
19
- <link rel="modulepreload" crossorigin href="./assets/runtime-config-loader-BHGniHP5.js">
18
+ <script type="module" crossorigin src="./assets/index-ClbjMBVt.js"></script>
19
+ <link rel="modulepreload" crossorigin href="./assets/modulepreload-polyfill-P2Xu9kJm.js">
20
20
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-HclGiUj8.js">
21
21
  <link rel="modulepreload" crossorigin href="./assets/base-CxPEiHuy.js">
22
22
  <link rel="stylesheet" crossorigin href="./assets/base-CaIEJUF9.css">
23
- <link rel="stylesheet" crossorigin href="./assets/index-7xOyXDhP.css">
23
+ <link rel="stylesheet" crossorigin href="./assets/index-Pum8ET-5.css">
24
24
  </head>
25
25
  <body>
26
26
 
@@ -61,6 +61,21 @@
61
61
  <span class="sidebar-create-btn-label">Create</span>
62
62
  </button>
63
63
  </div>
64
+ <button
65
+ class="ui-icon-button sidebar-options-btn"
66
+ id="fileExplorerOptionsBtn"
67
+ type="button"
68
+ aria-label="File explorer options"
69
+ aria-expanded="false"
70
+ aria-haspopup="menu"
71
+ title="File explorer options"
72
+ >
73
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true">
74
+ <circle cx="12" cy="5" r="1"></circle>
75
+ <circle cx="12" cy="12" r="1"></circle>
76
+ <circle cx="12" cy="19" r="1"></circle>
77
+ </svg>
78
+ </button>
64
79
  </div>
65
80
  </div>
66
81
  <div class="ui-nav-tabs" id="sidebarTabs">
@@ -117,6 +132,19 @@
117
132
  <nav id="fileTree" class="file-tree" aria-label="File explorer"></nav>
118
133
  <section id="commentOverviewPanel" class="comment-overview-panel hidden" aria-label="Open comments"></section>
119
134
  <div id="gitPanel" class="git-panel hidden" aria-label="Git changes"></div>
135
+ <div
136
+ class="sidebar-resizer"
137
+ id="sidebarResizer"
138
+ role="separator"
139
+ aria-orientation="vertical"
140
+ aria-label="Resize sidebar"
141
+ aria-controls="sidebar"
142
+ aria-valuemin="220"
143
+ aria-valuemax="420"
144
+ aria-valuenow="260"
145
+ tabindex="0"
146
+ title="Drag to resize sidebar"
147
+ ></div>
120
148
  </aside>
121
149
 
122
150
  <button
@@ -144,7 +172,24 @@
144
172
  </div>
145
173
 
146
174
  <div class="toolbar-center" id="toolbarCenter">
147
- <div class="ui-segmented-control view-toggle" role="group" aria-label="View mode">
175
+ <button
176
+ class="ui-button ui-button--secondary ui-button--compact toolbar-search-trigger"
177
+ id="toolbarSearchBtn"
178
+ type="button"
179
+ aria-label="Search files and text"
180
+ aria-controls="quickSwitcher"
181
+ aria-haspopup="dialog"
182
+ aria-keyshortcuts="Meta+K Control+K"
183
+ title="Search files and text (⌘K)"
184
+ >
185
+ <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true">
186
+ <circle cx="11" cy="11" r="7"></circle>
187
+ <line x1="20" y1="20" x2="16.65" y2="16.65"></line>
188
+ </svg>
189
+ <span class="toolbar-search-label">Search</span>
190
+ <kbd class="toolbar-search-kbd">⌘K</kbd>
191
+ </button>
192
+ <div class="ui-segmented-control view-toggle" id="toolbarViewToggle" role="group" aria-label="View mode">
148
193
  <button class="ui-segmented-btn active view-btn" data-view="split" aria-label="Split view" aria-pressed="true" title="Split view">
149
194
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
150
195
  <rect x="3" y="3" width="18" height="18" rx="2"></rect>
@@ -192,7 +237,7 @@
192
237
 
193
238
  <div class="user-avatars toolbar-presence-cluster" id="userAvatars"></div>
194
239
 
195
- <section class="presence-panel hidden" id="presencePanel" aria-label="Online users" aria-hidden="true">
240
+ <section class="collaboration-popover presence-panel hidden" id="presencePanel" aria-label="Online users" aria-hidden="true">
196
241
  <div class="presence-panel-header">
197
242
  <div>
198
243
  <h2 class="presence-panel-title">Online now</h2>
@@ -203,7 +248,7 @@
203
248
  </section>
204
249
 
205
250
  <div class="chat-container" id="chatContainer">
206
- <button class="ui-button ui-button--ghost ui-button--toolbar chat-toggle-btn" id="chatToggleBtn" aria-label="Open team chat" aria-expanded="false" title="Team chat">
251
+ <button type="button" class="ui-button ui-button--ghost ui-button--toolbar chat-toggle-btn" id="chatToggleBtn" aria-label="Open team chat" aria-controls="chatPanel" aria-expanded="false" title="Team chat">
207
252
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
208
253
  <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
209
254
  </svg>
@@ -212,23 +257,44 @@
212
257
  </button>
213
258
  <div class="toast-container chat-toast-container" id="chatToastContainer" aria-live="polite" aria-atomic="true"></div>
214
259
 
215
- <section class="chat-panel hidden" id="chatPanel" aria-label="Team chat">
260
+ <section class="collaboration-popover chat-panel hidden" id="chatPanel" role="dialog" aria-labelledby="chatPanelTitle">
216
261
  <div class="chat-panel-header">
217
- <div>
218
- <h2 class="chat-panel-title">Team chat</h2>
219
- <p class="chat-panel-status" id="chatStatus">Syncing...</p>
262
+ <div class="chat-panel-heading">
263
+ <h2 class="chat-panel-title" id="chatPanelTitle">Team chat</h2>
264
+ <p class="chat-panel-status" id="chatStatus" role="status" aria-live="polite" aria-atomic="true">Syncing...</p>
265
+ </div>
266
+ <div class="chat-panel-actions">
267
+ <span class="ui-status-badge ui-status-badge--accent chat-notification-status hidden" id="chatNotificationStatus" role="status"></span>
268
+ <button
269
+ type="button"
270
+ class="ui-button ui-button--ghost ui-button--compact chat-notification-action"
271
+ id="chatNotificationBtn"
272
+ >Enable desktop alerts</button>
273
+ <button
274
+ type="button"
275
+ class="ui-icon-button chat-notification-mute-action hidden"
276
+ id="chatNotificationMuteBtn"
277
+ aria-label="Mute desktop alerts for one hour"
278
+ aria-pressed="false"
279
+ title="Mute desktop alerts for one hour"
280
+ >
281
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
282
+ <path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9"></path>
283
+ <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
284
+ <path class="chat-notification-mute-slash" d="m4 4 16 16"></path>
285
+ </svg>
286
+ </button>
287
+ <button type="button" class="ui-icon-button chat-close-btn" id="chatCloseBtn" aria-label="Close team chat" title="Close team chat">
288
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true">
289
+ <line x1="18" y1="6" x2="6" y2="18"></line>
290
+ <line x1="6" y1="6" x2="18" y2="18"></line>
291
+ </svg>
292
+ </button>
220
293
  </div>
221
- <button
222
- class="ui-button ui-button--secondary ui-button--compact ui-button--action ui-button--surface ui-button--pill chat-notification-action"
223
- id="chatNotificationBtn"
224
- type="button"
225
- >
226
- Enable alerts
227
- </button>
228
294
  </div>
229
295
 
230
- <div class="chat-empty-state" id="chatEmptyState">
231
- Temporary room chat for whoever is online right now.
296
+ <div class="ui-empty-state ui-empty-state--compact chat-empty-state" id="chatEmptyState">
297
+ Messages are visible to everyone in this room.
232
298
  </div>
233
299
  <div class="chat-messages hidden" id="chatMessages" role="log" aria-live="polite" aria-relevant="additions text"></div>
234
300
 
@@ -237,10 +303,11 @@
237
303
  type="text"
238
304
  class="ui-input chat-input"
239
305
  id="chatInput"
240
- placeholder="Send a quick update..."
306
+ placeholder="Message the room..."
241
307
  autocomplete="off"
242
308
  spellcheck="true"
243
309
  maxlength="280"
310
+ enterkeyhint="send"
244
311
  aria-label="Team chat message"
245
312
  >
246
313
  <button type="submit" class="ui-button ui-button--primary chat-send-btn">Send</button>
@@ -296,6 +363,18 @@
296
363
  <span class="ui-toolbar-button-label">Search files</span>
297
364
  </button>
298
365
 
366
+ <button class="ui-button ui-button--ghost ui-button--toolbar ui-button--toggle toolbar-vim-button" id="toggleVimModeBtn" aria-label="Enable Vim keybindings" aria-pressed="false" title="Enable Vim keybindings">
367
+ <span class="toolbar-vim-icon" aria-hidden="true">
368
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
369
+ <rect x="3" y="4" width="18" height="16" rx="2"></rect>
370
+ <path d="m7 9 3 3-3 3"></path>
371
+ <path d="M13 15h4"></path>
372
+ </svg>
373
+ </span>
374
+ <span class="ui-toolbar-button-label">Vim</span>
375
+ <span class="ui-pill-badge ui-pill-badge--muted toolbar-vim-state" id="vimModeToggleLabel">Off</span>
376
+ </button>
377
+
299
378
  <details class="toolbar-overflow-group hidden" id="exportMenuGroup">
300
379
  <summary class="ui-button ui-button--ghost ui-button--toolbar toolbar-overflow-group-toggle" aria-label="Export options" title="Export">
301
380
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -652,28 +731,31 @@
652
731
 
653
732
  <div class="toast-container" id="toastContainer"></div>
654
733
 
655
- <div class="qs-overlay" id="quickSwitcher">
734
+ <div class="qs-overlay" id="quickSwitcher" role="dialog" aria-modal="true" aria-labelledby="quickSwitcherTitle" aria-hidden="true">
656
735
  <div class="qs-modal">
736
+ <h2 class="sr-only" id="quickSwitcherTitle">Search files and text</h2>
657
737
  <div class="qs-mode-tabs" role="tablist" aria-label="Search mode">
658
- <button class="qs-mode-tab active" type="button" role="tab" aria-selected="true" data-qs-mode="files">Files</button>
659
- <button class="qs-mode-tab" type="button" role="tab" aria-selected="false" data-qs-mode="text">Text</button>
738
+ <button class="qs-mode-tab active" id="quickSwitcherFilesTab" type="button" role="tab" aria-controls="quickSwitcherResults" aria-selected="true" data-qs-mode="files">Files</button>
739
+ <button class="qs-mode-tab" id="quickSwitcherTextTab" type="button" role="tab" aria-controls="quickSwitcherResults" aria-selected="false" data-qs-mode="text">Text</button>
660
740
  </div>
661
741
  <div class="qs-input-wrap">
662
742
  <svg class="qs-search-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
663
743
  <circle cx="11" cy="11" r="8"></circle>
664
744
  <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
665
745
  </svg>
666
- <input type="text" class="qs-input" id="quickSwitcherInput" placeholder="Search files..." autocomplete="off" spellcheck="false">
746
+ <input type="text" class="qs-input" id="quickSwitcherInput" placeholder="Search files..." aria-label="Search files" aria-controls="quickSwitcherResults" aria-describedby="quickSwitcherHint quickSwitcherScope" autocomplete="off" spellcheck="false">
667
747
  <kbd class="qs-kbd">esc</kbd>
668
748
  </div>
669
- <div class="qs-results" id="quickSwitcherResults"></div>
670
- <div class="qs-hint" id="quickSwitcherHint">Type to search files</div>
671
- <div class="qs-footer" aria-hidden="true">
749
+ <div class="qs-scope hidden" id="quickSwitcherScope" role="note" aria-hidden="true">Exact, case-insensitive text in Markdown, Base, Mermaid, PlantUML, Draw.io, and Excalidraw files. Images are excluded.</div>
750
+ <div class="qs-results" id="quickSwitcherResults" role="listbox" aria-label="Search results" aria-busy="false" tabindex="-1"></div>
751
+ <div class="qs-hint" id="quickSwitcherHint" role="status" aria-live="polite" aria-atomic="true">Type to search files</div>
752
+ <div class="qs-footer">
672
753
  <span><kbd>↑</kbd><kbd>↓</kbd> Navigate</span>
673
754
  <span><kbd>↵</kbd> Open</span>
674
755
  <span><kbd>Tab</kbd> Switch mode</span>
675
756
  </div>
676
757
  </div>
677
758
  </div>
759
+ <script src="./app-config.js"></script>
678
760
  </body>
679
761
  </html>
@@ -3,6 +3,7 @@ services:
3
3
  image: ${COLLABMD_IMAGE:-ghcr.io/andes90/collabmd:latest}
4
4
  depends_on:
5
5
  - plantuml
6
+ - structurizr
6
7
  environment:
7
8
  HOST: 0.0.0.0
8
9
  PORT: 1234
@@ -19,7 +20,11 @@ services:
19
20
  BASE_PATH: ${BASE_PATH:-}
20
21
  PUBLIC_WS_BASE_URL: ${PUBLIC_WS_BASE_URL:-}
21
22
  PLANTUML_SERVER_URL: http://plantuml:8080
23
+ STRUCTURIZR_SERVER_URL: http://structurizr:8080
24
+ STRUCTURIZR_MIRROR_DIR: ${COLLABMD_VAULT_DIR:-/data}/.collabmd/structurizr
25
+ STRUCTURIZR_TRUSTED_EXECUTABLE_DSL: ${STRUCTURIZR_TRUSTED_EXECUTABLE_DSL:-false}
22
26
  COLLABMD_WIKI_LINK_AUTO_CREATE: ${COLLABMD_WIKI_LINK_AUTO_CREATE:-true}
27
+ COLLABMD_MAX_PDF_UPLOAD_BYTES: ${COLLABMD_MAX_PDF_UPLOAD_BYTES:-52428800}
23
28
  COLLABMD_VAULT_DIR: ${COLLABMD_VAULT_DIR:-/data}
24
29
  COLLABMD_GIT_REPO_URL: ${COLLABMD_GIT_REPO_URL:-}
25
30
  COLLABMD_GIT_SSH_PRIVATE_KEY_FILE: ${COLLABMD_GIT_SSH_PRIVATE_KEY_FILE:-}
@@ -36,6 +41,9 @@ services:
36
41
  ports:
37
42
  - "${COLLABMD_HOST_PORT:-1234}:1234"
38
43
  restart: unless-stopped
44
+ networks:
45
+ - default
46
+ - diagram-private
39
47
  volumes:
40
48
  - type: bind
41
49
  source: ${HOST_VAULT_DIR:-./data/vault}
@@ -52,6 +60,40 @@ services:
52
60
 
53
61
  plantuml:
54
62
  image: plantuml/plantuml-server:jetty
63
+ networks:
64
+ - diagram-private
55
65
  ports:
56
66
  - "127.0.0.1:${PLANTUML_HOST_PORT:-18080}:8080"
57
67
  restart: unless-stopped
68
+
69
+ structurizr:
70
+ image: structurizr/structurizr:2026.06.28
71
+ command: ["local", "/data"]
72
+ environment:
73
+ STRUCTURIZR_EDITABLE: "false"
74
+ STRUCTURIZR_AUTOREFRESHINTERVAL: "0"
75
+ STRUCTURIZR_AUTOSAVEINTERVAL: "0"
76
+ STRUCTURIZR_NETWORK_URLS_ALLOWED: ${STRUCTURIZR_NETWORK_URLS_ALLOWED:-}
77
+ networks:
78
+ - diagram-private
79
+ security_opt:
80
+ - no-new-privileges:true
81
+ cap_drop:
82
+ - ALL
83
+ cpus: 1.0
84
+ mem_limit: 768m
85
+ pids_limit: 256
86
+ read_only: true
87
+ restart: unless-stopped
88
+ ports:
89
+ - "127.0.0.1:${STRUCTURIZR_HOST_PORT:-19090}:8080"
90
+ tmpfs:
91
+ - /tmp
92
+ volumes:
93
+ - type: bind
94
+ source: ${HOST_VAULT_DIR:-./data/vault}/.collabmd/structurizr
95
+ target: /data
96
+
97
+ networks:
98
+ diagram-private:
99
+ driver: bridge
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "collabmd",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "type": "module",
5
- "description": "Collaborative markdown vault like Obsidian, but online. Serve any directory of markdown files for realtime collaborative editing.",
5
+ "description": "Collaborative markdown vault \u2014 like Obsidian, but online. Serve any directory of markdown files for realtime collaborative editing.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/andes90/collabmd.git"
@@ -18,6 +18,7 @@
18
18
  "docker-compose.yml",
19
19
  "scripts/cloudflare-tunnel.mjs",
20
20
  "scripts/local-plantuml-compose.mjs",
21
+ "scripts/local-structurizr-compose.mjs",
21
22
  "src/"
22
23
  ],
23
24
  "bin": {
@@ -34,8 +35,11 @@
34
35
  "lint": "eslint .",
35
36
  "plantuml:up": "node scripts/local-plantuml-compose.mjs up",
36
37
  "plantuml:down": "node scripts/local-plantuml-compose.mjs down",
38
+ "structurizr:up": "node scripts/local-structurizr-compose.mjs up",
39
+ "structurizr:down": "node scripts/local-structurizr-compose.mjs down",
37
40
  "start": "npm run build && node bin/collabmd.js",
38
41
  "start:local-plantuml": "npm run build && node bin/collabmd.js --local-plantuml",
42
+ "start:local-structurizr": "npm run build && node bin/collabmd.js --local-structurizr",
39
43
  "start:prod": "node bin/collabmd.js",
40
44
  "test": "npm run test:guardrails && npm run test:unit && npm run test:integration:prebuilt && npm run test:browser && npm run test:e2e:prebuilt",
41
45
  "test:browser": "vitest run --config vitest.config.mjs --browser=chromium",
@@ -43,10 +47,10 @@
43
47
  "test:e2e:headed": "npm run build && playwright test --headed",
44
48
  "test:e2e:prebuilt": "playwright test",
45
49
  "test:excalidraw:stress": "node scripts/run-excalidraw-reliability-stress.mjs",
46
- "test:guardrails": "node --test tests/node/style-system-guardrails.test.js",
47
- "test:integration": "npm run build && node scripts/run-node-tests.mjs integration",
48
- "test:integration:prebuilt": "node scripts/run-node-tests.mjs integration",
49
- "test:unit": "npm run build && node scripts/run-node-tests.mjs fast",
50
+ "test:guardrails": "node --test tests/node/guardrails/*.test.js",
51
+ "test:integration": "npm run build && npm run test:integration:prebuilt",
52
+ "test:integration:prebuilt": "node --test --test-force-exit --test-concurrency=2 tests/node/integration/*.test.js",
53
+ "test:unit": "npm run build && node --test --test-force-exit tests/node/*.test.js",
50
54
  "tunnel": "node scripts/cloudflare-tunnel.mjs"
51
55
  },
52
56
  "keywords": [
@@ -73,9 +77,8 @@
73
77
  "@codemirror/state": "^6.7.1",
74
78
  "@codemirror/theme-one-dark": "^6.1.3",
75
79
  "@codemirror/view": "^6.43.8",
76
- "@excalidraw/excalidraw": "0.18.0-ab0255f",
77
- "@fontsource-variable/inter": "^5.3.0",
78
- "@fontsource/jetbrains-mono": "^5.3.0",
80
+ "@excalidraw/excalidraw": "0.18.0-4872083",
81
+ "@replit/codemirror-vim": "^6.4.0",
79
82
  "@turbodocx/html-to-docx": "^1.22.0",
80
83
  "archiver": "^8.0.0",
81
84
  "highlight.js": "^11.11.1",
@@ -84,28 +87,36 @@
84
87
  "markdown-it": "^15.0.0",
85
88
  "mermaid": "^11.16.1",
86
89
  "openid-client": "^6.8.4",
90
+ "pdfjs-dist": "6.2.108",
87
91
  "react": "^19.2.8",
88
92
  "react-dom": "^19.2.8",
89
93
  "sharp": "^0.35.3",
90
- "ws": "^8.21.2",
94
+ "ws": "^8.21.3",
91
95
  "y-codemirror.next": "^0.3.5",
92
96
  "y-protocols": "^1.0.7",
93
- "y-websocket": "^3.0.0",
97
+ "y-websocket": "^3.1.0",
94
98
  "yjs": "^13.6.32"
95
99
  },
96
100
  "overrides": {
97
101
  "@excalidraw/excalidraw": {
98
- "@radix-ui/react-tabs": "1.1.13"
99
- }
102
+ "@radix-ui/react-tabs": "1.1.13",
103
+ "nanoid": "3.3.18"
104
+ },
105
+ "@excalidraw/mermaid-to-excalidraw": {
106
+ "nanoid": "5.1.16"
107
+ },
108
+ "lodash-es": "4.18.1",
109
+ "nanoid": "3.3.18",
110
+ "axios": "1.18.0"
100
111
  },
101
112
  "devDependencies": {
102
113
  "@eslint/js": "^10.0.1",
103
114
  "@playwright/test": "^1.62.1",
104
115
  "@vitest/browser": "^4.1.10",
105
116
  "@vitest/browser-playwright": "^4.1.10",
106
- "eslint": "^10.8.0",
117
+ "eslint": "^10.8.1",
107
118
  "globals": "^17.9.0",
108
- "vite": "^8.2.0",
119
+ "vite": "^8.2.1",
109
120
  "vitest": "^4.1.10"
110
121
  }
111
122
  }
@@ -0,0 +1,101 @@
1
+ import { mkdir } from 'node:fs/promises';
2
+ import { spawn } from 'node:child_process';
3
+ import { dirname, resolve } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ const scriptPath = fileURLToPath(import.meta.url);
7
+ const scriptDir = dirname(scriptPath);
8
+ const projectRoot = resolve(scriptDir, '..');
9
+ const composeFile = resolve(projectRoot, 'docker-compose.yml');
10
+
11
+ function runCommand(command, args, { env = process.env } = {}) {
12
+ return new Promise((resolvePromise, rejectPromise) => {
13
+ const child = spawn(command, args, {
14
+ cwd: projectRoot,
15
+ env,
16
+ stdio: 'inherit',
17
+ });
18
+
19
+ child.on('error', rejectPromise);
20
+ child.on('exit', (code) => {
21
+ if (code === 0) {
22
+ resolvePromise();
23
+ return;
24
+ }
25
+
26
+ rejectPromise(new Error(`${command} ${args.join(' ')} exited with code ${code}`));
27
+ });
28
+ });
29
+ }
30
+
31
+ export function getLocalStructurizrHostPort() {
32
+ const rawValue = process.env.STRUCTURIZR_HOST_PORT || '19090';
33
+ const parsed = Number.parseInt(rawValue, 10);
34
+
35
+ if (!Number.isInteger(parsed) || parsed <= 0) {
36
+ throw new Error(`Invalid STRUCTURIZR_HOST_PORT: ${rawValue}`);
37
+ }
38
+
39
+ return parsed;
40
+ }
41
+
42
+ export function getLocalStructurizrServerUrl() {
43
+ return `http://127.0.0.1:${getLocalStructurizrHostPort()}`;
44
+ }
45
+
46
+ function getComposeArgs(command) {
47
+ return ['compose', '-f', composeFile, ...command];
48
+ }
49
+
50
+ export async function startLocalStructurizrComposeService({ vaultDir = process.env.COLLABMD_VAULT_DIR || '.' } = {}) {
51
+ const hostVaultDir = resolve(vaultDir);
52
+ await mkdir(resolve(hostVaultDir, '.collabmd/structurizr'), { recursive: true });
53
+ await runCommand('docker', getComposeArgs(['up', '-d', 'structurizr']), {
54
+ env: {
55
+ ...process.env,
56
+ HOST_VAULT_DIR: hostVaultDir,
57
+ STRUCTURIZR_HOST_PORT: String(getLocalStructurizrHostPort()),
58
+ },
59
+ });
60
+ return getLocalStructurizrServerUrl();
61
+ }
62
+
63
+ export async function stopLocalStructurizrComposeService() {
64
+ await runCommand('docker', getComposeArgs(['stop', 'structurizr']));
65
+ }
66
+
67
+ async function main() {
68
+ const command = process.argv[2] || 'up';
69
+
70
+ if (command === 'up') {
71
+ const url = await startLocalStructurizrComposeService();
72
+ console.log(`[structurizr] Local Structurizr renderer is available at ${url}`);
73
+ return;
74
+ }
75
+
76
+ if (command === 'down') {
77
+ await stopLocalStructurizrComposeService();
78
+ console.log('[structurizr] Local Structurizr renderer stopped');
79
+ return;
80
+ }
81
+
82
+ if (command === 'url') {
83
+ console.log(getLocalStructurizrServerUrl());
84
+ return;
85
+ }
86
+
87
+ console.error('Usage: node scripts/local-structurizr-compose.mjs [up|down|url]');
88
+ process.exit(1);
89
+ }
90
+
91
+ if (process.argv[1] && resolve(process.argv[1]) === scriptPath) {
92
+ main().catch((error) => {
93
+ if (error.code === 'ENOENT') {
94
+ console.error('[structurizr] Docker is not available. Install Docker Desktop or Docker Engine first.');
95
+ } else {
96
+ console.error(`[structurizr] ${error.message}`);
97
+ }
98
+
99
+ process.exit(1);
100
+ });
101
+ }
@@ -1,4 +1 @@
1
- import { ensureRuntimeConfigLoaded } from '../infrastructure/runtime-config-loader.js';
2
-
3
- await ensureRuntimeConfigLoaded();
4
1
  await import('../drawio-editor.js');
@@ -9,6 +9,7 @@
9
9
  <div id="root">
10
10
  <div class="drawio-loading" id="loadingState">Loading draw.io…</div>
11
11
  </div>
12
+ <script vite-ignore src="./app-config.js"></script>
12
13
  <script type="module" src="./drawio-editor-entry.js"></script>
13
14
  </body>
14
15
  </html>
@@ -1,4 +1 @@
1
- import { ensureRuntimeConfigLoaded } from '../infrastructure/runtime-config-loader.js';
2
-
3
- await ensureRuntimeConfigLoaded();
4
1
  await import('../excalidraw-editor.js');
@@ -9,6 +9,7 @@
9
9
  <div id="root">
10
10
  <div class="loading-state" id="loadingState">Loading Excalidraw...</div>
11
11
  </div>
12
+ <script vite-ignore src="./app-config.js"></script>
12
13
  <script type="module" src="./excalidraw-editor-entry.js"></script>
13
14
  </body>
14
15
  </html>
@@ -6,8 +6,6 @@ import '../styles/features/preview-markdown.css';
6
6
  import '../styles/overrides/highlightjs.css';
7
7
  import '../styles/export-document.css';
8
8
 
9
- import { ensureRuntimeConfigLoaded } from '../infrastructure/runtime-config-loader.js';
10
-
11
9
  function ensureHighlightThemeStylesheet() {
12
10
  let themeStylesheet = document.getElementById('hljs-theme');
13
11
  if (!(themeStylesheet instanceof HTMLLinkElement)) {
@@ -20,6 +18,5 @@ function ensureHighlightThemeStylesheet() {
20
18
  themeStylesheet.href = lightHighlightThemeUrl;
21
19
  }
22
20
 
23
- await ensureRuntimeConfigLoaded();
24
21
  ensureHighlightThemeStylesheet();
25
22
  await import('../export/export-page.js');
@@ -19,6 +19,7 @@
19
19
  </section>
20
20
  <article id="exportContent" class="preview-content export-content"></article>
21
21
  </main>
22
+ <script vite-ignore src="./app-config.js"></script>
22
23
  <script type="module" src="./export-document-entry.js"></script>
23
24
  </body>
24
25
  </html>