collabmd 0.1.46 → 0.1.48

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 (317) hide show
  1. package/README.md +9 -5
  2. package/dist/client/assets/{CodeMirrorEditor-UCMRAMCV-CYM5nxUi.js → CodeMirrorEditor-UCMRAMCV-BPH4FJkv.js} +1 -1
  3. package/dist/client/assets/JetBrainsMono-Regular-BQaDgvhP.woff2 +0 -0
  4. package/dist/client/assets/{abnfDiagram-N423BO3Z-CUMTFJhI.js → abnfDiagram-VCTEODGH-BNDLzJ7L.js} +1 -1
  5. package/dist/client/assets/architecture-7GRP2DOG-BMOPAkUC.js +1 -0
  6. package/dist/client/assets/{architectureDiagram-T3A2C74G-w25m71oV.js → architectureDiagram-5GKGNRK7-I39sYjHI.js} +1 -1
  7. package/dist/client/assets/babel-CY5KOv-I.js +16 -0
  8. package/dist/client/assets/base-BYODPHdS.js +1 -0
  9. package/dist/client/assets/blockDiagram-NRAW4CY4-C6DtJy5Y.js +129 -0
  10. package/dist/client/assets/browser-BKLM0ThC-IxjwuOIz-BBqQnUEb.js +1 -0
  11. package/dist/client/assets/c4Diagram-UCG6FXSJ-CtWtxS9_.js +38 -0
  12. package/dist/client/assets/channel-CaoKA_We.js +1 -0
  13. package/dist/client/assets/{chunk-U6XO7XAA-BFxjP5U3.js → chunk-2ZTRR5NV-C2qZJila.js} +1 -1
  14. package/dist/client/assets/{chunk-YOTPTUD7-D0vRKqYp.js → chunk-3Z5EZCMW-DMniOlPd.js} +1 -1
  15. package/dist/client/assets/{chunk-BIQX33UG-DZEsGuSn.js → chunk-5V3GS4D5-i-ZDOEnP.js} +1 -1
  16. package/dist/client/assets/{chunk-MOZMSUNE-XVucA-n6.js → chunk-6AZGARVD-BB6FqMl-.js} +1 -1
  17. package/dist/client/assets/{chunk-5JV3BV7I-Cy5pj3QY.js → chunk-6EIED4P4-DdUJkP0f.js} +1 -1
  18. package/dist/client/assets/{chunk-R7FJI6CG-Cnn3gE-Y.js → chunk-6K3QC6MW-CqVsVn-y.js} +1 -1
  19. package/dist/client/assets/{chunk-OSBZ3O6U-CrKZOUOr.js → chunk-6TQVIW2G-DKlLbNIP.js} +1 -1
  20. package/dist/client/assets/{chunk-JG7HCLWE-BYfiSaVt.js → chunk-747NJXEK-BFkZPlab.js} +1 -1
  21. package/dist/client/assets/{chunk-NSK5VX7P-TLH37VXI.js → chunk-75Z2AOVW-CdFSaPjz.js} +1 -1
  22. package/dist/client/assets/chunk-CKBBP62Z-DG26UiBv.js +2 -0
  23. package/dist/client/assets/{chunk-3NCLNEKW-Y2Jf_LI-.js → chunk-CLGD4ZFX-DQLgbQrv.js} +1 -1
  24. package/dist/client/assets/chunk-DSNCTWBM-8xkug7fQ.js +2 -0
  25. package/dist/client/assets/chunk-DU6HZSFF-COXDzJK1.js +127 -0
  26. package/dist/client/assets/{chunk-2GRJ4B5K-DhnlUv3F.js → chunk-F27PBJKO-CNHIFhjo.js} +1 -1
  27. package/dist/client/assets/{chunk-YGJVY4SA-CjSe7Bx7.js → chunk-FLYJHZSQ-Be7lKF17.js} +1 -1
  28. package/dist/client/assets/{chunk-KEIR6QF5-BICK3FdT.js → chunk-FOHPRMQF-DHwB1DNv.js} +2 -2
  29. package/dist/client/assets/{chunk-5RXB4S5H-BWrwFqMI.js → chunk-G27WJ6UU-D9-eg537.js} +2 -2
  30. package/dist/client/assets/chunk-GMAD6QVW-CbcBqPM5.js +72 -0
  31. package/dist/client/assets/{chunk-QBLGF6JB-CxAyS2mW.js → chunk-I5DQTOEV-Hm2LfiYI.js} +1 -1
  32. package/dist/client/assets/{chunk-5FCAYU7R-Dh5nylU8.js → chunk-ICYGCRZG-749o-pGJ.js} +1 -1
  33. package/dist/client/assets/{chunk-CQNSW5MT-B8S09OIh.js → chunk-IH6LHLGP-CC6I9F3i.js} +1 -1
  34. package/dist/client/assets/chunk-JQ64N6SF-DSFNH4bh.js +1 -0
  35. package/dist/client/assets/{chunk-CYSBUYHQ-C1Rf4art.js → chunk-KI3K4JFJ-Rma-0k_M.js} +1 -1
  36. package/dist/client/assets/{chunk-GF5L2VYU-DkJpO7ff.js → chunk-LCL6LL3I-DmDkVukh.js} +1 -1
  37. package/dist/client/assets/chunk-LNGE3PJU-DWpGwHrW.js +34 -0
  38. package/dist/client/assets/chunk-OBVCFTLP-BJR7u1jh.js +1 -0
  39. package/dist/client/assets/{chunk-5TONJI2A-DQOY3q1H.js → chunk-OUJLGHUK-D0j2JRSg.js} +1 -1
  40. package/dist/client/assets/chunk-P2QGCYS3-BRpqY32H.js +1 -0
  41. package/dist/client/assets/{chunk-KBJHAD2P-CB_3zWUf.js → chunk-POPQ4Y6H-Cb4SlVZF.js} +1 -1
  42. package/dist/client/assets/{chunk-4I5QYGJK-CCB2YcIH.js → chunk-PWAF6VOD-Cz8IwBB5.js} +1 -1
  43. package/dist/client/assets/chunk-R7TYR2AO-CTd0Yj98.js +10 -0
  44. package/dist/client/assets/chunk-RHFEMEQ7-CWY8cf4H.js +168 -0
  45. package/dist/client/assets/chunk-RM4UPSZO-CWRwxNWJ.js +41 -0
  46. package/dist/client/assets/{chunk-6Q2QTUOP-CPlWzBtc.js → chunk-SVP7TREG-CyHOmcac.js} +1 -1
  47. package/dist/client/assets/chunk-TEH6E4GO-DVayPj-q.js +62 -0
  48. package/dist/client/assets/{chunk-EMLP6XTP-RLD4nXpI.js → chunk-UY3FDG6J-CnmaAkG5.js} +1 -1
  49. package/dist/client/assets/{chunk-5HE753X5-Bw-yg4kO.js → chunk-XHIXRSVI-BFQ6B8BE.js} +1 -1
  50. package/dist/client/assets/classDiagram-DTDB5LWJ-7fEmn0zV.js +1 -0
  51. package/dist/client/assets/classDiagram-v2-JRS7N3AN-7fEmn0zV.js +1 -0
  52. package/dist/client/assets/comment-ui-shared-DuoyznXW.js +7 -0
  53. package/dist/client/assets/cynefin-OW5HDTMX-7tP7QfM3.js +1 -0
  54. package/dist/client/assets/{cynefinDiagram-MW4NZA55-CJxXfJek.js → cynefinDiagram-5FMLGOSQ-CdTPi2yO.js} +1 -1
  55. package/dist/client/assets/dagre-3AP2YEHR-5gtJtd0O.js +4 -0
  56. package/dist/client/assets/dagre-PrKaheQc.js +1 -0
  57. package/dist/client/assets/{diagram-7IWD3JNH-B2d2Bm15.js → diagram-S7CK7UJ4-BudWz9WU.js} +4 -4
  58. package/dist/client/assets/{diagram-UB23O5K3-DJcKCwv9.js → diagram-UQ7AKVKN-3v4rbH-s.js} +1 -1
  59. package/dist/client/assets/{diagram-B4RE2ZJO-NP4UAwjR.js → diagram-VSXAHHWV-CQRVEZR7.js} +1 -1
  60. package/dist/client/assets/{diagram-Q27KOJAE-DylDuwor.js → diagram-VX7I27RA-C_-rj0sw.js} +1 -1
  61. package/dist/client/assets/{diagram-LBJQPF4R-D1FJQV8t.js → diagram-Z3DM3KII-B4yxavgj.js} +1 -1
  62. package/dist/client/assets/direct-engine-DdrQKpgq-CtKfQzCt.js +5 -0
  63. package/dist/client/assets/dist-73RPdcyU.js +1 -0
  64. package/dist/client/assets/{dist-Bm6pf9Bl.js → dist-BJ1bJs33.js} +1 -1
  65. package/dist/client/assets/{dist-BalScOwZ.js → dist-BK9QvQrc.js} +1 -1
  66. package/dist/client/assets/{dist-DLMiIsNC.js → dist-BPHLJ09L.js} +1 -1
  67. package/dist/client/assets/{dist-Bf8f4HmM.js → dist-B_yQaEv_.js} +1 -1
  68. package/dist/client/assets/{dist-CC5IrQMG.js → dist-BeajGMhO.js} +1 -1
  69. package/dist/client/assets/{dist-PDZ3bSqm.js → dist-Bw3VIE_v.js} +1 -1
  70. package/dist/client/assets/{dist-xElaxbia.js → dist-ByrG2qBA.js} +1 -1
  71. package/dist/client/assets/{dist-ule2n6ak.js → dist-C5NgpdG5.js} +1 -1
  72. package/dist/client/assets/dist-CH-sQu3r.js +1 -0
  73. package/dist/client/assets/dist-CKS_-are.js +1 -0
  74. package/dist/client/assets/{dist-D-Z6FLem.js → dist-CdmKGRGr.js} +1 -1
  75. package/dist/client/assets/dist-ChRoo3IB.js +9 -0
  76. package/dist/client/assets/{dist-dtAdgL39.js → dist-CietwTVS.js} +1 -1
  77. package/dist/client/assets/{dist-jv4WdPnK.js → dist-D37Hyu3h.js} +1 -1
  78. package/dist/client/assets/dist-D3fehAZ2.js +2 -0
  79. package/dist/client/assets/{dist-BEwK4csK.js → dist-D5wCC32z.js} +1 -1
  80. package/dist/client/assets/{dist-shrl6K_0.js → dist-DDUn5zTz.js} +1 -1
  81. package/dist/client/assets/{dist-CZgOmxK6.js → dist-DGEbEfw4.js} +1 -1
  82. package/dist/client/assets/{dist-B5HTH2BO.js → dist-DVy5woUy.js} +1 -1
  83. package/dist/client/assets/{dist-DZKu9Cs8.js → dist-DZAAWTG-.js} +1 -1
  84. package/dist/client/assets/{dist-TjMh8n1u.js → dist-Dir5dDKZ.js} +1 -1
  85. package/dist/client/assets/dist-Dl_tpDSr.js +1 -0
  86. package/dist/client/assets/{dist-FWJsgGYI.js → dist-DuH3ZrHo.js} +1 -1
  87. package/dist/client/assets/{dist-BjHJDtyU.js → dist-DutPuFmC.js} +1 -1
  88. package/dist/client/assets/{dist-Cqhv5LAk.js → dist-LQ4kDCKz.js} +1 -1
  89. package/dist/client/assets/{dist-CCP_AKPG.js → dist-RKBTaQMb.js} +1 -1
  90. package/dist/client/assets/{dist-BoVBdSjk.js → dist-Tw-Fxpeb.js} +1 -1
  91. package/dist/client/assets/dist-eBx8q6Sy.js +1 -0
  92. package/dist/client/assets/{dist-rGBmqxC7.js → dist-mj2Ht75J.js} +1 -1
  93. package/dist/client/assets/{dist-BDt3rz7l.js → dist-netZOQtD.js} +1 -1
  94. package/dist/client/assets/document-formatter-Dxl_a8XO.js +2 -0
  95. package/dist/client/assets/{drawio-editor-FzY1cVw8.js → drawio-editor-BVaNNtYp.js} +2 -2
  96. package/dist/client/assets/{drawioEditor-BjiKJqlc.js → drawioEditor-BkIBlXx0.js} +2 -2
  97. package/dist/client/assets/{ebnfDiagram-BXEA7PRR-nw0wmA6y.js → ebnfDiagram-PWID7BFC-OXa8VEp1.js} +1 -1
  98. package/dist/client/assets/editor-session-DMyVdHLj.js +54 -0
  99. package/dist/client/assets/embedded-editor-base-B3l6Xy65.css +1 -0
  100. package/dist/client/assets/embedpdf-BmE13ZZ0.js +1 -0
  101. package/dist/client/assets/embedpdf-DA4bA119-BPqZxwjc.js +2363 -0
  102. package/dist/client/assets/{en-7NFCYGKX-BrgYZAEe.js → en-SJ2YIMFF-CJBL3nkq.js} +1 -1
  103. package/dist/client/assets/erDiagram-SSCWMZ5O-C-iy6VkX.js +99 -0
  104. package/dist/client/assets/estree-CuT_pB8K.js +44 -0
  105. package/dist/client/assets/eventmodeling-NTZA5JFV-BR2FzK4R.js +1 -0
  106. package/dist/client/assets/excalidraw-editor-BbSbI80a.css +1 -0
  107. package/dist/client/assets/excalidraw-editor-BjYaNEMY.js +9 -0
  108. package/dist/client/assets/excalidrawEditor-ChqF_d82.js +2 -0
  109. package/dist/client/assets/export-page-Dyu0XCbu.js +57 -0
  110. package/dist/client/assets/exportDocument-CJBx4Xjx.css +1 -0
  111. package/dist/client/assets/exportDocument-Dgvfa2Sd.js +2 -0
  112. package/dist/client/assets/{file-icon-svg-CQAjlWjK.js → file-icon-svg-Y_kpF957.js} +1 -1
  113. package/dist/client/assets/file-kind-BwMIcZbi.js +1 -0
  114. package/dist/client/assets/file-search-DDLyyLDU.js +1 -0
  115. package/dist/client/assets/flowDiagram-A5DVABFB-CiW1eN8C.js +1 -0
  116. package/dist/client/assets/{ganttDiagram-PKOTCBZU-BnM97BCT.js → ganttDiagram-EL5Y4UJY-DtKHAbez.js} +1 -1
  117. package/dist/client/assets/gitGraph-4MIJSDKK-DYlXv_yJ.js +1 -0
  118. package/dist/client/assets/{gitGraphDiagram-DS77QQ5N-BQpQhjuN.js → gitGraphDiagram-WWUBYQGX-oue8fQ5o.js} +1 -1
  119. package/dist/client/assets/github-dark.min-BV82VuKq.css +1 -0
  120. package/dist/client/assets/github.min-v3dd8CNH.css +1 -0
  121. package/dist/client/assets/html-Cdnr2qzU.js +25 -0
  122. package/dist/client/assets/image-ZVKINSPA-0zXSnE7M.js +1 -0
  123. package/dist/client/assets/index-CSNIMyOP.css +1 -0
  124. package/dist/client/assets/index-DG3N2Ps-.js +2 -0
  125. package/dist/client/assets/info-A6RAGUB7-BlU-8_xu.js +1 -0
  126. package/dist/client/assets/{infoDiagram-6WML65LV-DYB8HCDQ.js → infoDiagram-RXCK75RN-BMzo6KIn.js} +1 -1
  127. package/dist/client/assets/{ishikawaDiagram-WSZJBQD7-Coz_P3t6.js → ishikawaDiagram-5VMMS53U-BIM3h287.js} +1 -1
  128. package/dist/client/assets/{journeyDiagram-NVQOT4AX-B6edChce.js → journeyDiagram-EYS64GPL-mF6Lh8O-.js} +1 -1
  129. package/dist/client/assets/{kanban-definition-27J2QSJJ-BFd9-cLc.js → kanban-definition-3QL26DDD-DLN2NyoR.js} +2 -2
  130. package/dist/client/assets/{line-B_S_S8kV.js → line-BfTWJmgf.js} +1 -1
  131. package/dist/client/assets/main-D0wCxpVn.js +903 -0
  132. package/dist/client/assets/markdown-CByV-4CU.js +70 -0
  133. package/dist/client/assets/{mermaid-parser.core-CUVdebAV.js → mermaid-parser.core-Bl0efOMt.js} +2 -2
  134. package/dist/client/assets/mermaid.core-BJRLUQZE.js +11 -0
  135. package/dist/client/assets/{mindmap-definition-FAOFIHXS-C9PQ38Al.js → mindmap-definition-FBJOCRG2-CRyHaHTk.js} +1 -1
  136. package/dist/client/assets/packet-AYTQ26CC-BSJEH9Lb.js +1 -0
  137. package/dist/client/assets/pdfium-RAgkpwfK.wasm +0 -0
  138. package/dist/client/assets/{pegDiagram-VL7TDLO6-BMZUrSaU.js → pegDiagram-XKGWAZYB-B31fKPR2.js} +1 -1
  139. package/dist/client/assets/pie-WAS4IAKB-qxv01Y8W.js +1 -0
  140. package/dist/client/assets/{pieDiagram-7S7Q4E2Y-h8kbCL9o.js → pieDiagram-E7YTZNPT-B5OZPb88.js} +1 -1
  141. package/dist/client/assets/preview-render-compiler-CrJIooVD.js +35 -0
  142. package/dist/client/assets/preview-render-compiler-O0JxBVNF.js +1 -0
  143. package/dist/client/assets/{preview-render-profile-CE-5rVTC.js → preview-render-profile-B4RWYWHt.js} +1 -1
  144. package/dist/client/assets/preview-render-worker-_QTxqKvP.js +60 -0
  145. package/dist/client/assets/prod-BiYPMR1i.js +177 -0
  146. package/dist/client/assets/prod-VxdGZ5Ly.js +1 -0
  147. package/dist/client/assets/{quadrantDiagram-CIZ2JOQS-CkElyfMi.js → quadrantDiagram-AXDQQJYC-Drrw14YH.js} +1 -1
  148. package/dist/client/assets/quick-switcher-controller-CaEjEtq_.js +1 -0
  149. package/dist/client/assets/radar-RG4KPBEZ-B6h6pWOs.js +1 -0
  150. package/dist/client/assets/railroad-74A4TZTK-CGtTWdGc.js +1 -0
  151. package/dist/client/assets/railroad-abnf-HS5TGJTU-Cq7y22IA.js +1 -0
  152. package/dist/client/assets/railroad-ebnf-LZEXJU2U-V0aQVv9m.js +1 -0
  153. package/dist/client/assets/railroad-peg-WCYAUIDC-BQiIsX_p.js +1 -0
  154. package/dist/client/assets/{railroadDiagram-AXF67PYL-c75gnikD.js → railroadDiagram-O6MQD6OU-BPifP0MB.js} +1 -1
  155. package/dist/client/assets/{requirementDiagram-LRYGKXZP-mNxKLuHS.js → requirementDiagram-EFPCY7ZU-CRZG6mRB.js} +2 -2
  156. package/dist/client/assets/{sankeyDiagram-W5VNT64P-0OhplksI.js → sankeyDiagram-P5KCCOFB-DvarEJpo.js} +1 -1
  157. package/dist/client/assets/{sequenceDiagram-SI44F4Z6-BJ_yAocC.js → sequenceDiagram-WJ2MYXX4-B4oWlb-w.js} +1 -1
  158. package/dist/client/assets/standalone-6z5x8CWe.js +29 -0
  159. package/dist/client/assets/{stateDiagram-OKZ733FA-Cc83O86s.js → stateDiagram-HBIQ2CUA-qbHIIqRZ.js} +1 -1
  160. package/dist/client/assets/stateDiagram-v2-4QOOHH4V-B--gjrit.js +1 -0
  161. package/dist/client/assets/swimlanes-XN3QIQJK-xB6CtUGj.js +1 -0
  162. package/dist/client/assets/swimlanesDiagram-VK2B7HYN-DO8XNXEg.js +8 -0
  163. package/dist/client/assets/{timeline-definition-Z64GVDOM-BWDAGTHz.js → timeline-definition-24CTP7MA-Lj_yTNlY.js} +1 -1
  164. package/dist/client/assets/treeView-Q6P3EWNA-BTTYcvrF.js +1 -0
  165. package/dist/client/assets/treemap-WGGIJYW6-Cg7tyfH8.js +1 -0
  166. package/dist/client/assets/{vault-api-client-_LpV1aIn.js → vault-api-client-BkwdFjx0.js} +2 -2
  167. package/dist/client/assets/vault-utils-DvoSftJT.js +22 -0
  168. package/dist/client/assets/{vennDiagram-T6HMQDX7-LOSsnlMB.js → vennDiagram-4TSXK5OY-BekRp5Y0.js} +1 -1
  169. package/dist/client/assets/wardley-WFR3VGLG-C6N1rULY.js +1 -0
  170. package/dist/client/assets/{wardleyDiagram-T6FBY63Y-BxII3foY.js → wardleyDiagram-VM6X3IG4-kdnV_Hdm.js} +1 -1
  171. package/dist/client/assets/worker-engine-m0rlHn8R-S8mpn_O0.js +17369 -0
  172. package/dist/client/assets/{xychartDiagram-ELKLHX3M-B-pTEjju.js → xychartDiagram-S5SC5T6Z-DufGwNSB.js} +3 -3
  173. package/dist/client/assets/yaml-9ltHPDNO.js +154 -0
  174. package/dist/client/drawio-editor.html +1 -1
  175. package/dist/client/excalidraw-editor.html +1 -1
  176. package/dist/client/export-document.html +3 -3
  177. package/dist/client/index.html +56 -24
  178. package/package.json +22 -18
  179. package/src/client/app/index.html +53 -21
  180. package/src/client/application/app-shell/comments-feature.js +2 -3
  181. package/src/client/application/app-shell/export-feature.js +17 -1
  182. package/src/client/application/app-shell/git-feature.js +30 -11
  183. package/src/client/application/app-shell/presence-feature.js +2 -2
  184. package/src/client/application/app-shell/ui-feature-identity.js +13 -0
  185. package/src/client/application/app-shell/ui-feature-shell.js +228 -9
  186. package/src/client/application/app-shell-elements.js +5 -0
  187. package/src/client/application/pdf-preview-controller.js +53 -970
  188. package/src/client/application/preview-render-compiler.js +3 -0
  189. package/src/client/application/quick-switcher-loader.js +1 -1
  190. package/src/client/application/workspace-coordinator.js +21 -4
  191. package/src/client/application/workspace-preview-controller.js +120 -5
  192. package/src/client/application/workspace-route-controller.js +4 -1
  193. package/src/client/assets/vendor/highlight/github-dark.min.css +2 -10
  194. package/src/client/assets/vendor/highlight/github.min.css +2 -10
  195. package/src/client/assets/vendor/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
  196. package/src/client/assets/vendor/jetbrains-mono/OFL.txt +93 -0
  197. package/src/client/bootstrap/collabmd-app-shell.js +31 -8
  198. package/src/client/domain/document-formatter.js +193 -0
  199. package/src/client/domain/file-search.js +73 -0
  200. package/src/client/domain/git-labels.js +5 -0
  201. package/src/client/domain/vault-paths.js +6 -4
  202. package/src/client/domain/wiki-link-completions.js +20 -20
  203. package/src/client/drawio-editor.js +8 -3
  204. package/src/client/excalidraw-editor.js +163 -6
  205. package/src/client/export/export-host.js +57 -36
  206. package/src/client/export/export-page.js +20 -6
  207. package/src/client/export/export-pipeline.js +322 -22
  208. package/src/client/infrastructure/editor-session.js +4 -0
  209. package/src/client/infrastructure/editor-view-adapter.js +60 -14
  210. package/src/client/presentation/bases-preview-controller.js +35 -11
  211. package/src/client/presentation/comment-ui/comment-ui-render.js +4 -0
  212. package/src/client/presentation/comment-ui-controller.js +2 -0
  213. package/src/client/presentation/excalidraw-embed-controller.js +7 -0
  214. package/src/client/presentation/file-action-controller.js +15 -2
  215. package/src/client/presentation/file-explorer-controller.js +3 -5
  216. package/src/client/presentation/file-explorer-view.js +43 -45
  217. package/src/client/presentation/file-history-view-controller.js +6 -1
  218. package/src/client/presentation/file-tree-state.js +5 -14
  219. package/src/client/presentation/git-diff-view-controller.js +36 -11
  220. package/src/client/presentation/git-panel-controller.js +12 -8
  221. package/src/client/presentation/quick-switcher-controller.js +92 -153
  222. package/src/client/styles/components/scrollbars.css +10 -0
  223. package/src/client/styles/export-document.css +44 -29
  224. package/src/client/styles/features/collaboration-presence.css +13 -1
  225. package/src/client/styles/features/preview-markdown.css +79 -0
  226. package/src/client/styles/features/quick-switcher.css +8 -0
  227. package/src/client/styles/foundation/themes.css +1 -0
  228. package/src/client/styles/foundation/tokens.css +8 -0
  229. package/src/client/styles/layout/shell.css +73 -339
  230. package/src/client/styles/layout/sidebar.css +42 -4
  231. package/src/client/styles/layout/view-modes.css +2 -0
  232. package/src/client/styles/overrides/codemirror.css +31 -19
  233. package/src/client/styles/overrides/highlightjs.css +20 -4
  234. package/src/client/styles/surfaces/excalidraw-editor.css +42 -0
  235. package/src/domain/file-kind.js +12 -1
  236. package/src/server/domain/ripgrep-search-service.js +110 -37
  237. package/src/server/infrastructure/git/git-service.js +23 -11
  238. package/src/server/infrastructure/http/create-git-api-command-handler.js +3 -1
  239. package/src/server/infrastructure/http/create-structurizr-api-handler.js +4 -2
  240. package/src/server/infrastructure/persistence/path-utils.js +10 -4
  241. package/src/server/infrastructure/persistence/vault-file-store.js +2 -0
  242. package/src/server/infrastructure/structurizr/structurizr-workspace-service.js +33 -7
  243. package/dist/client/assets/architecture-TIHT7OUA-CsHfPErM.js +0 -1
  244. package/dist/client/assets/base-CxPEiHuy.js +0 -1
  245. package/dist/client/assets/blockDiagram-VBNYF7ZC-CipJt9Jl.js +0 -132
  246. package/dist/client/assets/c4Diagram-5PPSVZJV-B5ktVx6g.js +0 -10
  247. package/dist/client/assets/channel-4Jkmq93I.js +0 -1
  248. package/dist/client/assets/chunk-7BUUIJ7U-Bb538aSH.js +0 -1
  249. package/dist/client/assets/chunk-7Z6QIM7H-BP9Pdsm9.js +0 -10
  250. package/dist/client/assets/chunk-ERSWUTIN-hHdvnhaY.js +0 -41
  251. package/dist/client/assets/chunk-I66GZJ75-CVFiiffQ.js +0 -127
  252. package/dist/client/assets/chunk-J7OUQ5F2-4CEb7pvH.js +0 -2
  253. package/dist/client/assets/chunk-JQJVKLGR-cx8X_24v.js +0 -156
  254. package/dist/client/assets/chunk-QR6OTTB3-CDAA_5Ib.js +0 -62
  255. package/dist/client/assets/chunk-RYQCIY6F-D-a0zH8K.js +0 -1
  256. package/dist/client/assets/chunk-UBXNYLIW-Bhk-PbFK.js +0 -1
  257. package/dist/client/assets/chunk-W5SLKNZC-BdNSCxZ9.js +0 -1
  258. package/dist/client/assets/chunk-WRU74C26-h6_XkD3_.js +0 -70
  259. package/dist/client/assets/chunk-ZIRB5QZD-O39ZBUk3.js +0 -32
  260. package/dist/client/assets/classDiagram-JCYQIIEL-L7lsyW_w.js +0 -1
  261. package/dist/client/assets/classDiagram-v2-OCEON4UE-L7lsyW_w.js +0 -1
  262. package/dist/client/assets/comment-ui-shared-BC4pt4w8.js +0 -7
  263. package/dist/client/assets/cynefin-VYW2F7L2-Ds2Fw2Y0.js +0 -1
  264. package/dist/client/assets/dagre-Buvkdvvj.js +0 -1
  265. package/dist/client/assets/dagre-VZM6K2ZE-L1xArOGs.js +0 -4
  266. package/dist/client/assets/dist-B5Jf1SLZ.js +0 -2
  267. package/dist/client/assets/dist-BKW4PALF.js +0 -1
  268. package/dist/client/assets/dist-BWcHHOx-.js +0 -1
  269. package/dist/client/assets/dist-DaYdhcVs.js +0 -1
  270. package/dist/client/assets/dist-Kh2COra_.js +0 -1
  271. package/dist/client/assets/dist-tOaegDYS2.js +0 -1
  272. package/dist/client/assets/editor-session-Cm9ekeNo.js +0 -54
  273. package/dist/client/assets/embedded-editor-base-CwTkk911.css +0 -1
  274. package/dist/client/assets/erDiagram-JOGREHBK-cYUpEKpf.js +0 -85
  275. package/dist/client/assets/es-DXGV3RHd.js +0 -22
  276. package/dist/client/assets/eventmodeling-45OFAUF4-CLEiVx5s.js +0 -1
  277. package/dist/client/assets/excalidraw-editor-B46zsTFI.js +0 -9
  278. package/dist/client/assets/excalidraw-editor-Bt7gMSoh.css +0 -1
  279. package/dist/client/assets/excalidrawEditor-CT2pHq7e.js +0 -2
  280. package/dist/client/assets/export-page-A7NHawJY.js +0 -39
  281. package/dist/client/assets/exportDocument-B2L8fe34.css +0 -1
  282. package/dist/client/assets/exportDocument-BaqcOAAW.js +0 -2
  283. package/dist/client/assets/file-kind-BbqgGzpc.js +0 -1
  284. package/dist/client/assets/flowDiagram-UKHOOZJN-D0ypP0Ez.js +0 -1
  285. package/dist/client/assets/gitGraph-TEB2WS4Q-CZFBqwW-.js +0 -1
  286. package/dist/client/assets/github-dark.min-Z5exjX_n.css +0 -1
  287. package/dist/client/assets/github.min-D2BCvnWf.css +0 -1
  288. package/dist/client/assets/image-QXRYHUNP-SWEV8H0J.js +0 -1
  289. package/dist/client/assets/index-ClbjMBVt.js +0 -2
  290. package/dist/client/assets/index-Pum8ET-5.css +0 -1
  291. package/dist/client/assets/info-DKCQHKI2--1InqQeT.js +0 -1
  292. package/dist/client/assets/main-B3uPyqic.js +0 -893
  293. package/dist/client/assets/map-BaFkSB1l.js +0 -1
  294. package/dist/client/assets/mermaid.core-DN-lF51U.js +0 -11
  295. package/dist/client/assets/packet-7NZHBO7P-BGMXB0XL.js +0 -1
  296. package/dist/client/assets/pdf-BL9Pr2D5.js +0 -54
  297. package/dist/client/assets/pdf.worker-CLesOks4.mjs +0 -64857
  298. package/dist/client/assets/pdf_viewer-FVkkThnz.js +0 -551
  299. package/dist/client/assets/pie-RZYD4A2V-DgYg3tCt.js +0 -1
  300. package/dist/client/assets/preview-render-compiler-BD-XhkS2.js +0 -35
  301. package/dist/client/assets/preview-render-compiler-BKedaMxx.js +0 -1
  302. package/dist/client/assets/preview-render-worker-CiPqc9n6.js +0 -60
  303. package/dist/client/assets/prod-Dy20X7eT.js +0 -1
  304. package/dist/client/assets/prod-hnwh7wRM.js +0 -177
  305. package/dist/client/assets/quick-switcher-controller-fqOYR7qR.js +0 -12
  306. package/dist/client/assets/radar-I7S5WNFK-Ag-zp_Rq.js +0 -1
  307. package/dist/client/assets/railroad-3IZDKUUU-aibJDIDV.js +0 -1
  308. package/dist/client/assets/railroad-abnf-AHOZXSZD-BBMEuvIl.js +0 -1
  309. package/dist/client/assets/railroad-ebnf-EBAXGLYW-Be1nseej.js +0 -1
  310. package/dist/client/assets/railroad-peg-LSFZ7HO6-DIvD-Eyb.js +0 -1
  311. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-B1-BufUk.js +0 -1
  312. package/dist/client/assets/swimlanes-SLNWSIFB-oVTWEJIj.js +0 -2
  313. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-C5OTVwEu.js +0 -8
  314. package/dist/client/assets/treeView-QDETBFTQ-uHZ-3Fz8.js +0 -1
  315. package/dist/client/assets/treemap-6X3UGDF4-BnUKyy3l.js +0 -1
  316. package/dist/client/assets/vault-utils-wdQ0RNR9.js +0 -1
  317. package/dist/client/assets/wardley-OPB4EBWU-Da7TLC2F.js +0 -1
