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
@@ -14,15 +14,18 @@ import {
14
14
  sanitizeSvgMarkup,
15
15
  } from '../application/preview-diagram-utils.js';
16
16
  import { compilePreviewDocument } from '../application/preview-render-compiler.js';
17
- import { stripVaultFileExtension } from '../../domain/file-kind.js';
18
- import { parseSceneJson, sceneToInitialData } from '../domain/excalidraw-scene.js';
17
+ import { isMarkdownFilePath, stripVaultFileExtension } from '../../domain/file-kind.js';
18
+ import { resolveVaultRelativePath } from '../../domain/vault-paths.js';
19
+ import { resolveWikiTargetPath } from '../../domain/wiki-link-resolver.js';
20
+ import { createExcalidrawExportOptions, parseSceneJson } from '../domain/excalidraw-scene.js';
19
21
  import { escapeHtml } from '../domain/vault-utils.js';
20
22
  import { downloadBlob } from '../browser-utils.js';
21
23
  import { resolveApiUrl, resolveAppUrl } from '../infrastructure/runtime-config.js';
24
+ import { parseApiResponse } from '../infrastructure/api-client-utils.js';
22
25
 
23
26
  const EXPORT_PAGE_SOURCE = 'collabmd-export-page';
24
27
  const EXPORT_HOST_SOURCE = 'collabmd-export-host';