@@ -1,5 +1,12 @@
1
1
  import { exportToSvg as exportExcalidrawToSvg } from '@excalidraw/excalidraw';
2
2
 
3
+ import baseStyles from '../styles/base.css?inline';
4
+ import tokenStyles from '../styles/foundation/tokens.css?inline';
5
+ import themeStyles from '../styles/foundation/themes.css?inline';
6
+ import previewStyles from '../styles/features/preview-markdown.css?inline';
7
+ import highlightOverrideStyles from '../styles/overrides/highlightjs.css?inline';
8
+ import exportStyles from '../styles/export-document.css?inline';
9
+ import highlightStyles from '../assets/vendor/highlight/github.min.css?inline';
3
10
  import {
4
11
  encodeSvgDataUrl,
5
12
  loadImage,
@@ -7,14 +14,17 @@ import {
7
14
  sanitizeSvgMarkup,
8
15
  } from '../application/preview-diagram-utils.js';
9
16
  import { compilePreviewDocument } from '../application/preview-render-compiler.js';
10
- import { stripVaultFileExtension } from '../../domain/file-kind.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';
11
20
  import { parseSceneJson, sceneToInitialData } from '../domain/excalidraw-scene.js';
21
+ import { escapeHtml } from '../domain/vault-utils.js';
12
22
  import { downloadBlob } from '../browser-utils.js';
13
23
  import { resolveApiUrl, resolveAppUrl } from '../infrastructure/runtime-config.js';
14
24
 
15
25
  const EXPORT_PAGE_SOURCE = 'collabmd-export-page';
16
26
  const EXPORT_HOST_SOURCE = 'collabmd-export-host';
17
- const LIGHT_EXPORT_MERMAID_THEME = Object.freeze({
27
+ const EXPORT_MERMAID_CONFIG = Object.freeze({
18
28
  htmlLabels: false,
19
29
  flowchart: {
20
30
  defaultRenderer: 'dagre-wrapper',
@@ -25,7 +35,6 @@ const LIGHT_EXPORT_MERMAID_THEME = Object.freeze({
25
35
  useMaxWidth: true,
26
36
  },
27
37
  startOnLoad: false,
28
- theme: 'default',
29
38
  });
30
39
  const EXPORT_ASSET_FETCH_TIMEOUT_MS = 10_000;
31
40
  const EXPORT_ASSET_MAX_BYTES = 10 * 1024 * 1024;
@@ -46,6 +55,20 @@ const DOCX_IMAGE_TYPE_LABELS = new Map([
46
55
  ['image/gif', 'GIF'],
47
56
  ['image/webp', 'WebP'],
48
57
  ]);
58
+ const HTML_EXPORT_STYLES = [
59
+ baseStyles,
60
+ tokenStyles,
61
+ themeStyles,
62
+ previewStyles,
63
+ highlightOverrideStyles,
64
+ exportStyles,
65
+ highlightStyles,
66
+ `html, body {
67
+ height: auto;
68
+ min-height: 100%;
69
+ overflow: visible;
70
+ }`,
71
+ ].join('\n');
49
72
 
50
73
  let mermaidLoaderPromise = null;
51
74
  let assetCounter = 0;
@@ -55,6 +78,10 @@ function createAssetId(prefix = 'asset') {
55
78
  return `${prefix}-${assetCounter.toString(36)}`;
56
79
  }
57
80
 
81
+ function normalizeExportTheme(theme) {
82
+ return theme === 'dark' ? 'dark' : 'light';
83
+ }
84
+
58
85
  function createDocumentTitle(filePath, title = '') {
59
86
  const normalizedTitle = String(title ?? '').trim();
60
87
  if (normalizedTitle) {
@@ -65,6 +92,65 @@ function createDocumentTitle(filePath, title = '') {
65
92
  return stripVaultFileExtension(leaf) || 'document';
66
93
  }
67
94
 
95
+ function createDocumentAnchorId(filePath) {
96
+ return `export-doc-${encodeURIComponent(String(filePath ?? '').toLowerCase()).replace(/%/gu, '-').replace(/\./gu, '-')}`;
97
+ }
98
+
99
+ function createExportHeadingSlug(value) {
100
+ return String(value ?? '').trim().toLowerCase().replace(/[^a-z0-9]+/gu, '-').replace(/^-|-$/gu, '');
101
+ }
102
+
103
+ function rewriteDirectoryDocumentLinks(container, { fileList, sourceFilePath }) {
104
+ const exportedPaths = new Set(fileList);
105
+ const sourceAnchorId = createDocumentAnchorId(sourceFilePath);
106
+
107
+ Array.from(container.querySelectorAll('[id]')).forEach((element) => {
108
+ element.id = `${sourceAnchorId}-${element.id}`;
109
+ });
110
+
111
+ Array.from(container.querySelectorAll('a[href]')).forEach((link) => {
112
+ const rawHref = String(link.getAttribute('href') || '').trim();
113
+ const wikiTarget = String(link.getAttribute('data-wiki-target') || '').trim();
114
+ if (wikiTarget) {
115
+ const [targetPath, targetHeading = ''] = wikiTarget.split('#', 2);
116
+ const resolved = targetPath ? resolveWikiTargetPath(targetPath, fileList) : sourceFilePath;
117
+ if (resolved && exportedPaths.has(resolved)) {
118
+ const headingSlug = createExportHeadingSlug(targetHeading);
119
+ const targetAnchorId = createDocumentAnchorId(resolved);
120
+ link.setAttribute('href', headingSlug ? `#${targetAnchorId}-${headingSlug}` : `#${targetAnchorId}`);
121
+ link.removeAttribute('target');
122
+ link.removeAttribute('rel');
123
+ }
124
+ return;
125
+ }
126
+
127
+ if (!rawHref || /^(?:[a-z][a-z\d+.-]*:|\/\/)/iu.test(rawHref)) {
128
+ return;
129
+ }
130
+
131
+ if (rawHref.startsWith('#')) {
132
+ link.setAttribute('href', `#${sourceAnchorId}-${rawHref.slice(1)}`);
133
+ return;
134
+ }
135
+
136
+ const [pathPart, fragment = ''] = rawHref.split('#', 2);
137
+ const resolved = resolveVaultRelativePath(sourceFilePath, pathPart);
138
+ if (!exportedPaths.has(resolved)) {
139
+ return;
140
+ }
141
+
142
+ const targetAnchorId = createDocumentAnchorId(resolved);
143
+ link.setAttribute('href', fragment ? `#${targetAnchorId}-${fragment}` : `#${targetAnchorId}`);
144
+ link.removeAttribute('target');
145
+ link.removeAttribute('rel');
146
+ });
147
+ }
148
+
149
+ function replaceChildrenFromHtml(target, html) {
150
+ const parsed = new DOMParser().parseFromString(`<body>${String(html ?? '')}</body>`, 'text/html');
151
+ target.replaceChildren(...parsed.body.childNodes);
152
+ }
153
+
68
154
  function encodeSvgBase64DataUrl(svgMarkup) {
69
155
  const bytes = new TextEncoder().encode(String(svgMarkup ?? ''));
70
156
  const chunkSize = 0x8000;
@@ -95,7 +181,7 @@ function trimSvgCanvas(svgMarkup, { padding = 16 } = {}) {
95
181
  probe.style.top = '0';
96
182
  probe.style.visibility = 'hidden';
97
183
  probe.style.pointerEvents = 'none';
98
- probe.innerHTML = svgMarkup;
184
+ replaceChildrenFromHtml(probe, svgMarkup);
99
185
  document.body.appendChild(probe);
100
186
 
101
187
  try {
@@ -145,7 +231,7 @@ async function svgMarkupToPngDataUrl(svgMarkup) {
145
231
  type: 'image/svg+xml;charset=utf-8',
146
232
  }));
147
233
  const svgProbe = document.createElement('div');
148
- svgProbe.innerHTML = svgMarkup;
234
+ replaceChildrenFromHtml(svgProbe, svgMarkup);
149
235
  const svgElement = svgProbe.querySelector('svg');
150
236
 
151
237
  try {
@@ -616,7 +702,7 @@ function createDiagramFigureElement({
616
702
  if (svgMarkup) {
617
703
  const surface = document.createElement('div');
618
704
  surface.className = 'export-diagram-surface';
619
- surface.innerHTML = svgMarkup;
705
+ replaceChildrenFromHtml(surface, svgMarkup);
620
706
 
621
707
  const svgElement = surface.querySelector('svg');
622
708
  if (svgElement) {
@@ -656,7 +742,7 @@ async function ensureMermaidRuntime() {
656
742
  throw new Error('Mermaid runtime failed to initialize');
657
743
  }
658
744
 
659
- runtime.initialize(LIGHT_EXPORT_MERMAID_THEME);
745
+ runtime.initialize({ ...EXPORT_MERMAID_CONFIG, theme: 'default' });
660
746
  return runtime;
661
747
  });
662
748
 
@@ -686,7 +772,10 @@ function prepareMermaidSource(source) {
686
772
 
687
773
  async function renderMermaidToSvgMarkup(source) {
688
774
  const mermaid = await ensureMermaidRuntime();
689
- mermaid.initialize(LIGHT_EXPORT_MERMAID_THEME);
775
+ mermaid.initialize({
776
+ ...EXPORT_MERMAID_CONFIG,
777
+ theme: document.documentElement.dataset.theme === 'dark' ? 'dark' : 'default',
778
+ });
690
779
  const renderHost = document.createElement('div');
691
780
  renderHost.style.position = 'fixed';
692
781
  renderHost.style.left = '-10000px';
@@ -839,6 +928,97 @@ async function resolveDiagramShell(snapshot, shell, { label, prefix, render }) {
839
928
  }));
840
929
  }
841
930
 
931
+ function getBaseCellText(cell) {
932
+ if (cell?.text != null) {
933
+ return String(cell.text);
934
+ }
935
+ if (Array.isArray(cell?.value)) {
936
+ return cell.value.join(', ');
937
+ }
938
+ return cell?.value == null ? '' : String(cell.value);
939
+ }
940
+
941
+ async function resolveBaseEmbed(snapshot, placeholder) {
942
+ const response = await fetchJson(resolveApiUrl('/base/query'), {
943
+ body: JSON.stringify({
944
+ activeFilePath: snapshot.filePath,
945
+ path: placeholder.dataset.basePath || '',
946
+ search: '',
947
+ source: placeholder.dataset.baseSource || null,
948
+ sourcePath: placeholder.dataset.baseSourcePath || snapshot.filePath,
949
+ view: placeholder.dataset.baseView || '',
950
+ }),
951
+ headers: { 'Content-Type': 'application/json' },
952
+ method: 'POST',
953
+ });
954
+ const result = response.result;
955
+ if (!result || !Array.isArray(result.columns) || !Array.isArray(result.groups)) {
956
+ throw new Error('Base query returned no rendered view');
957
+ }
958
+
959
+ // ponytail: static tables preserve base data; share card/list renderers if those export layouts become necessary.
960
+ if (result.view?.type && result.view.type !== 'table') {
961
+ snapshot.warnings.push(`Base ${result.view.type} view exported as a static table`);
962
+ }
963
+
964
+ const shell = document.createElement('section');
965
+ shell.className = 'bases-shell bases-shell-static';
966
+ const toolbar = document.createElement('header');
967
+ toolbar.className = 'bases-toolbar';
968
+ const toolbarMain = document.createElement('div');
969
+ toolbarMain.className = 'bases-toolbar-main';
970
+ const title = document.createElement('strong');
971
+ title.textContent = result.view?.name || 'Base view';
972
+ const meta = document.createElement('div');
973
+ meta.className = 'bases-meta';
974
+ meta.textContent = `${result.totalRows ?? 0} results`;
975
+ toolbarMain.append(title, meta);
976
+ toolbar.appendChild(toolbarMain);
977
+ shell.appendChild(toolbar);
978
+
979
+ const content = document.createElement('div');
980
+ content.className = 'bases-content';
981
+ result.groups.forEach((group) => {
982
+ if (result.groups.length > 1) {
983
+ const heading = document.createElement('h3');
984
+ heading.textContent = group.label || group.key || 'Group';
985
+ content.appendChild(heading);
986
+ }
987
+ const tableShell = document.createElement('div');
988
+ tableShell.className = 'bases-table-shell';
989
+ const table = document.createElement('table');
990
+ table.className = 'bases-table';
991
+ const headRow = table.createTHead().insertRow();
992
+ result.columns.forEach((column) => {
993
+ const heading = document.createElement('th');
994
+ heading.scope = 'col';
995
+ heading.textContent = column.label || column.id || '';
996
+ headRow.appendChild(heading);
997
+ });
998
+ const body = table.createTBody();
999
+ (group.rows || []).forEach((row) => {
1000
+ const tableRow = body.insertRow();
1001
+ result.columns.forEach((column, columnIndex) => {
1002
+ const cell = tableRow.insertCell();
1003
+ const text = getBaseCellText(row.cells?.[column.id]);
1004
+ if (columnIndex === 0 && row.path) {
1005
+ const link = document.createElement('a');
1006
+ link.href = buildWikiLinkHref(row.path);
1007
+ link.dataset.wikiTarget = row.path;
1008
+ link.textContent = text;
1009
+ cell.appendChild(link);
1010
+ } else {
1011
+ cell.textContent = text;
1012
+ }
1013
+ });
1014
+ });
1015
+ tableShell.appendChild(table);
1016
+ content.appendChild(tableShell);
1017
+ });
1018
+ shell.appendChild(content);
1019
+ placeholder.replaceWith(shell);
1020
+ }
1021
+
842
1022
  async function resolveExcalidrawEmbed(snapshot, placeholder) {
843
1023
  const target = String(placeholder.dataset.embedTarget ?? '').trim();
844
1024
  if (!target) {
@@ -1004,6 +1184,20 @@ export async function resolveExportAssets(snapshot, {
1004
1184
  }
1005
1185
  }
1006
1186
 
1187
+ const baseEmbeds = Array.from(container.querySelectorAll('.bases-embed-placeholder[data-base-key]'));
1188
+ for (const placeholder of baseEmbeds) {
1189
+ try {
1190
+ await resolveBaseEmbed(snapshot, placeholder);
1191
+ } catch (error) {
1192
+ const message = error instanceof Error ? error.message : 'Unknown error';
1193
+ snapshot.warnings.push(`Base export failed: ${message}`);
1194
+ placeholder.replaceWith(Object.assign(document.createElement('p'), {
1195
+ className: 'export-warning',
1196
+ textContent: `Base export failed: ${message}`,
1197
+ }));
1198
+ }
1199
+ }
1200
+
1007
1201
  const excalidrawEmbeds = Array.from(container.querySelectorAll('.excalidraw-embed-placeholder[data-embed-key]'));
1008
1202
  for (const placeholder of excalidrawEmbeds) {
1009
1203
  try {
@@ -1035,9 +1229,11 @@ export async function resolveExportAssets(snapshot, {
1035
1229
  }
1036
1230
 
1037
1231
  export async function prepareExportSnapshot({
1232
+ directoryFileList = [],
1038
1233
  fileList = [],
1039
1234
  filePath,
1040
1235
  markdownText = '',
1236
+ theme = 'light',
1041
1237
  title = '',
1042
1238
  } = {}) {
1043
1239
  const normalizedFilePath = String(filePath ?? '').trim();
@@ -1048,6 +1244,7 @@ export async function prepareExportSnapshot({
1048
1244
  generatedAt: new Date().toISOString(),
1049
1245
  html: '',
1050
1246
  sourceMarkdown: normalizedMarkdown,
1247
+ theme: normalizeExportTheme(theme),
1051
1248
  title: createDocumentTitle(normalizedFilePath, title),
1052
1249
  warnings: [],
1053
1250
  };
@@ -1060,13 +1257,78 @@ export async function prepareExportSnapshot({
1060
1257
  });
1061
1258
  const container = document.createElement('div');
1062
1259
  container.className = 'preview-content export-content';
1063
- container.innerHTML = compiled.html;
1260
+ replaceChildrenFromHtml(container, compiled.html);
1064
1261
 
1065
1262
  await resolveExportAssets(snapshot, { container });
1263
+ if (directoryFileList.length > 0) {
1264
+ rewriteDirectoryDocumentLinks(container, {
1265
+ fileList: directoryFileList,
1266
+ sourceFilePath: normalizedFilePath,
1267
+ });
1268
+ }
1066
1269
  snapshot.html = container.innerHTML;
1067
1270
  return snapshot;
1068
1271
  }
1069
1272
 
1273
+ export async function prepareDirectoryExportSnapshot({
1274
+ currentFilePath = '',
1275
+ currentMarkdownText = '',
1276
+ directoryPath,
1277
+ fileList = [],
1278
+ theme = 'light',
1279
+ } = {}) {
1280
+ const normalizedDirectoryPath = String(directoryPath ?? '').replace(/\\/gu, '/').replace(/^\/+|\/+$/gu, '').trim();
1281
+ const directoryPrefix = `${normalizedDirectoryPath}/`;
1282
+ const markdownPaths = fileList
1283
+ .filter((filePath) => isMarkdownFilePath(filePath) && String(filePath).startsWith(directoryPrefix))
1284
+ .sort((left, right) => left.localeCompare(right, undefined, { sensitivity: 'base' }));
1285
+ if (markdownPaths.length === 0) {
1286
+ throw new Error('The selected folder contains no markdown notes');
1287
+ }
1288
+
1289
+ const documents = [];
1290
+ const warnings = [];
1291
+ for (const filePath of markdownPaths) {
1292
+ const markdownText = filePath === currentFilePath
1293
+ ? String(currentMarkdownText ?? '')
1294
+ : await fetchTextFile(filePath);
1295
+ const documentSnapshot = await prepareExportSnapshot({
1296
+ directoryFileList: markdownPaths,
1297
+ fileList,
1298
+ filePath,
1299
+ markdownText,
1300
+ theme,
1301
+ });
1302
+ warnings.push(...documentSnapshot.warnings.map((warning) => `${filePath}: ${warning}`));
1303
+ documents.push(documentSnapshot);
1304
+ }
1305
+
1306
+ const title = createDocumentTitle(normalizedDirectoryPath);
1307
+ const tableOfContents = documents.map((documentSnapshot) => (
1308
+ `<li><a href="#${createDocumentAnchorId(documentSnapshot.filePath)}">${escapeHtml(documentSnapshot.filePath)}</a></li>`
1309
+ )).join('');
1310
+ const html = [
1311
+ `<nav class="export-directory-toc" aria-label="Exported notes"><h1>${escapeHtml(title)}</h1><ol>${tableOfContents}</ol></nav>`,
1312
+ ...documents.map((documentSnapshot) => [
1313
+ `<section class="export-document-section" id="${createDocumentAnchorId(documentSnapshot.filePath)}">`,
1314
+ `<header class="export-document-heading"><h1>${escapeHtml(documentSnapshot.title)}</h1><p>${escapeHtml(documentSnapshot.filePath)}</p></header>`,
1315
+ documentSnapshot.html,
1316
+ '</section>',
1317
+ ].join('')),
1318
+ ].join('');
1319
+
1320
+ return {
1321
+ assets: {},
1322
+ filePath: normalizedDirectoryPath,
1323
+ generatedAt: new Date().toISOString(),
1324
+ html,
1325
+ sourceMarkdown: '',
1326
+ theme: normalizeExportTheme(theme),
1327
+ title,
1328
+ warnings,
1329
+ };
1330
+ }
1331
+
1070
1332
  function applyDocxTableStyles(table, {
1071
1333
  borderColor = '#d1d5db',
1072
1334
  cellPadding = '8px 10px',
@@ -1202,12 +1464,7 @@ function createDocxCodeBlockTable(pre) {
1202
1464
  paragraph.style.color = '#111827';
1203
1465
 
1204
1466
  const text = (line || '').replace(/\t/g, ' ');
1205
- if (!text) {
1206
- paragraph.innerHTML = '&nbsp;';
1207
- } else {
1208
- paragraph.textContent = text;
1209
- paragraph.innerHTML = paragraph.innerHTML.replace(/ /g, '&nbsp;');
1210
- }
1467
+ paragraph.textContent = text ? text.replace(/ /gu, '\u00a0') : '\u00a0';
1211
1468
 
1212
1469
  contentNodes.push(paragraph);
1213
1470
  });
@@ -1222,7 +1479,7 @@ function createDocxCodeBlockTable(pre) {
1222
1479
 
1223
1480
  export function buildDocxHtmlDocument(snapshot) {
1224
1481
  const template = document.createElement('template');
1225
- template.innerHTML = snapshot.html;
1482
+ replaceChildrenFromHtml(template.content, snapshot.html);
1226
1483
 
1227
1484
  Array.from(template.content.querySelectorAll('.table-wrapper')).forEach((wrapper) => {
1228
1485
  const table = wrapper.querySelector(':scope > table');
@@ -1387,6 +1644,38 @@ export function buildDocxHtmlDocument(snapshot) {
1387
1644
  </html>`;
1388
1645
  }
1389
1646
 
1647
+ export function buildHtmlDocument(snapshot) {
1648
+ const template = document.createElement('template');
1649
+ replaceChildrenFromHtml(template.content, snapshot.html);
1650
+ Array.from(template.content.querySelectorAll('[data-export-docx-src]')).forEach((element) => {
1651
+ element.removeAttribute('data-export-docx-src');
1652
+ });
1653
+
1654
+ const theme = normalizeExportTheme(snapshot.theme);
1655
+ return `<!DOCTYPE html>
1656
+ <html lang="en" data-theme="${theme}">
1657
+ <head>
1658
+ <meta charset="UTF-8">
1659
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1660
+ <title>${escapeHtml(snapshot.title)}</title>
1661
+ <style>${HTML_EXPORT_STYLES.replace(/<\/style/giu, '<\\/style')}</style>
1662
+ </head>
1663
+ <body data-theme="${theme}">
1664
+ <main class="export-page-shell">
1665
+ <article class="preview-content export-content">${template.innerHTML}</article>
1666
+ </main>
1667
+ </body>
1668
+ </html>`;
1669
+ }
1670
+
1671
+ export function htmlAdapter(snapshot) {
1672
+ downloadBlob(
1673
+ new Blob([buildHtmlDocument(snapshot)], { type: 'text/html;charset=utf-8' }),
1674
+ `${createDocumentTitle(snapshot.filePath, snapshot.title)}.html`,
1675
+ { removeDelayMs: 0, revokeDelayMs: 1000 },
1676
+ );
1677
+ }
1678
+
1390
1679
  export async function docxAdapter(snapshot) {
1391
1680
  const response = await fetch(resolveApiUrl('/export/docx'), {
1392
1681
  body: JSON.stringify({
@@ -1461,6 +1750,11 @@ export async function runExportAdapter(snapshot, format) {
1461
1750
  return;
1462
1751
  }
1463
1752
 
1753
+ if (format === 'html') {
1754
+ await htmlAdapter(snapshot);
1755
+ return;
1756
+ }
1757
+
1464
1758
  await docxAdapter(snapshot);
1465
1759
  }
1466
1760
 
@@ -1477,10 +1771,11 @@ export function postExportPageMessage(type, payload = {}) {
1477
1771
  }
1478
1772
 
1479
1773
  export async function waitForBootstrapPayload() {
1480
- const requestUrl = new URL(window.location.href);
1481
- const action = requestUrl.searchParams.get('action') === 'pdf' ? 'pdf' : 'docx';
1482
- const filePath = requestUrl.searchParams.get('file') || '';
1483
- const jobId = requestUrl.searchParams.get('job') || '';
1774
+ const searchParams = new URLSearchParams(window.location.search);
1775
+ const requestedAction = searchParams.get('action');
1776
+ const action = ['html', 'pdf'].includes(requestedAction) ? requestedAction : 'docx';
1777
+ const filePath = searchParams.get('file') || '';
1778
+ const jobId = searchParams.get('job') || window.name || '';
1484
1779
 
1485
1780
  if (jobId && window.opener && !window.opener.closed) {
1486
1781
  postExportPageMessage('ready', { jobId });
@@ -1508,11 +1803,15 @@ export async function waitForBootstrapPayload() {
1508
1803
 
1509
1804
  cleanup();
1510
1805
  resolve({
1511
- action,
1806
+ action: ['html', 'pdf'].includes(payload.action) ? payload.action : action,
1807
+ currentFilePath: payload.currentFilePath || '',
1808
+ currentMarkdownText: payload.currentMarkdownText || '',
1809
+ directoryPath: payload.directoryPath || '',
1512
1810
  fileList: Array.isArray(payload.fileList) ? payload.fileList : [],
1513
1811
  filePath: payload.filePath || filePath,
1514
- title: payload.title || '',
1515
1812
  markdownText: payload.markdownText || '',
1813
+ theme: normalizeExportTheme(payload.theme),
1814
+ title: payload.title || '',
1516
1815
  });
1517
1816
  };
1518
1817
 
@@ -1525,6 +1824,7 @@ export async function waitForBootstrapPayload() {
1525
1824
  fileList: [],
1526
1825
  filePath,
1527
1826
  markdownText: filePath ? await fetchTextFile(filePath) : '',
1827
+ theme: 'light',
1528
1828
  title: '',
1529
1829
  };
1530
1830
  }
@@ -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
  }