25
- const LIGHT_EXPORT_MERMAID_THEME = Object.freeze({
28
+ const EXPORT_MERMAID_CONFIG = Object.freeze({
26
29
  htmlLabels: false,
27
30
  flowchart: {
28
31
  defaultRenderer: 'dagre-wrapper',
@@ -33,7 +36,6 @@ const LIGHT_EXPORT_MERMAID_THEME = Object.freeze({
33
36
  useMaxWidth: true,
34
37
  },
35
38
  startOnLoad: false,
36
- theme: 'default',
37
39
  });
38
40
  const EXPORT_ASSET_FETCH_TIMEOUT_MS = 10_000;
39
41
  const EXPORT_ASSET_MAX_BYTES = 10 * 1024 * 1024;
@@ -77,6 +79,10 @@ function createAssetId(prefix = 'asset') {
77
79
  return `${prefix}-${assetCounter.toString(36)}`;
78
80
  }
79
81
 
82
+ function normalizeExportTheme(theme) {
83
+ return theme === 'dark' ? 'dark' : 'light';
84
+ }
85
+
80
86
  function createDocumentTitle(filePath, title = '') {
81
87
  const normalizedTitle = String(title ?? '').trim();
82
88
  if (normalizedTitle) {
@@ -87,6 +93,65 @@ function createDocumentTitle(filePath, title = '') {
87
93
  return stripVaultFileExtension(leaf) || 'document';
88
94
  }
89
95
 
96
+ function createDocumentAnchorId(filePath) {
97
+ return `export-doc-${encodeURIComponent(String(filePath ?? '').toLowerCase()).replace(/%/gu, '-').replace(/\./gu, '-')}`;
98
+ }
99
+
100
+ function createExportHeadingSlug(value) {
101
+ return String(value ?? '').trim().toLowerCase().replace(/[^a-z0-9]+/gu, '-').replace(/^-|-$/gu, '');
102
+ }
103
+
104
+ function rewriteDirectoryDocumentLinks(container, { fileList, sourceFilePath }) {
105
+ const exportedPaths = new Set(fileList);
106
+ const sourceAnchorId = createDocumentAnchorId(sourceFilePath);
107
+
108
+ Array.from(container.querySelectorAll('[id]')).forEach((element) => {
109
+ element.id = `${sourceAnchorId}-${element.id}`;
110
+ });
111
+
112
+ Array.from(container.querySelectorAll('a[href]')).forEach((link) => {
113
+ const rawHref = String(link.getAttribute('href') || '').trim();
114
+ const wikiTarget = String(link.getAttribute('data-wiki-target') || '').trim();
115
+ if (wikiTarget) {
116
+ const [targetPath, targetHeading = ''] = wikiTarget.split('#', 2);
117
+ const resolved = targetPath ? resolveWikiTargetPath(targetPath, fileList) : sourceFilePath;
118
+ if (resolved && exportedPaths.has(resolved)) {
119
+ const headingSlug = createExportHeadingSlug(targetHeading);
120
+ const targetAnchorId = createDocumentAnchorId(resolved);
121
+ link.setAttribute('href', headingSlug ? `#${targetAnchorId}-${headingSlug}` : `#${targetAnchorId}`);
122
+ link.removeAttribute('target');
123
+ link.removeAttribute('rel');
124
+ }
125
+ return;
126
+ }
127
+
128
+ if (!rawHref || /^(?:[a-z][a-z\d+.-]*:|\/\/)/iu.test(rawHref)) {
129
+ return;
130
+ }
131
+
132
+ if (rawHref.startsWith('#')) {
133
+ link.setAttribute('href', `#${sourceAnchorId}-${rawHref.slice(1)}`);
134
+ return;
135
+ }
136
+
137
+ const [pathPart, fragment = ''] = rawHref.split('#', 2);
138
+ const resolved = resolveVaultRelativePath(sourceFilePath, pathPart);
139
+ if (!exportedPaths.has(resolved)) {
140
+ return;
141
+ }
142
+
143
+ const targetAnchorId = createDocumentAnchorId(resolved);
144
+ link.setAttribute('href', fragment ? `#${targetAnchorId}-${fragment}` : `#${targetAnchorId}`);
145
+ link.removeAttribute('target');
146
+ link.removeAttribute('rel');
147
+ });
148
+ }
149
+
150
+ function replaceChildrenFromHtml(target, html) {
151
+ const parsed = new DOMParser().parseFromString(`<body>${String(html ?? '')}</body>`, 'text/html');
152
+ target.replaceChildren(...parsed.body.childNodes);
153
+ }
154
+
90
155
  function encodeSvgBase64DataUrl(svgMarkup) {
91
156
  const bytes = new TextEncoder().encode(String(svgMarkup ?? ''));
92
157
  const chunkSize = 0x8000;
@@ -117,7 +182,7 @@ function trimSvgCanvas(svgMarkup, { padding = 16 } = {}) {
117
182
  probe.style.top = '0';
118
183
  probe.style.visibility = 'hidden';
119
184
  probe.style.pointerEvents = 'none';
120
- probe.innerHTML = svgMarkup;
185
+ replaceChildrenFromHtml(probe, svgMarkup);
121
186
  document.body.appendChild(probe);
122
187
 
123
188
  try {
@@ -167,7 +232,7 @@ async function svgMarkupToPngDataUrl(svgMarkup) {
167
232
  type: 'image/svg+xml;charset=utf-8',
168
233
  }));
169
234
  const svgProbe = document.createElement('div');
170
- svgProbe.innerHTML = svgMarkup;
235
+ replaceChildrenFromHtml(svgProbe, svgMarkup);
171
236
  const svgElement = svgProbe.querySelector('svg');
172
237
 
173
238
  try {
@@ -291,11 +356,7 @@ async function fetchJson(url, init = {}) {
291
356
  },
292
357
  ...init,
293
358
  });
294
- const data = await response.json().catch(() => null);
295
- if (!response.ok) {
296
- throw new Error(data?.error || `Request failed: ${response.status}`);
297
- }
298
- return data;
359
+ return parseApiResponse(response, `Request failed: ${response.status}`);
299
360
  }
300
361
 
301
362
  async function fetchTextFile(filePath) {
@@ -638,7 +699,7 @@ function createDiagramFigureElement({
638
699
  if (svgMarkup) {
639
700
  const surface = document.createElement('div');
640
701
  surface.className = 'export-diagram-surface';
641
- surface.innerHTML = svgMarkup;
702
+ replaceChildrenFromHtml(surface, svgMarkup);
642
703
 
643
704
  const svgElement = surface.querySelector('svg');
644
705
  if (svgElement) {
@@ -678,7 +739,7 @@ async function ensureMermaidRuntime() {
678
739
  throw new Error('Mermaid runtime failed to initialize');
679
740
  }
680
741
 
681
- runtime.initialize(LIGHT_EXPORT_MERMAID_THEME);
742
+ runtime.initialize({ ...EXPORT_MERMAID_CONFIG, theme: 'default' });
682
743
  return runtime;
683
744
  });
684
745
 
@@ -708,7 +769,10 @@ function prepareMermaidSource(source) {
708
769
 
709
770
  async function renderMermaidToSvgMarkup(source) {
710
771
  const mermaid = await ensureMermaidRuntime();
711
- mermaid.initialize(LIGHT_EXPORT_MERMAID_THEME);
772
+ mermaid.initialize({
773
+ ...EXPORT_MERMAID_CONFIG,
774
+ theme: document.documentElement.dataset.theme === 'dark' ? 'dark' : 'default',
775
+ });
712
776
  const renderHost = document.createElement('div');
713
777
  renderHost.style.position = 'fixed';
714
778
  renderHost.style.left = '-10000px';
@@ -753,17 +817,7 @@ async function renderPlantUmlToSvgMarkup(source) {
753
817
  async function renderExcalidrawToSvgMarkup(filePath) {
754
818
  const rawScene = await fetchTextFile(filePath);
755
819
  const scene = parseSceneJson(rawScene);
756
- const initialData = sceneToInitialData(scene, { theme: 'light' });
757
- const svgElement = await exportExcalidrawToSvg({
758
- appState: {
759
- ...initialData.appState,
760
- exportBackground: true,
761
- exportWithDarkMode: false,
762
- },
763
- elements: initialData.elements.filter((element) => !element.isDeleted),
764
- exportPadding: 24,
765
- files: initialData.files || null,
766
- });
820
+ const svgElement = await exportExcalidrawToSvg(createExcalidrawExportOptions(scene));
767
821
  return normalizeExportSvgMarkup(svgElement.outerHTML, { padding: 24 });
768
822
  }
769
823
 
@@ -861,6 +915,97 @@ async function resolveDiagramShell(snapshot, shell, { label, prefix, render }) {
861
915
  }));
862
916
  }
863
917
 
918
+ function getBaseCellText(cell) {
919
+ if (cell?.text != null) {
920
+ return String(cell.text);
921
+ }
922
+ if (Array.isArray(cell?.value)) {
923
+ return cell.value.join(', ');
924
+ }
925
+ return cell?.value == null ? '' : String(cell.value);
926
+ }
927
+
928
+ async function resolveBaseEmbed(snapshot, placeholder) {
929
+ const response = await fetchJson(resolveApiUrl('/base/query'), {
930
+ body: JSON.stringify({
931
+ activeFilePath: snapshot.filePath,
932
+ path: placeholder.dataset.basePath || '',
933
+ search: '',
934
+ source: placeholder.dataset.baseSource || null,
935
+ sourcePath: placeholder.dataset.baseSourcePath || snapshot.filePath,
936
+ view: placeholder.dataset.baseView || '',
937
+ }),
938
+ headers: { 'Content-Type': 'application/json' },
939
+ method: 'POST',
940
+ });
941
+ const result = response.result;
942
+ if (!result || !Array.isArray(result.columns) || !Array.isArray(result.groups)) {
943
+ throw new Error('Base query returned no rendered view');
944
+ }
945
+
946
+ // ponytail: static tables preserve base data; share card/list renderers if those export layouts become necessary.
947
+ if (result.view?.type && result.view.type !== 'table') {
948
+ snapshot.warnings.push(`Base ${result.view.type} view exported as a static table`);
949
+ }
950
+
951
+ const shell = document.createElement('section');
952
+ shell.className = 'bases-shell bases-shell-static';
953
+ const toolbar = document.createElement('header');
954
+ toolbar.className = 'bases-toolbar';
955
+ const toolbarMain = document.createElement('div');
956
+ toolbarMain.className = 'bases-toolbar-main';
957
+ const title = document.createElement('strong');
958
+ title.textContent = result.view?.name || 'Base view';
959
+ const meta = document.createElement('div');
960
+ meta.className = 'bases-meta';
961
+ meta.textContent = `${result.totalRows ?? 0} results`;
962
+ toolbarMain.append(title, meta);
963
+ toolbar.appendChild(toolbarMain);
964
+ shell.appendChild(toolbar);
965
+
966
+ const content = document.createElement('div');
967
+ content.className = 'bases-content';
968
+ result.groups.forEach((group) => {
969
+ if (result.groups.length > 1) {
970
+ const heading = document.createElement('h3');
971
+ heading.textContent = group.label || group.key || 'Group';
972
+ content.appendChild(heading);
973
+ }
974
+ const tableShell = document.createElement('div');
975
+ tableShell.className = 'bases-table-shell';
976
+ const table = document.createElement('table');
977
+ table.className = 'bases-table';
978
+ const headRow = table.createTHead().insertRow();
979
+ result.columns.forEach((column) => {
980
+ const heading = document.createElement('th');
981
+ heading.scope = 'col';
982
+ heading.textContent = column.label || column.id || '';
983
+ headRow.appendChild(heading);
984
+ });
985
+ const body = table.createTBody();
986
+ (group.rows || []).forEach((row) => {
987
+ const tableRow = body.insertRow();
988
+ result.columns.forEach((column, columnIndex) => {
989
+ const cell = tableRow.insertCell();
990
+ const text = getBaseCellText(row.cells?.[column.id]);
991
+ if (columnIndex === 0 && row.path) {
992
+ const link = document.createElement('a');
993
+ link.href = buildWikiLinkHref(row.path);
994
+ link.dataset.wikiTarget = row.path;
995
+ link.textContent = text;
996
+ cell.appendChild(link);
997
+ } else {
998
+ cell.textContent = text;
999
+ }
1000
+ });
1001
+ });
1002
+ tableShell.appendChild(table);
1003
+ content.appendChild(tableShell);
1004
+ });
1005
+ shell.appendChild(content);
1006
+ placeholder.replaceWith(shell);
1007
+ }
1008
+
864
1009
  async function resolveExcalidrawEmbed(snapshot, placeholder) {
865
1010
  const target = String(placeholder.dataset.embedTarget ?? '').trim();
866
1011
  if (!target) {
@@ -1026,6 +1171,20 @@ export async function resolveExportAssets(snapshot, {
1026
1171
  }
1027
1172
  }
1028
1173
 
1174
+ const baseEmbeds = Array.from(container.querySelectorAll('.bases-embed-placeholder[data-base-key]'));
1175
+ for (const placeholder of baseEmbeds) {
1176
+ try {
1177
+ await resolveBaseEmbed(snapshot, placeholder);
1178
+ } catch (error) {
1179
+ const message = error instanceof Error ? error.message : 'Unknown error';
1180
+ snapshot.warnings.push(`Base export failed: ${message}`);
1181
+ placeholder.replaceWith(Object.assign(document.createElement('p'), {
1182
+ className: 'export-warning',
1183
+ textContent: `Base export failed: ${message}`,
1184
+ }));
1185
+ }
1186
+ }
1187
+
1029
1188
  const excalidrawEmbeds = Array.from(container.querySelectorAll('.excalidraw-embed-placeholder[data-embed-key]'));
1030
1189
  for (const placeholder of excalidrawEmbeds) {
1031
1190
  try {
@@ -1057,9 +1216,11 @@ export async function resolveExportAssets(snapshot, {
1057
1216
  }
1058
1217
 
1059
1218
  export async function prepareExportSnapshot({
1219
+ directoryFileList = [],
1060
1220
  fileList = [],
1061
1221
  filePath,
1062
1222
  markdownText = '',
1223
+ theme = 'light',
1063
1224
  title = '',
1064
1225
  } = {}) {
1065
1226
  const normalizedFilePath = String(filePath ?? '').trim();
@@ -1070,6 +1231,7 @@ export async function prepareExportSnapshot({
1070
1231
  generatedAt: new Date().toISOString(),
1071
1232
  html: '',
1072
1233
  sourceMarkdown: normalizedMarkdown,
1234
+ theme: normalizeExportTheme(theme),
1073
1235
  title: createDocumentTitle(normalizedFilePath, title),
1074
1236
  warnings: [],
1075
1237
  };
@@ -1082,13 +1244,78 @@ export async function prepareExportSnapshot({
1082
1244
  });
1083
1245
  const container = document.createElement('div');
1084
1246
  container.className = 'preview-content export-content';
1085
- container.innerHTML = compiled.html;
1247
+ replaceChildrenFromHtml(container, compiled.html);
1086
1248
 
1087
1249
  await resolveExportAssets(snapshot, { container });
1250
+ if (directoryFileList.length > 0) {
1251
+ rewriteDirectoryDocumentLinks(container, {
1252
+ fileList: directoryFileList,
1253
+ sourceFilePath: normalizedFilePath,
1254
+ });
1255
+ }
1088
1256
  snapshot.html = container.innerHTML;
1089
1257
  return snapshot;
1090
1258
  }
1091
1259
 
1260
+ export async function prepareDirectoryExportSnapshot({
1261
+ currentFilePath = '',
1262
+ currentMarkdownText = '',
1263
+ directoryPath,
1264
+ fileList = [],
1265
+ theme = 'light',
1266
+ } = {}) {
1267
+ const normalizedDirectoryPath = String(directoryPath ?? '').replace(/\\/gu, '/').replace(/^\/+|\/+$/gu, '').trim();
1268
+ const directoryPrefix = `${normalizedDirectoryPath}/`;
1269
+ const markdownPaths = fileList
1270
+ .filter((filePath) => isMarkdownFilePath(filePath) && String(filePath).startsWith(directoryPrefix))
1271
+ .sort((left, right) => left.localeCompare(right, undefined, { sensitivity: 'base' }));
1272
+ if (markdownPaths.length === 0) {
1273
+ throw new Error('The selected folder contains no markdown notes');
1274
+ }
1275
+
1276
+ const documents = [];
1277
+ const warnings = [];
1278
+ for (const filePath of markdownPaths) {
1279
+ const markdownText = filePath === currentFilePath
1280
+ ? String(currentMarkdownText ?? '')
1281
+ : await fetchTextFile(filePath);
1282
+ const documentSnapshot = await prepareExportSnapshot({
1283
+ directoryFileList: markdownPaths,
1284
+ fileList,
1285
+ filePath,
1286
+ markdownText,
1287
+ theme,
1288
+ });
1289
+ warnings.push(...documentSnapshot.warnings.map((warning) => `${filePath}: ${warning}`));
1290
+ documents.push(documentSnapshot);
1291
+ }
1292
+
1293
+ const title = createDocumentTitle(normalizedDirectoryPath);
1294
+ const tableOfContents = documents.map((documentSnapshot) => (
1295
+ `<li><a href="#${createDocumentAnchorId(documentSnapshot.filePath)}">${escapeHtml(documentSnapshot.filePath)}</a></li>`
1296
+ )).join('');
1297
+ const html = [
1298
+ `<nav class="export-directory-toc" aria-label="Exported notes"><h1>${escapeHtml(title)}</h1><ol>${tableOfContents}</ol></nav>`,
1299
+ ...documents.map((documentSnapshot) => [
1300
+ `<section class="export-document-section" id="${createDocumentAnchorId(documentSnapshot.filePath)}">`,
1301
+ `<header class="export-document-heading"><h1>${escapeHtml(documentSnapshot.title)}</h1><p>${escapeHtml(documentSnapshot.filePath)}</p></header>`,
1302
+ documentSnapshot.html,
1303
+ '</section>',
1304
+ ].join('')),
1305
+ ].join('');
1306
+
1307
+ return {
1308
+ assets: {},
1309
+ filePath: normalizedDirectoryPath,
1310
+ generatedAt: new Date().toISOString(),
1311
+ html,
1312
+ sourceMarkdown: '',
1313
+ theme: normalizeExportTheme(theme),
1314
+ title,
1315
+ warnings,
1316
+ };
1317
+ }
1318
+
1092
1319
  function applyDocxTableStyles(table, {
1093
1320
  borderColor = '#d1d5db',
1094
1321
  cellPadding = '8px 10px',
@@ -1224,12 +1451,7 @@ function createDocxCodeBlockTable(pre) {
1224
1451
  paragraph.style.color = '#111827';
1225
1452
 
1226
1453
  const text = (line || '').replace(/\t/g, ' ');
1227
- if (!text) {
1228
- paragraph.innerHTML = '&nbsp;';
1229
- } else {
1230
- paragraph.textContent = text;
1231
- paragraph.innerHTML = paragraph.innerHTML.replace(/ /g, '&nbsp;');
1232
- }
1454
+ paragraph.textContent = text ? text.replace(/ /gu, '\u00a0') : '\u00a0';
1233
1455
 
1234
1456
  contentNodes.push(paragraph);
1235
1457
  });
@@ -1244,7 +1466,7 @@ function createDocxCodeBlockTable(pre) {
1244
1466
 
1245
1467
  export function buildDocxHtmlDocument(snapshot) {
1246
1468
  const template = document.createElement('template');
1247
- template.innerHTML = snapshot.html;
1469
+ replaceChildrenFromHtml(template.content, snapshot.html);
1248
1470
 
1249
1471
  Array.from(template.content.querySelectorAll('.table-wrapper')).forEach((wrapper) => {
1250
1472
  const table = wrapper.querySelector(':scope > table');
@@ -1411,20 +1633,21 @@ export function buildDocxHtmlDocument(snapshot) {
1411
1633
 
1412
1634
  export function buildHtmlDocument(snapshot) {
1413
1635
  const template = document.createElement('template');
1414
- template.innerHTML = snapshot.html;
1636
+ replaceChildrenFromHtml(template.content, snapshot.html);
1415
1637
  Array.from(template.content.querySelectorAll('[data-export-docx-src]')).forEach((element) => {
1416
1638
  element.removeAttribute('data-export-docx-src');
1417
1639
  });
1418
1640
 
1641
+ const theme = normalizeExportTheme(snapshot.theme);
1419
1642
  return `<!DOCTYPE html>
1420
- <html lang="en" data-theme="light">
1643
+ <html lang="en" data-theme="${theme}">
1421
1644
  <head>
1422
1645
  <meta charset="UTF-8">
1423
1646
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1424
1647
  <title>${escapeHtml(snapshot.title)}</title>
1425
1648
  <style>${HTML_EXPORT_STYLES.replace(/<\/style/giu, '<\\/style')}</style>
1426
1649
  </head>
1427
- <body data-theme="light">
1650
+ <body data-theme="${theme}">
1428
1651
  <main class="export-page-shell">
1429
1652
  <article class="preview-content export-content">${template.innerHTML}</article>
1430
1653
  </main>
@@ -1535,11 +1758,11 @@ export function postExportPageMessage(type, payload = {}) {
1535
1758
  }
1536
1759
 
1537
1760
  export async function waitForBootstrapPayload() {
1538
- const requestUrl = new URL(window.location.href);
1539
- const requestedAction = requestUrl.searchParams.get('action');
1761
+ const searchParams = new URLSearchParams(window.location.search);
1762
+ const requestedAction = searchParams.get('action');
1540
1763
  const action = ['html', 'pdf'].includes(requestedAction) ? requestedAction : 'docx';
1541
- const filePath = requestUrl.searchParams.get('file') || '';
1542
- const jobId = requestUrl.searchParams.get('job') || '';
1764
+ const filePath = searchParams.get('file') || '';
1765
+ const jobId = searchParams.get('job') || window.name || '';
1543
1766
 
1544
1767
  if (jobId && window.opener && !window.opener.closed) {
1545
1768
  postExportPageMessage('ready', { jobId });
@@ -1567,11 +1790,15 @@ export async function waitForBootstrapPayload() {
1567
1790
 
1568
1791
  cleanup();
1569
1792
  resolve({
1570
- action,
1793
+ action: ['html', 'pdf'].includes(payload.action) ? payload.action : action,
1794
+ currentFilePath: payload.currentFilePath || '',
1795
+ currentMarkdownText: payload.currentMarkdownText || '',
1796
+ directoryPath: payload.directoryPath || '',
1571
1797
  fileList: Array.isArray(payload.fileList) ? payload.fileList : [],
1572
1798
  filePath: payload.filePath || filePath,
1573
- title: payload.title || '',
1574
1799
  markdownText: payload.markdownText || '',
1800
+ theme: normalizeExportTheme(payload.theme),
1801
+ title: payload.title || '',
1575
1802
  });
1576
1803
  };
1577
1804
 
@@ -1584,6 +1811,7 @@ export async function waitForBootstrapPayload() {
1584
1811
  fileList: [],
1585
1812
  filePath,
1586
1813
  markdownText: filePath ? await fetchTextFile(filePath) : '',
1814
+ theme: 'light',
1587
1815
  title: '',
1588
1816
  };
1589
1817
  }
@@ -0,0 +1,23 @@
1
+ import { resolveApiUrl } from '../domain/runtime-paths.js';
2
+ import { parseApiResponse } from './api-client-utils.js';
3
+
4
+ export const agentConnectionApiClient = {
5
+ listConnections() {
6
+ return fetch(resolveApiUrl('/agent/connections'))
7
+ .then((response) => parseApiResponse(response, 'Failed to load Agent Connections'));
8
+ },
9
+
10
+ createConnection(payload) {
11
+ return fetch(resolveApiUrl('/agent/connections'), {
12
+ body: JSON.stringify(payload),
13
+ headers: { 'Content-Type': 'application/json' },
14
+ method: 'POST',
15
+ }).then((response) => parseApiResponse(response, 'Failed to create Agent Connection'));
16
+ },
17
+
18
+ revokeConnection(connectionId) {
19
+ return fetch(resolveApiUrl(`/agent/connections/${encodeURIComponent(connectionId)}`), {
20
+ method: 'DELETE',
21
+ }).then((response) => parseApiResponse(response, 'Failed to revoke Agent Connection'));
22
+ },
23
+ };
@@ -1,6 +1,7 @@
1
1
  import '../styles/features/auth-gate.css';
2
2
 
3
3
  import { getHashParamsFromRaw } from '../domain/hash-routes.js';
4
+ import { parseApiResponse } from './api-client-utils.js';
4
5
  import { getRuntimeConfig } from './runtime-config.js';
5
6
 
6
7
  const DEFAULT_AUTH_CONFIG = {
@@ -66,12 +67,7 @@ async function fetchAuthStatus(config) {
66
67
  },
67
68
  });
68
69
 
69
- const payload = await response.json().catch(() => ({}));
70
- if (!response.ok) {
71
- throw new Error(payload.error || 'Failed to read auth status');
72
- }
73
-
74
- return payload;
70
+ return parseApiResponse(response, 'Failed to read auth status');
75
71
  }
76
72
 
77
73
  function syncOidcIdentityToLocalState(status) {
@@ -100,13 +96,7 @@ async function submitPassword(config, password) {
100
96
  },
101
97
  body: JSON.stringify({ password }),
102
98
  });
103
- const payload = await response.json().catch(() => ({}));
104
-
105
- if (!response.ok) {
106
- throw new Error(payload.error || 'Authentication failed');
107
- }
108
-
109
- return payload;
99
+ return parseApiResponse(response, 'Authentication failed');
110
100
  }
111
101
 
112
102
  function createOverlayShell() {
@@ -274,6 +274,10 @@ export class EditorSession {
274
274
  this.viewAdapter.requestMeasure();
275
275
  }
276
276
 
277
+ formatDocument(filePath) {
278
+ return this.viewAdapter.formatDocument(filePath);
279
+ }
280
+
277
281
  runEditorCommand(commandId) {
278
282
  return this.viewAdapter.runEditorCommand(commandId);
279
283
  }
@@ -286,6 +290,13 @@ export class EditorSession {
286
290
  return this.viewAdapter.insertText(text);
287
291
  }
288
292
 
293
+ applyTextReplacements(replacements) {
294
+ if (!this.collaborationClient.initialSyncComplete) {
295
+ throw new Error('The collaborative document is not synchronized');
296
+ }
297
+ return this.viewAdapter.applyTextReplacements(replacements);
298
+ }
299
+
289
300
  replaceText(text) {
290
301
  return this.viewAdapter.replaceText(text);
291
302
  }
@@ -302,6 +313,10 @@ export class EditorSession {
302
313
  return this.viewAdapter.flashRemoteRange(range);
303
314
  }
304
315
 
316
+ isInitialSyncComplete() {
317
+ return this.collaborationClient.initialSyncComplete;
318
+ }
319
+
305
320
  waitForInitialSync(timeoutMs = 1500) {
306
321
  return this.collaborationClient.waitForInitialSync(timeoutMs);
307
322
  }