collabmd 0.1.21 → 0.1.25

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 (723) hide show
  1. package/README.md +102 -12
  2. package/bin/collabmd.js +3 -2
  3. package/dist/client/assets/CodeMirrorEditor-UCMRAMCV-BHWNpLuY.js +1 -0
  4. package/dist/client/assets/_basePickBy-CJWegqog.js +1 -0
  5. package/dist/client/assets/_baseUniq-CFKN1k1n.js +1 -0
  6. package/dist/client/assets/apl-khHl8vBy.js +1 -0
  7. package/dist/client/assets/ar-SA-NXDWD63E-DND5MLpM.js +8 -0
  8. package/dist/client/assets/arc-D1SV2GW0.js +1 -0
  9. package/dist/client/assets/architecture-PBZL5I3N-0dui3p7-.js +1 -0
  10. package/dist/client/assets/architectureDiagram-2XIMDMQ5-DXpDe6lq.js +36 -0
  11. package/dist/client/assets/array-BTHl6o_K.js +1 -0
  12. package/dist/client/assets/asciiarmor-7xnRhA8w.js +1 -0
  13. package/dist/client/assets/asn1-_x-T1mFB.js +1 -0
  14. package/dist/client/assets/asterisk-Ct2NwVUw.js +1 -0
  15. package/dist/client/assets/az-AZ-MXSORGZV-ILYw2sYr.js +1 -0
  16. package/dist/client/assets/bg-BG-O6MV2KSF-DmfoZHM8.js +5 -0
  17. package/dist/client/assets/blockDiagram-WCTKOSBZ-DlJn0Rs1.js +132 -0
  18. package/dist/client/assets/bn-BD-T2VJNT7N-uYQx1Wph.js +3 -0
  19. package/dist/client/assets/bn-IN-MMW2ORAC-CmlBLY7g.js +3 -0
  20. package/dist/client/assets/brainfuck-CAmdgqDN.js +1 -0
  21. package/dist/client/assets/c4Diagram-IC4MRINW-C6S9MOEW.js +10 -0
  22. package/dist/client/assets/ca-ES-MKBCGNOG-DWiYvMvF.js +8 -0
  23. package/dist/client/assets/channel-CVwYcdlk.js +1 -0
  24. package/dist/client/assets/chunk-27N2SPOM-RxZ2_zJJ.js +34 -0
  25. package/dist/client/assets/chunk-3PELD44J-BvOh9EJp.js +1 -0
  26. package/dist/client/assets/chunk-4BX2VUAB-LBTVcC6-.js +1 -0
  27. package/dist/client/assets/chunk-55IACEB6-T5nuDI6U.js +1 -0
  28. package/dist/client/assets/chunk-7E7YKBS2-CBNUsbS7.js +1 -0
  29. package/dist/client/assets/chunk-7R4GIKGN-Dh9p1sbP.js +80 -0
  30. package/{public/assets/js/chunks/chunk-IR2DOYV4.js → dist/client/assets/chunk-A66AFZZU-D0IDIehU.js} +2 -2
  31. package/dist/client/assets/chunk-C72U2L5F-DLNOvzEI.js +1 -0
  32. package/dist/client/assets/chunk-Cq_f4orQ.js +1 -0
  33. package/dist/client/assets/chunk-EGIJ26TM-BkBsHEWn.js +1 -0
  34. package/dist/client/assets/chunk-ETSVUAFD-BnK5BhxL.js +12 -0
  35. package/{public/assets/js/chunks/chunk-U6APNHAF.js → dist/client/assets/chunk-FMBD7UC4-BoiIqhkb.js} +2 -2
  36. package/dist/client/assets/chunk-GEFDOKGD-CIg-LRSp.js +2 -0
  37. package/dist/client/assets/chunk-GLR3WWYH-CqGMuOti.js +2 -0
  38. package/dist/client/assets/chunk-HHEYEP7N-Czb3OX2v.js +1 -0
  39. package/dist/client/assets/chunk-JSJVCQXG-C6-G93S3.js +1 -0
  40. package/dist/client/assets/chunk-KX2RTZJC-CJlt0Rne.js +1 -0
  41. package/dist/client/assets/chunk-KYZI473N-C-ObF5L3.js +53 -0
  42. package/dist/client/assets/chunk-L3YUKLVL-BzkNNFii.js +1 -0
  43. package/dist/client/assets/chunk-MX3YWQON-bjcMtEei.js +1 -0
  44. package/dist/client/assets/chunk-NQ4KR5QH-DY9oh8PD.js +220 -0
  45. package/dist/client/assets/chunk-O4XLMI2P-CVfnFXq8.js +7 -0
  46. package/dist/client/assets/chunk-OZEHJAEY-DyD-ywvu.js +1 -0
  47. package/dist/client/assets/chunk-PQ6SQG4A-BOJs3QbF.js +1 -0
  48. package/dist/client/assets/chunk-PU5JKC2W-1nkyDxBh.js +70 -0
  49. package/dist/client/assets/chunk-QZHKN3VN-DU7fMcaP.js +1 -0
  50. package/dist/client/assets/chunk-R5LLSJPH-D9t4mFiL.js +1 -0
  51. package/dist/client/assets/chunk-SRAX5OIU-B-Zdxy2r.js +1 -0
  52. package/dist/client/assets/chunk-WL4C6EOR-Bs95uEnp.js +189 -0
  53. package/dist/client/assets/chunk-XIRO2GV7-CtwY16Jh.js +1 -0
  54. package/dist/client/assets/chunk-XPW4576I-CvxG514V.js +32 -0
  55. package/dist/client/assets/chunk-XZSTWKYB-BNB3Mgw3.js +94 -0
  56. package/dist/client/assets/chunk-YBOYWFTD-MIDp82ug.js +1 -0
  57. package/dist/client/assets/chunk-Z5NKEFVG-CIMf1Se5.js +22 -0
  58. package/dist/client/assets/classDiagram-VBA2DB6C-CBSmkOe7.js +1 -0
  59. package/dist/client/assets/classDiagram-v2-RAHNMMFH-CJarRy94.js +1 -0
  60. package/dist/client/assets/clike-BJcwKCE7.js +1 -0
  61. package/dist/client/assets/clojure-uSRILJfc.js +1 -0
  62. package/dist/client/assets/clone-CMmi3x0H.js +1 -0
  63. package/dist/client/assets/cmake-j5-7WxMz.js +1 -0
  64. package/dist/client/assets/cobol-cnURuZ43.js +1 -0
  65. package/dist/client/assets/coffeescript-iQD116iO.js +1 -0
  66. package/dist/client/assets/commonlisp-DGzExN9H.js +1 -0
  67. package/dist/client/assets/cose-bilkent-S5V4N54A-BKEY00wk.js +1 -0
  68. package/dist/client/assets/crystal-CnjkM1-q.js +1 -0
  69. package/dist/client/assets/cs-CZ-V77HGUP7-sLBAF2Iw.js +7 -0
  70. package/dist/client/assets/css-C-Nv0c9S.js +1 -0
  71. package/dist/client/assets/cypher-hxitpny2.js +1 -0
  72. package/dist/client/assets/cytoscape.esm-0xzpJ66h.js +321 -0
  73. package/dist/client/assets/d-BtdAWoTB.js +1 -0
  74. package/dist/client/assets/da-DK-I5RFNTM4-B__PLwca.js +2 -0
  75. package/dist/client/assets/dagre-Cm2w_QpZ.js +1 -0
  76. package/dist/client/assets/dagre-KLK3FWXG-BddfhbwG.js +4 -0
  77. package/dist/client/assets/de-CH-WLRDEVBV-D61DKw_9.js +7 -0
  78. package/dist/client/assets/de-DE-DTI4WUSC-Ba3fBYEU.js +7 -0
  79. package/dist/client/assets/defaultLocale-PG3Gbk8q.js +1 -0
  80. package/dist/client/assets/diagram-E7M64L7V-BoyJ8kpo.js +24 -0
  81. package/dist/client/assets/diagram-IFDJBPK2-DLWembLL.js +43 -0
  82. package/dist/client/assets/diagram-P4PSJMXO-CPmPa0OC.js +24 -0
  83. package/dist/client/assets/diff-f_ZkWiYS.js +1 -0
  84. package/dist/client/assets/dist-BATDm5JF.js +1 -0
  85. package/dist/client/assets/dist-BDDCA7hC.js +1 -0
  86. package/dist/client/assets/dist-BEs40fGb.js +1 -0
  87. package/dist/client/assets/dist-BPyPcaZr.js +1 -0
  88. package/dist/client/assets/dist-BiNL3fhN.js +1 -0
  89. package/dist/client/assets/dist-BpEcA20b.js +2 -0
  90. package/dist/client/assets/dist-BtROnx4-.js +1 -0
  91. package/dist/client/assets/dist-CCxn5Mk-.js +13 -0
  92. package/dist/client/assets/dist-CKdaLumK.js +1 -0
  93. package/dist/client/assets/dist-CNcGnl0T.js +1 -0
  94. package/dist/client/assets/dist-CPzoLjNz.js +1 -0
  95. package/dist/client/assets/dist-CQzPpOiH.js +1 -0
  96. package/dist/client/assets/dist-Cje3pdZH.js +9 -0
  97. package/dist/client/assets/dist-CnKD4Y92.js +1 -0
  98. package/dist/client/assets/dist-CxPc5kI6.js +1 -0
  99. package/dist/client/assets/dist-Czv7DXcw.js +23 -0
  100. package/dist/client/assets/dist-D4ebIlQB.js +6 -0
  101. package/dist/client/assets/dist-D7S1mzwR.js +1 -0
  102. package/dist/client/assets/dist-DFIisyRk.js +1 -0
  103. package/dist/client/assets/dist-DGbPPlZ8.js +1 -0
  104. package/dist/client/assets/dist-DL-EaOiC.js +1 -0
  105. package/dist/client/assets/dist-DhkKj77m.js +1 -0
  106. package/dist/client/assets/dist-DnpxzfoU.js +1 -0
  107. package/dist/client/assets/dist-Dy9oGocr.js +11 -0
  108. package/dist/client/assets/dist-Le-AVwIk.js +1 -0
  109. package/dist/client/assets/dist-StJm6K24.js +1 -0
  110. package/dist/client/assets/dist-gCWIHDgw.js +1 -0
  111. package/dist/client/assets/dist-mDBaykBY.js +1 -0
  112. package/dist/client/assets/dist-tyxqXzyB.js +1 -0
  113. package/dist/client/assets/dist-vL71uaef.js +1 -0
  114. package/dist/client/assets/dockerfile-BmylqEVx.js +1 -0
  115. package/dist/client/assets/dtd-B6xdyNDx.js +1 -0
  116. package/dist/client/assets/dylan-BzUoKQTn.js +1 -0
  117. package/dist/client/assets/ebnf-BlTaNq16.js +1 -0
  118. package/dist/client/assets/ecl-CffPaRqR.js +1 -0
  119. package/dist/client/assets/editor-session-DsM3VgQv.js +16 -0
  120. package/dist/client/assets/eiffel-B66P6crR.js +1 -0
  121. package/dist/client/assets/el-GR-ZXDJ2OS4-CpEbk42T.js +7 -0
  122. package/dist/client/assets/elm-DIwllOLv.js +1 -0
  123. package/dist/client/assets/en-CTDJDZ6K-C36Iqh9O.js +1 -0
  124. package/dist/client/assets/erDiagram-INFDFZHY-Dwg_AhU2.js +70 -0
  125. package/dist/client/assets/erlang-DwYA67QU.js +1 -0
  126. package/dist/client/assets/es-ES-DYQHAD43-Ba-6t0Wr.js +7 -0
  127. package/dist/client/assets/eu-ES-QDSYU5Y3-CYzUKQ2_.js +7 -0
  128. package/dist/client/assets/excalidraw-editor-Cs5p0lBn.js +182 -0
  129. package/dist/client/assets/excalidraw-editor-D8O7A69r.css +1 -0
  130. package/dist/client/assets/excalidraw-mermaid-stub-BtCKxPxK.js +1 -0
  131. package/dist/client/assets/excalidraw-mermaid-stub-C1ZaaI05.js +1 -0
  132. package/dist/client/assets/excalidrawEditor-wgJb2hmP.js +2 -0
  133. package/dist/client/assets/fa-IR-26LZG4PM-CxLc7ohL.js +9 -0
  134. package/dist/client/assets/factor-Cc9mS1OI.js +1 -0
  135. package/dist/client/assets/fcl-DD6dBrvI.js +1 -0
  136. package/dist/client/assets/fi-FI-6YS4KDE4-DtYLOEJY.js +6 -0
  137. package/dist/client/assets/flowDiagram-PKNHOUZH-BIJd4wAz.js +162 -0
  138. package/dist/client/assets/forth-DFLLMv-i.js +1 -0
  139. package/dist/client/assets/fortran-CNZVMQdQ.js +1 -0
  140. package/dist/client/assets/fr-FR-BRLLPTZC-9O_U5gdi.js +12 -0
  141. package/dist/client/assets/ganttDiagram-A5KZAMGK-BiMwicnp.js +292 -0
  142. package/dist/client/assets/gas-DyiCLKEJ.js +1 -0
  143. package/dist/client/assets/gherkin-CHgE7bAJ.js +1 -0
  144. package/dist/client/assets/gitGraph-HDMCJU4V-iPo6Lz4k.js +1 -0
  145. package/dist/client/assets/gitGraphDiagram-K3NZZRJ6-lk_paRel.js +65 -0
  146. package/dist/client/assets/github-dark.min-Z5exjX_n.css +1 -0
  147. package/dist/client/assets/github.min-D2BCvnWf.css +1 -0
  148. package/dist/client/assets/gl-ES-OKUZTLYG-Bb7TO64O.js +6 -0
  149. package/dist/client/assets/graphlib-B2nPo9Z4.js +1 -0
  150. package/dist/client/assets/groovy-BZc3It91.js +1 -0
  151. package/dist/client/assets/haskell-DJ4hTi3A.js +1 -0
  152. package/dist/client/assets/haxe-sJjg_lHN.js +1 -0
  153. package/dist/client/assets/he-IL-26MGYIU7-CQW1igm9.js +8 -0
  154. package/dist/client/assets/hi-IN-Q4ZOGTP2-BM91ENLs.js +3 -0
  155. package/dist/client/assets/http-DwAi3Ho1.js +1 -0
  156. package/dist/client/assets/hu-HU-P2OXPSN5-HiGbsUwM.js +3 -0
  157. package/dist/client/assets/id-ID-2EIKXYN6-DEG8vRZ2.js +8 -0
  158. package/dist/client/assets/idl-CCIDRFwr.js +1 -0
  159. package/dist/client/assets/image-32MOCVDX-viHDtJGM.js +1 -0
  160. package/dist/client/assets/image-blob-reduce.esm-D4wBfumB.js +2 -0
  161. package/dist/client/assets/index-B6m_KATZ.css +1 -0
  162. package/dist/client/assets/index-D20GlrKF.js +2 -0
  163. package/dist/client/assets/info-3K5VOQVL-DePZHLA4.js +1 -0
  164. package/dist/client/assets/infoDiagram-LFFYTUFH-CiAT_kJZ.js +2 -0
  165. package/dist/client/assets/init-Bb7Vx0CW.js +1 -0
  166. package/dist/client/assets/isArrayLikeObject-DxEG9mY7.js +1 -0
  167. package/dist/client/assets/isEmpty-DGNCKhlT.js +1 -0
  168. package/dist/client/assets/ishikawaDiagram-PHBUUO56-CE3HierS.js +70 -0
  169. package/dist/client/assets/it-IT-4CFKVXI2-DSrGqCKD.js +12 -0
  170. package/dist/client/assets/ja-JP-MAND2Z4V-OFpEymIv.js +7 -0
  171. package/dist/client/assets/javascript-BlUxwA0O.js +1 -0
  172. package/dist/client/assets/javascript-DcX_cm1u.js +1 -0
  173. package/dist/client/assets/journeyDiagram-4ABVD52K-CzoczPjW.js +139 -0
  174. package/dist/client/assets/jsx-runtime-DRYOYO9I.js +1 -0
  175. package/dist/client/assets/julia-BU0qBb1w.js +1 -0
  176. package/dist/client/assets/kaa-HQRTCXTJ-CpOJ_vn4.js +1 -0
  177. package/dist/client/assets/kab-KAB-JKIKKTGH-CNPzzJH6.js +4 -0
  178. package/dist/client/assets/kanban-definition-K7BYSVSG-Cr6iNYl4.js +89 -0
  179. package/dist/client/assets/katex-DoaSnJ5T.js +261 -0
  180. package/dist/client/assets/kk-KZ-HXQ63ZFC-CgtjU5JI.js +1 -0
  181. package/dist/client/assets/km-KH-PKL3LSGX-BAJh8UnF.js +7 -0
  182. package/dist/client/assets/ko-KR-KXLREZX3-BshOksBX.js +5 -0
  183. package/dist/client/assets/ku-TR-MJ4IER3X-Bi3YtiD-.js +6 -0
  184. package/dist/client/assets/line-D2NTyhqv.js +1 -0
  185. package/dist/client/assets/linear-DntNI0Uj.js +1 -0
  186. package/dist/client/assets/livescript-uk34VDGK.js +1 -0
  187. package/dist/client/assets/lt-LT-H6WFQ6FJ-DQ2W0g7h.js +3 -0
  188. package/dist/client/assets/lua-ClQGOv84.js +1 -0
  189. package/dist/client/assets/lv-LV-GOCK6SJW-DeqTo8T7.js +4 -0
  190. package/dist/client/assets/main-DONXLDrC.js +599 -0
  191. package/dist/client/assets/math-DQo53qzt.js +1 -0
  192. package/dist/client/assets/mathematica-BDmKpvRN.js +1 -0
  193. package/dist/client/assets/mbox-T5kA6jAQ.js +1 -0
  194. package/dist/client/assets/mermaid-parser.core-Bh2Ta9ou.js +4 -0
  195. package/dist/client/assets/mermaid-runtime-CLtta79D.js +11 -0
  196. package/dist/client/assets/mindmap-definition-YRQLILUH-DufPyQO8.js +68 -0
  197. package/dist/client/assets/mirc-DRRKKkcJ.js +1 -0
  198. package/dist/client/assets/mllike-iZXopbca.js +1 -0
  199. package/dist/client/assets/modelica-DP8T2DKM.js +1 -0
  200. package/dist/client/assets/mr-IN-IXVLDMEQ-CnH5Wjc7.js +9 -0
  201. package/dist/client/assets/mscgen-DXIRw2qg.js +1 -0
  202. package/dist/client/assets/mumps-BKUS05-y.js +1 -0
  203. package/dist/client/assets/my-MM-YG6MYTTD-BefEpouO.js +1 -0
  204. package/dist/client/assets/nb-NO-XGWJISD2-CNRrlrPY.js +8 -0
  205. package/dist/client/assets/nginx-CzYOtr2G.js +1 -0
  206. package/dist/client/assets/nl-NL-XVDVCPNC-CuLTw3kL.js +13 -0
  207. package/dist/client/assets/nn-NO-EMX5MJX5-NHFRnQkl.js +4 -0
  208. package/dist/client/assets/nsis-YyYYKQIB.js +1 -0
  209. package/dist/client/assets/ntriples-ZgZuaYbW.js +1 -0
  210. package/dist/client/assets/oc-FR-ROEINTVO-8kCbAtcr.js +4 -0
  211. package/dist/client/assets/octave-CnOndUN3.js +1 -0
  212. package/dist/client/assets/ordinal-BuNU9EgZ.js +1 -0
  213. package/dist/client/assets/oz-DjW322Rn.js +1 -0
  214. package/dist/client/assets/pa-IN-ZYN6SUDY-Dh8USSIe.js +4 -0
  215. package/dist/client/assets/packet-RMMSAZCW-BVw0pEk-.js +1 -0
  216. package/dist/client/assets/pascal-BdeW5uRX.js +1 -0
  217. package/dist/client/assets/path-BxyPWlyM.js +1 -0
  218. package/dist/client/assets/percentages-5DKR754L-RQFE76Sg.js +1 -0
  219. package/dist/client/assets/perl-_CDvIe1D.js +1 -0
  220. package/dist/client/assets/pica-BG8AR4mo.js +2 -0
  221. package/dist/client/assets/pie-UPGHQEXC-ChUWa5qF.js +1 -0
  222. package/dist/client/assets/pieDiagram-SKSYHLDU--YidSJxi.js +30 -0
  223. package/dist/client/assets/pig-inWo_B4W.js +1 -0
  224. package/dist/client/assets/pl-PL-6VTG7PHC-BMbgP62B.js +12 -0
  225. package/dist/client/assets/powershell-CO5KWJsy.js +1 -0
  226. package/dist/client/assets/preload-helper-Chd9yIcd.js +1 -0
  227. package/dist/client/assets/preview-render-compiler-CWBdv5tw.js +1 -0
  228. package/dist/client/assets/preview-render-profile-BjrQVCWD.js +23 -0
  229. package/dist/client/assets/preview-render-worker-DbMTa0Y6.js +23 -0
  230. package/dist/client/assets/properties-CjVp4a6M.js +1 -0
  231. package/dist/client/assets/protobuf-DybFT2KT.js +1 -0
  232. package/dist/client/assets/pt-BR-5YFKRR5G-CyrwFw_N.js +6 -0
  233. package/dist/client/assets/pt-PT-GEIXXZ67-SpK5vaGR.js +8 -0
  234. package/dist/client/assets/pug-CM36H1hd.js +1 -0
  235. package/dist/client/assets/puppet-Dw_NDgko.js +1 -0
  236. package/dist/client/assets/python-2pwcWoy7.js +1 -0
  237. package/dist/client/assets/q-C47l8kdS.js +1 -0
  238. package/dist/client/assets/quadrantDiagram-337W2JSQ-n7EIFT_f.js +7 -0
  239. package/dist/client/assets/quick-switcher-controller-CKrGBgcl.js +5 -0
  240. package/dist/client/assets/r-BmcXGVZ5.js +1 -0
  241. package/dist/client/assets/radar-KQ55EAFF-B4gMcoDX.js +1 -0
  242. package/dist/client/assets/requirementDiagram-Z7DCOOCP-BrquJATD.js +73 -0
  243. package/dist/client/assets/ro-RO-E2P6TFZI-90dn2iUp.js +12 -0
  244. package/dist/client/assets/room-zaSnuMv5.js +4 -0
  245. package/dist/client/assets/rough.esm-C7Rbwqik.js +1 -0
  246. package/dist/client/assets/roundRect-CDlbNkEg.js +1 -0
  247. package/dist/client/assets/rpm-Cm0x5xT_.js +1 -0
  248. package/dist/client/assets/ru-RU-YBIIY43T-Cl52NZnQ.js +10 -0
  249. package/dist/client/assets/ruby-Dl-I4pxG.js +1 -0
  250. package/dist/client/assets/runtime-config-loader--hxFvh23.js +1 -0
  251. package/dist/client/assets/sankeyDiagram-WA2Y5GQK-IpD6lgfO.js +10 -0
  252. package/dist/client/assets/sas-Bxkg4GVX.js +1 -0
  253. package/dist/client/assets/scheme-CO3zogua.js +1 -0
  254. package/dist/client/assets/sequenceDiagram-2WXFIKYE-DxZ6glIZ.js +145 -0
  255. package/dist/client/assets/shell-gYrTvBTP.js +1 -0
  256. package/dist/client/assets/si-LK-673C2CI2-DMSUxT-y.js +1 -0
  257. package/dist/client/assets/sieve-COX4Kn1X.js +1 -0
  258. package/dist/client/assets/simple-mode-BY9UFVy7.js +1 -0
  259. package/dist/client/assets/sk-SK-CKZHQ4AP-DUDai5Oe.js +7 -0
  260. package/dist/client/assets/sl-SI-557H2GWM-BbLeATfl.js +6 -0
  261. package/dist/client/assets/smalltalk-Dma1z5eE.js +1 -0
  262. package/dist/client/assets/solr-BvhcdkNH.js +1 -0
  263. package/dist/client/assets/sparql-gX7W9xeh.js +1 -0
  264. package/dist/client/assets/spreadsheet-BnlQRxWz.js +1 -0
  265. package/dist/client/assets/sql-CwA10oIk.js +1 -0
  266. package/dist/client/assets/src-H0-aBY9y.js +1 -0
  267. package/dist/client/assets/stateDiagram-RAJIS63D-A-rbDcdL.js +1 -0
  268. package/dist/client/assets/stateDiagram-v2-FVOUBMTO-CKhOHHLe.js +1 -0
  269. package/dist/client/assets/stex-DhLUylSV.js +1 -0
  270. package/dist/client/assets/stylus-9ZGSp3KB.js +1 -0
  271. package/dist/client/assets/subset-shared.chunk-93a-Md8B.js +1 -0
  272. package/dist/client/assets/subset-worker.chunk-B7pmUG1o.js +1 -0
  273. package/dist/client/assets/sv-SE-XOPKKDWS-BBa-AcMf.js +8 -0
  274. package/dist/client/assets/swift-CurfpLXH.js +1 -0
  275. package/dist/client/assets/ta-IN-XBH7DQI3-9uR7ADzx.js +6 -0
  276. package/dist/client/assets/tcl-BPvzXR-t.js +1 -0
  277. package/dist/client/assets/textile-BUq3vgBH.js +1 -0
  278. package/dist/client/assets/th-TH-TOCWH3R4-Box9U3ny.js +1 -0
  279. package/dist/client/assets/tiddlywiki-DRR6E4hS.js +1 -0
  280. package/dist/client/assets/tiki-C1XMixgx.js +1 -0
  281. package/dist/client/assets/timeline-definition-YZTLITO2-DuTppHot.js +61 -0
  282. package/dist/client/assets/toml-BQjoWSzq.js +1 -0
  283. package/dist/client/assets/tr-TR-GXW6CYY5-BA8pS3C5.js +4 -0
  284. package/dist/client/assets/treemap-KZPCXAKY-on28XbV_.js +1 -0
  285. package/dist/client/assets/troff-DbgTp3Cj.js +1 -0
  286. package/dist/client/assets/ttcn-1OxchGWH.js +1 -0
  287. package/dist/client/assets/ttcn-cfg-CC8OhyHu.js +1 -0
  288. package/dist/client/assets/turtle-D1WjVU4-.js +1 -0
  289. package/dist/client/assets/uk-UA-IJKTNUDG-B6hoHqzM.js +6 -0
  290. package/dist/client/assets/uz-UZ-TBZZEA4V-CPuftH33.js +1 -0
  291. package/dist/client/assets/vault-api-client-D7C_m9eq.js +188 -0
  292. package/dist/client/assets/vault-utils-Js2T-e-h.js +1 -0
  293. package/dist/client/assets/vb-Bf-XXYNJ.js +1 -0
  294. package/dist/client/assets/vbscript-HeSyWuOi.js +1 -0
  295. package/dist/client/assets/velocity-CUkiDsJQ.js +1 -0
  296. package/dist/client/assets/vennDiagram-LZ73GAT5-J0SBkXj8.js +34 -0
  297. package/dist/client/assets/verilog-BFxB5RAN.js +1 -0
  298. package/dist/client/assets/vhdl-BJUXQE-6.js +1 -0
  299. package/dist/client/assets/vi-VN-MULSGNVB-yRFd9OXl.js +7 -0
  300. package/dist/client/assets/webidl-advQMGTP.js +1 -0
  301. package/dist/client/assets/xquery-CNzoFgd7.js +1 -0
  302. package/dist/client/assets/xychartDiagram-JWTSCODW-Dn9dSYxn.js +7 -0
  303. package/dist/client/assets/yacas-BsmlDKac.js +1 -0
  304. package/dist/client/assets/yjs-provider-reset-guard-BcnBGrS9.js +4 -0
  305. package/dist/client/assets/z80-Bnez4vZ_.js +1 -0
  306. package/dist/client/assets/zh-CN-MVX3E32U-VzUIXB4K.js +11 -0
  307. package/dist/client/assets/zh-HK-JNU5RLIE-i0G2jHO_.js +1 -0
  308. package/dist/client/assets/zh-TW-LENVCA6T-BkHZg3jv.js +9 -0
  309. package/dist/client/excalidraw-editor.html +31 -0
  310. package/{public → dist/client}/index.html +135 -222
  311. package/docker-compose.yml +13 -1
  312. package/package.json +14 -7
  313. package/src/client/app/excalidraw-editor-entry.js +4 -0
  314. package/{public → src/client/app}/excalidraw-editor.html +1 -3
  315. package/src/client/app/index.html +469 -0
  316. package/src/client/app/main-entry.js +24 -0
  317. package/src/client/application/app-shell/git-feature.js +268 -32
  318. package/src/client/application/app-shell/ui-feature-identity.js +170 -0
  319. package/src/client/application/app-shell/ui-feature-shell.js +419 -0
  320. package/src/client/application/app-shell/ui-feature-sidebar.js +98 -0
  321. package/src/client/application/app-shell/ui-feature-tab-activity.js +128 -0
  322. package/src/client/application/app-shell/ui-feature-toolbar.js +520 -0
  323. package/src/client/application/app-shell/ui-feature.js +10 -648
  324. package/src/client/application/app-shell/workspace-feature.js +46 -0
  325. package/src/client/application/app-shell-elements.js +4 -0
  326. package/src/client/application/mermaid-preview-hydrator.js +1 -1
  327. package/src/client/application/plantuml-preview-hydrator.js +1 -1
  328. package/src/client/application/workspace-coordinator.js +147 -18
  329. package/src/client/application/workspace-preview-controller.js +34 -0
  330. package/src/client/application/workspace-route-controller.js +104 -0
  331. package/src/client/bootstrap/collabmd-app-shell.js +104 -0
  332. package/src/client/domain/markdown-formatting.js +197 -52
  333. package/src/client/domain/markdown-toolbar-actions.js +191 -0
  334. package/src/client/domain/runtime-paths.js +15 -0
  335. package/src/client/domain/workspace-request-id.js +7 -0
  336. package/src/client/excalidraw-editor.js +48 -2
  337. package/src/client/infrastructure/app-version-monitor.js +114 -0
  338. package/src/client/infrastructure/auth-client.js +219 -52
  339. package/src/client/infrastructure/browser-navigation-port.js +20 -0
  340. package/src/client/infrastructure/editor-collaboration-client.js +4 -0
  341. package/src/client/infrastructure/editor-session.js +47 -7
  342. package/src/client/infrastructure/editor-view-adapter.js +122 -58
  343. package/src/client/infrastructure/runtime-config-loader.js +56 -0
  344. package/src/client/infrastructure/runtime-config.js +66 -0
  345. package/src/client/infrastructure/vault-api-client.js +41 -7
  346. package/src/client/presentation/backlinks-panel.js +42 -9
  347. package/src/client/presentation/comment-ui/comment-ui-card.js +632 -0
  348. package/src/client/presentation/comment-ui/comment-ui-layout.js +452 -0
  349. package/src/client/presentation/comment-ui/comment-ui-render.js +149 -0
  350. package/src/client/presentation/comment-ui/comment-ui-shared.js +297 -0
  351. package/src/client/presentation/comment-ui/comment-ui-state.js +268 -0
  352. package/src/client/presentation/comment-ui-controller.js +13 -1529
  353. package/src/client/presentation/comments-panel.js +2 -2
  354. package/src/client/presentation/excalidraw-embed-controller.js +60 -2
  355. package/src/client/presentation/file-action-controller.js +195 -32
  356. package/src/client/presentation/file-explorer-controller.js +16 -2
  357. package/src/client/presentation/file-explorer-view.js +248 -7
  358. package/src/client/presentation/file-history-view-controller.js +806 -0
  359. package/src/client/presentation/file-tree-state.js +100 -5
  360. package/src/client/presentation/git-diff-view-controller.js +718 -121
  361. package/src/client/presentation/git-panel-controller.js +458 -66
  362. package/src/client/presentation/layout-controller.js +1 -1
  363. package/src/client/presentation/toast-controller.js +49 -6
  364. package/src/client/styles/components/actions.css +89 -0
  365. package/src/client/styles/components/feedback.css +71 -0
  366. package/src/client/styles/components/navigation.css +68 -0
  367. package/src/client/styles/components/scrollbars.css +104 -0
  368. package/src/client/styles/components/states.css +289 -0
  369. package/src/client/styles/components/surfaces.css +155 -0
  370. package/src/client/styles/features/backlinks.css +218 -0
  371. package/src/client/styles/features/collaboration-chat.css +228 -0
  372. package/src/client/styles/features/collaboration-dialogs.css +154 -0
  373. package/src/client/styles/features/collaboration-presence.css +103 -0
  374. package/src/client/styles/features/collaboration-ui.css +3 -0
  375. package/src/client/styles/features/comment-card.css +236 -0
  376. package/src/client/styles/features/comment-markdown.css +127 -0
  377. package/src/client/styles/features/comment-overlays.css +60 -0
  378. package/src/client/styles/features/comments-drawer.css +120 -0
  379. package/src/client/styles/features/comments.css +4 -0
  380. package/src/client/styles/features/diagram-preview.css +227 -0
  381. package/src/client/styles/features/diff-commit.css +268 -0
  382. package/src/client/styles/features/diff-lines.css +160 -0
  383. package/src/client/styles/features/diff-toolbar.css +98 -0
  384. package/src/client/styles/features/diff.css +3 -0
  385. package/src/client/styles/features/embedded-preview.css +218 -0
  386. package/src/client/styles/features/git-branch.css +155 -0
  387. package/src/client/styles/features/git-files.css +105 -0
  388. package/src/client/styles/features/git-history.css +339 -0
  389. package/src/client/styles/features/git.css +3 -0
  390. package/src/client/styles/features/media-lightbox.css +157 -0
  391. package/src/client/styles/features/outline.css +115 -0
  392. package/src/client/styles/features/preview-content.css +3 -0
  393. package/src/client/styles/features/preview-markdown.css +201 -0
  394. package/src/client/styles/features/preview-sidebars.css +2 -0
  395. package/src/client/styles/features/quick-switcher.css +167 -0
  396. package/src/client/styles/foundation/themes.css +347 -0
  397. package/src/client/styles/foundation/tokens.css +66 -0
  398. package/src/client/styles/foundation/utilities.css +36 -0
  399. package/src/client/styles/layout/editor-page.css +303 -0
  400. package/src/client/styles/layout/overlays.css +132 -0
  401. package/src/client/styles/layout/responsive.css +331 -0
  402. package/src/client/styles/layout/shell.css +314 -0
  403. package/src/client/styles/layout/sidebar.css +209 -0
  404. package/src/client/styles/layout/view-modes.css +92 -0
  405. package/src/client/styles/overrides/codemirror.css +53 -0
  406. package/src/client/styles/overrides/highlightjs.css +7 -0
  407. package/src/client/styles/overrides/vendor.css +2 -0
  408. package/src/client/styles/primitives/controls.css +277 -0
  409. package/src/client/styles/style.css +25 -4945
  410. package/src/server/auth/create-auth-service.js +373 -15
  411. package/src/server/auth/session-cookie.js +30 -4
  412. package/src/server/config/build-info.js +76 -0
  413. package/src/server/config/env.js +130 -6
  414. package/src/server/create-app-server.js +8 -0
  415. package/src/server/domain/collaboration/collaboration-room.js +90 -47
  416. package/src/server/index.js +3 -1
  417. package/src/server/infrastructure/git/command-runner.js +2 -1
  418. package/src/server/infrastructure/git/git-service.js +48 -2
  419. package/src/server/infrastructure/git/history-service.js +683 -0
  420. package/src/server/infrastructure/git/parsers.js +30 -0
  421. package/src/server/infrastructure/git/responses.js +73 -0
  422. package/src/server/infrastructure/http/create-auth-api-handler.js +30 -2
  423. package/src/server/infrastructure/http/create-git-api-command-handler.js +2 -0
  424. package/src/server/infrastructure/http/create-git-api-handler.js +2 -0
  425. package/src/server/infrastructure/http/create-git-api-query-handler.js +61 -0
  426. package/src/server/infrastructure/http/create-request-handler.js +15 -0
  427. package/src/server/infrastructure/http/create-static-handler.js +11 -2
  428. package/src/server/infrastructure/http/create-vault-api-command-handler.js +67 -0
  429. package/src/server/infrastructure/persistence/path-utils.js +11 -0
  430. package/src/server/infrastructure/persistence/vault-file-store.js +158 -3
  431. package/src/server/infrastructure/workspace/workspace-mutation-coordinator.js +84 -3
  432. package/public/assets/css/base.css +0 -1
  433. package/public/assets/css/style.css +0 -1
  434. package/public/assets/js/chunks/CodeMirrorEditor-UCMRAMCV-MAKZFDBE.js +0 -12
  435. package/public/assets/js/chunks/apl-C5P5JBDI.js +0 -1
  436. package/public/assets/js/chunks/ar-SA-NXDWD63E-MF6HMEA4.js +0 -8
  437. package/public/assets/js/chunks/architecture-PBZL5I3N-55LDZ5WS.js +0 -1
  438. package/public/assets/js/chunks/architectureDiagram-2XIMDMQ5-2VP562X7.js +0 -36
  439. package/public/assets/js/chunks/asciiarmor-3NCLLELT.js +0 -1
  440. package/public/assets/js/chunks/asn1-KF4WXU3M.js +0 -1
  441. package/public/assets/js/chunks/asterisk-EA3VIN65.js +0 -1
  442. package/public/assets/js/chunks/az-AZ-MXSORGZV-AIGO4TNU.js +0 -1
  443. package/public/assets/js/chunks/bg-BG-O6MV2KSF-X6AVO2AF.js +0 -5
  444. package/public/assets/js/chunks/blockDiagram-WCTKOSBZ-KM56WWDE.js +0 -132
  445. package/public/assets/js/chunks/bn-BD-T2VJNT7N-7OMHRIGC.js +0 -3
  446. package/public/assets/js/chunks/bn-IN-MMW2ORAC-EPKMNKG7.js +0 -3
  447. package/public/assets/js/chunks/brainfuck-A3CTQVFD.js +0 -1
  448. package/public/assets/js/chunks/c4Diagram-IC4MRINW-KX6UEGQZ.js +0 -10
  449. package/public/assets/js/chunks/ca-ES-MKBCGNOG-U44SUUTN.js +0 -8
  450. package/public/assets/js/chunks/chunk-2NTQWLZD.js +0 -25
  451. package/public/assets/js/chunks/chunk-2YRP2AWD.js +0 -1
  452. package/public/assets/js/chunks/chunk-3BUCGSSJ.js +0 -1
  453. package/public/assets/js/chunks/chunk-47L7JGE3.js +0 -1
  454. package/public/assets/js/chunks/chunk-4BCHPULB.js +0 -1
  455. package/public/assets/js/chunks/chunk-4NKM6YFO.js +0 -161
  456. package/public/assets/js/chunks/chunk-4WGMPBK5.js +0 -1
  457. package/public/assets/js/chunks/chunk-55WF6Y2Q.js +0 -1
  458. package/public/assets/js/chunks/chunk-5QRWYPYT.js +0 -25
  459. package/public/assets/js/chunks/chunk-775E65SU.js +0 -1
  460. package/public/assets/js/chunks/chunk-AJRGTECU.js +0 -70
  461. package/public/assets/js/chunks/chunk-B2J3PHGY.js +0 -1
  462. package/public/assets/js/chunks/chunk-B4JKB3BC.js +0 -1
  463. package/public/assets/js/chunks/chunk-CGVY4PKT.js +0 -13
  464. package/public/assets/js/chunks/chunk-CVTRX3TE.js +0 -220
  465. package/public/assets/js/chunks/chunk-DW6KK6VF.js +0 -1
  466. package/public/assets/js/chunks/chunk-E2HMNOQL.js +0 -189
  467. package/public/assets/js/chunks/chunk-EPTJZP5H.js +0 -7
  468. package/public/assets/js/chunks/chunk-G7NUGGE7.js +0 -13
  469. package/public/assets/js/chunks/chunk-GFDM7YCF.js +0 -1
  470. package/public/assets/js/chunks/chunk-GI7LBIBP.js +0 -1
  471. package/public/assets/js/chunks/chunk-GXRL27M7.js +0 -1
  472. package/public/assets/js/chunks/chunk-H6EYDHRW.js +0 -1
  473. package/public/assets/js/chunks/chunk-HEWVH67U.js +0 -9
  474. package/public/assets/js/chunks/chunk-HOCBCDA5.js +0 -1
  475. package/public/assets/js/chunks/chunk-HS2CUOC6.js +0 -1
  476. package/public/assets/js/chunks/chunk-HUAS4BYI.js +0 -12
  477. package/public/assets/js/chunks/chunk-HVNNEPP5.js +0 -2
  478. package/public/assets/js/chunks/chunk-I2GVZI7W.js +0 -38
  479. package/public/assets/js/chunks/chunk-I6PVWGBN.js +0 -14
  480. package/public/assets/js/chunks/chunk-IZ3V3F2A.js +0 -1
  481. package/public/assets/js/chunks/chunk-KPAQHIOI.js +0 -1
  482. package/public/assets/js/chunks/chunk-M3EW4V74.js +0 -1
  483. package/public/assets/js/chunks/chunk-MK3AFU3C.js +0 -90
  484. package/public/assets/js/chunks/chunk-NM6J3ND7.js +0 -1
  485. package/public/assets/js/chunks/chunk-NO7UPWTU.js +0 -1
  486. package/public/assets/js/chunks/chunk-OHGDMMWM.js +0 -1
  487. package/public/assets/js/chunks/chunk-OOT2HALX.js +0 -1
  488. package/public/assets/js/chunks/chunk-OQLLZFFN.js +0 -1
  489. package/public/assets/js/chunks/chunk-PF6TP4EI.js +0 -1
  490. package/public/assets/js/chunks/chunk-PMOZMECZ.js +0 -85
  491. package/public/assets/js/chunks/chunk-QBGS6DJR.js +0 -1
  492. package/public/assets/js/chunks/chunk-QF3ZQ6UQ.js +0 -1
  493. package/public/assets/js/chunks/chunk-QFXMAUW4.js +0 -1
  494. package/public/assets/js/chunks/chunk-QYKIT2IH.js +0 -41
  495. package/public/assets/js/chunks/chunk-S75BI2UQ.js +0 -1
  496. package/public/assets/js/chunks/chunk-SKEZZ3H6.js +0 -1
  497. package/public/assets/js/chunks/chunk-SO6QBCB6.js +0 -1
  498. package/public/assets/js/chunks/chunk-TFP6LRYJ.js +0 -53
  499. package/public/assets/js/chunks/chunk-VOODXHXA.js +0 -1
  500. package/public/assets/js/chunks/chunk-W7WJUTSA.js +0 -3
  501. package/public/assets/js/chunks/chunk-WNXFO2F2.js +0 -1
  502. package/public/assets/js/chunks/chunk-X6EEYWV4.js +0 -6
  503. package/public/assets/js/chunks/chunk-YVW3ZETS.js +0 -1
  504. package/public/assets/js/chunks/chunk-ZR2QRTBG.js +0 -339
  505. package/public/assets/js/chunks/chunk-ZZJX4LQ2.js +0 -1
  506. package/public/assets/js/chunks/classDiagram-VBA2DB6C-IYW4O2RM.js +0 -1
  507. package/public/assets/js/chunks/classDiagram-v2-RAHNMMFH-DNKVN2WD.js +0 -1
  508. package/public/assets/js/chunks/clike-RTBH33GE.js +0 -1
  509. package/public/assets/js/chunks/clojure-BR2VJ2JI.js +0 -1
  510. package/public/assets/js/chunks/cmake-2HEWVFEE.js +0 -1
  511. package/public/assets/js/chunks/cobol-V6EIK6DN.js +0 -1
  512. package/public/assets/js/chunks/coffeescript-JW3ZOGMD.js +0 -1
  513. package/public/assets/js/chunks/commonlisp-UCWSIHYK.js +0 -1
  514. package/public/assets/js/chunks/cose-bilkent-S5V4N54A-QVYRFFNC.js +0 -1
  515. package/public/assets/js/chunks/crystal-GR4VLC3M.js +0 -1
  516. package/public/assets/js/chunks/cs-CZ-V77HGUP7-OLBAKFG5.js +0 -7
  517. package/public/assets/js/chunks/css-C5DVWGB4.js +0 -1
  518. package/public/assets/js/chunks/cypher-K7FZM5GC.js +0 -1
  519. package/public/assets/js/chunks/d-CF3QNNH5.js +0 -1
  520. package/public/assets/js/chunks/da-DK-I5RFNTM4-QJIG2SEZ.js +0 -2
  521. package/public/assets/js/chunks/dagre-KLK3FWXG-KVNBUDOY.js +0 -4
  522. package/public/assets/js/chunks/de-CH-WLRDEVBV-4MMJDMVD.js +0 -7
  523. package/public/assets/js/chunks/de-DE-DTI4WUSC-ML7C46TT.js +0 -7
  524. package/public/assets/js/chunks/diagram-E7M64L7V-ZP33VRUC.js +0 -24
  525. package/public/assets/js/chunks/diagram-IFDJBPK2-ZG35YWOD.js +0 -43
  526. package/public/assets/js/chunks/diagram-P4PSJMXO-ZGIGM7D2.js +0 -24
  527. package/public/assets/js/chunks/diff-KOMSZU7O.js +0 -1
  528. package/public/assets/js/chunks/dist-7RQKSOUX.js +0 -7
  529. package/public/assets/js/chunks/dist-ARWGZ6MN.js +0 -1
  530. package/public/assets/js/chunks/dist-DPBSGC3Y.js +0 -2
  531. package/public/assets/js/chunks/dist-E36PJE5M.js +0 -1
  532. package/public/assets/js/chunks/dist-E5NM7OBW.js +0 -1
  533. package/public/assets/js/chunks/dist-ERADYPEK.js +0 -1
  534. package/public/assets/js/chunks/dist-F43RIHBZ.js +0 -1
  535. package/public/assets/js/chunks/dist-HAB5NIXI.js +0 -1
  536. package/public/assets/js/chunks/dist-HG23OLRA.js +0 -1
  537. package/public/assets/js/chunks/dist-IEJXBSDJ.js +0 -1
  538. package/public/assets/js/chunks/dist-IQA4KVJK.js +0 -1
  539. package/public/assets/js/chunks/dist-OIQTNVT2.js +0 -3
  540. package/public/assets/js/chunks/dist-PMZJ734S.js +0 -1
  541. package/public/assets/js/chunks/dist-RCQFQRLD.js +0 -1
  542. package/public/assets/js/chunks/dist-RQLC4GVI.js +0 -1
  543. package/public/assets/js/chunks/dist-RSJGLSKC.js +0 -1
  544. package/public/assets/js/chunks/dist-SGNQZVVX.js +0 -1
  545. package/public/assets/js/chunks/dist-VCFTF7Z6.js +0 -1
  546. package/public/assets/js/chunks/dist-VTO23SHH.js +0 -1
  547. package/public/assets/js/chunks/dist-XOODBV4L.js +0 -1
  548. package/public/assets/js/chunks/dist-ZFZNCRZY.js +0 -1
  549. package/public/assets/js/chunks/dockerfile-XCIKYOSI.js +0 -1
  550. package/public/assets/js/chunks/dtd-3XFH7W6Z.js +0 -1
  551. package/public/assets/js/chunks/dylan-3UWPKVOR.js +0 -1
  552. package/public/assets/js/chunks/ebnf-OLHTL3VN.js +0 -1
  553. package/public/assets/js/chunks/ecl-43LZ3ZRM.js +0 -1
  554. package/public/assets/js/chunks/editor-session-EAUBJCHH.js +0 -22
  555. package/public/assets/js/chunks/eiffel-ISPO2UJF.js +0 -1
  556. package/public/assets/js/chunks/el-GR-ZXDJ2OS4-WSCEIO6J.js +0 -7
  557. package/public/assets/js/chunks/elm-CLK576PK.js +0 -1
  558. package/public/assets/js/chunks/en-CTDJDZ6K-IC3QAUOI.js +0 -1
  559. package/public/assets/js/chunks/erDiagram-INFDFZHY-ZMS6H2TH.js +0 -70
  560. package/public/assets/js/chunks/erlang-AVQXQFOT.js +0 -1
  561. package/public/assets/js/chunks/es-ES-DYQHAD43-XGB5X5IM.js +0 -7
  562. package/public/assets/js/chunks/eu-ES-QDSYU5Y3-LA3JTIJ2.js +0 -7
  563. package/public/assets/js/chunks/excalidraw-mermaid-stub-NYXTOJ4H.js +0 -1
  564. package/public/assets/js/chunks/fa-IR-26LZG4PM-PFALMEDX.js +0 -9
  565. package/public/assets/js/chunks/factor-CRTVBD6Q.js +0 -1
  566. package/public/assets/js/chunks/fcl-FX24LKTH.js +0 -1
  567. package/public/assets/js/chunks/fi-FI-6YS4KDE4-ES5MV6P4.js +0 -6
  568. package/public/assets/js/chunks/flowDiagram-PKNHOUZH-QD4L5IE5.js +0 -162
  569. package/public/assets/js/chunks/forth-YKDKCTVS.js +0 -1
  570. package/public/assets/js/chunks/fortran-UJWC6SLU.js +0 -1
  571. package/public/assets/js/chunks/fr-FR-BRLLPTZC-VMFE22YV.js +0 -12
  572. package/public/assets/js/chunks/ganttDiagram-A5KZAMGK-VTMTQESP.js +0 -292
  573. package/public/assets/js/chunks/gas-MYEMWGRE.js +0 -1
  574. package/public/assets/js/chunks/gherkin-JWHAU2YG.js +0 -1
  575. package/public/assets/js/chunks/gitGraph-HDMCJU4V-YPHS74XX.js +0 -1
  576. package/public/assets/js/chunks/gitGraphDiagram-K3NZZRJ6-Z3EZ634T.js +0 -65
  577. package/public/assets/js/chunks/gl-ES-OKUZTLYG-GPT42ZHV.js +0 -6
  578. package/public/assets/js/chunks/groovy-QZIZQIAK.js +0 -1
  579. package/public/assets/js/chunks/haskell-JR3G7YNW.js +0 -1
  580. package/public/assets/js/chunks/haxe-TVLAIYEN.js +0 -1
  581. package/public/assets/js/chunks/he-IL-26MGYIU7-VQ5XQYYY.js +0 -8
  582. package/public/assets/js/chunks/hi-IN-Q4ZOGTP2-2Z766MXA.js +0 -3
  583. package/public/assets/js/chunks/http-YXQRE77G.js +0 -1
  584. package/public/assets/js/chunks/hu-HU-P2OXPSN5-6XDVPGTE.js +0 -3
  585. package/public/assets/js/chunks/id-ID-2EIKXYN6-J5GWSY2S.js +0 -8
  586. package/public/assets/js/chunks/idl-RAQGJ6LJ.js +0 -1
  587. package/public/assets/js/chunks/image-32MOCVDX-JN2EUMQG.js +0 -1
  588. package/public/assets/js/chunks/image-blob-reduce.esm-K5OWL55S.js +0 -13
  589. package/public/assets/js/chunks/info-3K5VOQVL-CXJSPNNP.js +0 -1
  590. package/public/assets/js/chunks/infoDiagram-LFFYTUFH-WQ34MUJA.js +0 -2
  591. package/public/assets/js/chunks/ishikawaDiagram-PHBUUO56-4IARWKJK.js +0 -70
  592. package/public/assets/js/chunks/it-IT-4CFKVXI2-NMBWUWFF.js +0 -12
  593. package/public/assets/js/chunks/ja-JP-MAND2Z4V-GQZYXXOC.js +0 -7
  594. package/public/assets/js/chunks/javascript-NM7KDJUE.js +0 -1
  595. package/public/assets/js/chunks/journeyDiagram-4ABVD52K-FJ4LF4SX.js +0 -139
  596. package/public/assets/js/chunks/julia-LG3BH25B.js +0 -1
  597. package/public/assets/js/chunks/kaa-HQRTCXTJ-7D6PAKDJ.js +0 -1
  598. package/public/assets/js/chunks/kab-KAB-JKIKKTGH-TNKFXNAX.js +0 -4
  599. package/public/assets/js/chunks/kanban-definition-K7BYSVSG-TY4EVYI3.js +0 -89
  600. package/public/assets/js/chunks/katex-5YJCUCFD.js +0 -261
  601. package/public/assets/js/chunks/kk-KZ-HXQ63ZFC-T4HCMWED.js +0 -1
  602. package/public/assets/js/chunks/km-KH-PKL3LSGX-HTLHEJV6.js +0 -7
  603. package/public/assets/js/chunks/ko-KR-KXLREZX3-QMR52QVI.js +0 -5
  604. package/public/assets/js/chunks/ku-TR-MJ4IER3X-K5CNY4UO.js +0 -6
  605. package/public/assets/js/chunks/livescript-4CVWVI4M.js +0 -1
  606. package/public/assets/js/chunks/lt-LT-H6WFQ6FJ-IW25FAGX.js +0 -3
  607. package/public/assets/js/chunks/lua-VWGE7DQ7.js +0 -1
  608. package/public/assets/js/chunks/lv-LV-GOCK6SJW-KTDFW5OH.js +0 -4
  609. package/public/assets/js/chunks/mathematica-D7APQSEU.js +0 -1
  610. package/public/assets/js/chunks/mbox-BN3XQBYX.js +0 -1
  611. package/public/assets/js/chunks/mermaid-runtime-BIFNJ2CT.js +0 -18
  612. package/public/assets/js/chunks/mindmap-definition-YRQLILUH-5B565RNP.js +0 -68
  613. package/public/assets/js/chunks/mirc-565WBI76.js +0 -1
  614. package/public/assets/js/chunks/mllike-VV3KS46B.js +0 -1
  615. package/public/assets/js/chunks/modelica-EGX44FZV.js +0 -1
  616. package/public/assets/js/chunks/mr-IN-IXVLDMEQ-PHM5DT7Q.js +0 -9
  617. package/public/assets/js/chunks/mscgen-GFGTHENT.js +0 -1
  618. package/public/assets/js/chunks/mumps-POZYWSMI.js +0 -1
  619. package/public/assets/js/chunks/my-MM-YG6MYTTD-ZHLCMEVA.js +0 -1
  620. package/public/assets/js/chunks/nb-NO-XGWJISD2-KSDFG6YU.js +0 -8
  621. package/public/assets/js/chunks/nginx-JUBX55EU.js +0 -1
  622. package/public/assets/js/chunks/nl-NL-XVDVCPNC-KVF3ZO2R.js +0 -13
  623. package/public/assets/js/chunks/nn-NO-EMX5MJX5-34QKSHNR.js +0 -4
  624. package/public/assets/js/chunks/nsis-RC4CREGM.js +0 -1
  625. package/public/assets/js/chunks/ntriples-4WK6CNVE.js +0 -1
  626. package/public/assets/js/chunks/oc-FR-ROEINTVO-5GP4AOYO.js +0 -4
  627. package/public/assets/js/chunks/octave-GOKFN2V7.js +0 -1
  628. package/public/assets/js/chunks/oz-OQUMNC63.js +0 -1
  629. package/public/assets/js/chunks/pa-IN-ZYN6SUDY-MVL7O44W.js +0 -4
  630. package/public/assets/js/chunks/packet-RMMSAZCW-D7XTR5TT.js +0 -1
  631. package/public/assets/js/chunks/pascal-BBWQWWWD.js +0 -1
  632. package/public/assets/js/chunks/percentages-5DKR754L-DG7W23CV.js +0 -1
  633. package/public/assets/js/chunks/perl-KTPJTTAM.js +0 -1
  634. package/public/assets/js/chunks/pica-6G3NROWT.js +0 -17
  635. package/public/assets/js/chunks/pie-UPGHQEXC-KGC3O6LN.js +0 -1
  636. package/public/assets/js/chunks/pieDiagram-SKSYHLDU-KWKRDEZS.js +0 -30
  637. package/public/assets/js/chunks/pig-IJMBS4FZ.js +0 -1
  638. package/public/assets/js/chunks/pl-PL-6VTG7PHC-VADRWSX4.js +0 -12
  639. package/public/assets/js/chunks/powershell-6YGCBHDP.js +0 -1
  640. package/public/assets/js/chunks/preview-render-compiler-6Y7TKXFJ.js +0 -1
  641. package/public/assets/js/chunks/properties-5QTD3364.js +0 -1
  642. package/public/assets/js/chunks/protobuf-LTRWBIK3.js +0 -1
  643. package/public/assets/js/chunks/pt-BR-5YFKRR5G-HHF4UPO4.js +0 -6
  644. package/public/assets/js/chunks/pt-PT-GEIXXZ67-TUTAUZJK.js +0 -8
  645. package/public/assets/js/chunks/pug-U4PV3WLG.js +0 -1
  646. package/public/assets/js/chunks/puppet-WGYJPR3Y.js +0 -1
  647. package/public/assets/js/chunks/python-6YGH4S47.js +0 -1
  648. package/public/assets/js/chunks/q-VIG4IJLI.js +0 -1
  649. package/public/assets/js/chunks/quadrantDiagram-337W2JSQ-GWQRUFHQ.js +0 -7
  650. package/public/assets/js/chunks/quick-switcher-controller-A6SKH5HI.js +0 -5
  651. package/public/assets/js/chunks/r-NVPCXGTR.js +0 -1
  652. package/public/assets/js/chunks/radar-KQ55EAFF-OPO64DRI.js +0 -1
  653. package/public/assets/js/chunks/requirementDiagram-Z7DCOOCP-ASW7IPJL.js +0 -73
  654. package/public/assets/js/chunks/ro-RO-E2P6TFZI-RJFCULYF.js +0 -12
  655. package/public/assets/js/chunks/roundRect-Z3DX3W5S.js +0 -1
  656. package/public/assets/js/chunks/rpm-UEA257HD.js +0 -1
  657. package/public/assets/js/chunks/ru-RU-YBIIY43T-BF27TNVK.js +0 -10
  658. package/public/assets/js/chunks/ruby-KPQRAJGE.js +0 -1
  659. package/public/assets/js/chunks/sankeyDiagram-WA2Y5GQK-W6BBWCLW.js +0 -10
  660. package/public/assets/js/chunks/sas-L7VATVH5.js +0 -1
  661. package/public/assets/js/chunks/scheme-T2NOWR3P.js +0 -1
  662. package/public/assets/js/chunks/sequenceDiagram-2WXFIKYE-H4G3ISLN.js +0 -145
  663. package/public/assets/js/chunks/shell-DLVDUNFA.js +0 -1
  664. package/public/assets/js/chunks/si-LK-673C2CI2-IOFGU4U2.js +0 -1
  665. package/public/assets/js/chunks/sieve-BKBZYDBU.js +0 -1
  666. package/public/assets/js/chunks/sk-SK-CKZHQ4AP-6O5JGN26.js +0 -7
  667. package/public/assets/js/chunks/sl-SI-557H2GWM-2NEHLV7W.js +0 -6
  668. package/public/assets/js/chunks/smalltalk-WRJQKJSD.js +0 -1
  669. package/public/assets/js/chunks/solr-66B3BIDL.js +0 -1
  670. package/public/assets/js/chunks/sparql-S25Z47JG.js +0 -1
  671. package/public/assets/js/chunks/spreadsheet-B272EF7Y.js +0 -1
  672. package/public/assets/js/chunks/sql-BPLIIUYC.js +0 -1
  673. package/public/assets/js/chunks/stateDiagram-RAJIS63D-OF5XXRUS.js +0 -1
  674. package/public/assets/js/chunks/stateDiagram-v2-FVOUBMTO-IV2CSQSQ.js +0 -1
  675. package/public/assets/js/chunks/stex-4IJY64QX.js +0 -1
  676. package/public/assets/js/chunks/stylus-PJUHLGPT.js +0 -1
  677. package/public/assets/js/chunks/subset-shared.chunk-4NMWHS4D.js +0 -1
  678. package/public/assets/js/chunks/subset-worker.chunk-NTLP7Y66.js +0 -1
  679. package/public/assets/js/chunks/sv-SE-XOPKKDWS-Q2L6KGFV.js +0 -8
  680. package/public/assets/js/chunks/swift-UYHTO4SX.js +0 -1
  681. package/public/assets/js/chunks/ta-IN-XBH7DQI3-ISSUGZAK.js +0 -6
  682. package/public/assets/js/chunks/tcl-OQ5J3VO2.js +0 -1
  683. package/public/assets/js/chunks/textile-NOGVBEYF.js +0 -1
  684. package/public/assets/js/chunks/th-TH-TOCWH3R4-TABEAMJA.js +0 -1
  685. package/public/assets/js/chunks/tiddlywiki-SYTK4QUE.js +0 -1
  686. package/public/assets/js/chunks/tiki-P7K4ZLOM.js +0 -1
  687. package/public/assets/js/chunks/timeline-definition-YZTLITO2-HBCANIUC.js +0 -61
  688. package/public/assets/js/chunks/toml-AUZYRP36.js +0 -1
  689. package/public/assets/js/chunks/tr-TR-GXW6CYY5-5NQRN52Y.js +0 -4
  690. package/public/assets/js/chunks/treemap-KZPCXAKY-WYMCT5F7.js +0 -1
  691. package/public/assets/js/chunks/troff-XFYJNQOJ.js +0 -1
  692. package/public/assets/js/chunks/ttcn-AK2IXWU6.js +0 -1
  693. package/public/assets/js/chunks/ttcn-cfg-3IDPIYPU.js +0 -1
  694. package/public/assets/js/chunks/turtle-OIDMF46P.js +0 -1
  695. package/public/assets/js/chunks/uk-UA-IJKTNUDG-2IIL3TO5.js +0 -6
  696. package/public/assets/js/chunks/uz-UZ-TBZZEA4V-X22KVKBP.js +0 -1
  697. package/public/assets/js/chunks/vb-J6K4XVA2.js +0 -1
  698. package/public/assets/js/chunks/vbscript-FM7DDZZE.js +0 -1
  699. package/public/assets/js/chunks/velocity-6KZFEOFD.js +0 -1
  700. package/public/assets/js/chunks/vennDiagram-LZ73GAT5-EBRF3MZR.js +0 -34
  701. package/public/assets/js/chunks/verilog-EWWQPMNN.js +0 -1
  702. package/public/assets/js/chunks/vhdl-CJ3M4IHI.js +0 -1
  703. package/public/assets/js/chunks/vi-VN-MULSGNVB-TENM65C7.js +0 -7
  704. package/public/assets/js/chunks/webidl-XVBHXCRV.js +0 -1
  705. package/public/assets/js/chunks/xquery-7WZOZ4UK.js +0 -1
  706. package/public/assets/js/chunks/xychartDiagram-JWTSCODW-WIFVRQPR.js +0 -7
  707. package/public/assets/js/chunks/yacas-MZ2ZZPF3.js +0 -1
  708. package/public/assets/js/chunks/z80-I447CBF7.js +0 -1
  709. package/public/assets/js/chunks/zh-CN-MVX3E32U-S5VA2BA5.js +0 -11
  710. package/public/assets/js/chunks/zh-HK-JNU5RLIE-A4VUKZFV.js +0 -1
  711. package/public/assets/js/chunks/zh-TW-LENVCA6T-KFB6KHMM.js +0 -9
  712. package/public/assets/js/excalidraw-editor-7ORML5YA.css +0 -1
  713. package/public/assets/js/excalidraw-editor-TCIH6GJL.js +0 -347
  714. package/public/assets/js/excalidraw-editor.css +0 -1
  715. package/public/assets/js/excalidraw-editor.js +0 -1
  716. package/public/assets/js/main.js +0 -381
  717. package/public/assets/js/preview-render-worker.js +0 -30
  718. /package/{public/assets/js/assets/Assistant-Bold-ZDZZ6JHA.woff2 → dist/client/assets/Assistant-Bold-gm-uSS1B.woff2} +0 -0
  719. /package/{public/assets/js/assets/Assistant-Medium-DZ25RZU3.woff2 → dist/client/assets/Assistant-Medium-DrcxCXg3.woff2} +0 -0
  720. /package/{public/assets/js/assets/Assistant-Regular-PLF2XOGW.woff2 → dist/client/assets/Assistant-Regular-DVxZuzxb.woff2} +0 -0
  721. /package/{public/assets/js/assets/Assistant-SemiBold-CZ5MX6FK.woff2 → dist/client/assets/Assistant-SemiBold-SCI4bEL9.woff2} +0 -0
  722. /package/{public → src/client}/assets/vendor/highlight/github-dark.min.css +0 -0
  723. /package/{public → src/client}/assets/vendor/highlight/github.min.css +0 -0
@@ -5,20 +5,34 @@ function getPathLeaf(pathValue) {
5
5
  return String(pathValue ?? '').split('/').pop() || '';
6
6
  }
7
7
 
8
+ function getPathDir(pathValue) {
9
+ const parts = String(pathValue ?? '').split('/');
10
+ parts.pop();
11
+ return parts.join('/');
12
+ }
13
+
14
+ function createSectionId(pathValue) {
15
+ return `diff-section-${encodeURIComponent(String(pathValue ?? '')).replace(/%/g, '_')}`;
16
+ }
17
+
8
18
  function badgeClass(status) {
9
19
  switch (status) {
10
20
  case 'added':
11
21
  case 'untracked':
12
- return 'added';
22
+ return 'ui-status-badge--success';
13
23
  case 'deleted':
14
- return 'deleted';
24
+ return 'ui-status-badge--danger';
15
25
  case 'renamed':
16
- return 'renamed';
26
+ return 'ui-status-badge--accent';
17
27
  default:
18
- return 'modified';
28
+ return 'ui-status-badge--warning';
19
29
  }
20
30
  }
21
31
 
32
+ function chevronSvg(collapsed = false) {
33
+ return `<svg class="diff-section-chevron${collapsed ? ' collapsed' : ''}" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg>`;
34
+ }
35
+
22
36
  function commonPrefixLength(left, right) {
23
37
  let index = 0;
24
38
  while (index < left.length && index < right.length && left[index] === right[index]) {
@@ -131,12 +145,14 @@ function renderSplitRow(leftLine, rightLine) {
131
145
 
132
146
  export class GitDiffViewController {
133
147
  constructor({
148
+ onBackToHistory = null,
134
149
  onCommitStaged = null,
135
150
  onOpenFile = null,
136
151
  onStageFile = null,
137
152
  onUnstageFile = null,
138
153
  toastController = null,
139
154
  } = {}) {
155
+ this.onBackToHistory = onBackToHistory;
140
156
  this.onCommitStaged = onCommitStaged;
141
157
  this.onOpenFile = onOpenFile;
142
158
  this.onStageFile = onStageFile;
@@ -149,16 +165,31 @@ export class GitDiffViewController {
149
165
  this.openEditorButton = document.getElementById('diffOpenEditorBtn');
150
166
  this.primaryActionButton = document.getElementById('diffPrimaryActionBtn');
151
167
  this.commitButton = document.getElementById('diffCommitBtn');
168
+ this.backToHistoryButton = document.getElementById('diffBackToHistoryBtn');
169
+ this.gitActionsGroup = document.getElementById('diffGitActionsGroup');
170
+ this.editorActionsGroup = document.getElementById('diffEditorActionsGroup');
171
+ this.actionsDivider = document.getElementById('diffToolbarDivider');
152
172
  this.stats = document.getElementById('diffStats');
153
173
  this.prevButton = document.getElementById('diffPrevBtn');
154
174
  this.nextButton = document.getElementById('diffNextBtn');
175
+ this.layoutToggle = document.getElementById('diffLayoutToggle');
155
176
  this.modeButtons = Array.from(document.querySelectorAll('[data-diff-mode]'));
177
+ this.layoutButtons = Array.from(document.querySelectorAll('[data-diff-layout]'));
156
178
  this.mode = 'unified';
179
+ this.layoutMode = 'focused';
180
+ this.source = 'workspace';
157
181
  this.data = null;
158
182
  this.currentIndex = 0;
183
+ this.activeFilePath = null;
159
184
  this.fileCache = new Map();
160
- this.loadingFilePath = null;
185
+ this.fileErrors = new Map();
186
+ this.loadingFiles = new Set();
187
+ this.collapsedFiles = new Set();
188
+ this.fileLoadPromises = new Map();
161
189
  this.requestScope = 'all';
190
+ this.commitHash = null;
191
+ this.commitMeta = null;
192
+ this.historyFilePath = null;
162
193
  this.pendingAction = null;
163
194
  this.repoStatus = null;
164
195
  }
@@ -166,7 +197,20 @@ export class GitDiffViewController {
166
197
  initialize() {
167
198
  this.prevButton?.addEventListener('click', () => this.navigateFile(-1));
168
199
  this.nextButton?.addEventListener('click', () => this.navigateFile(1));
200
+ this.backToHistoryButton?.addEventListener('click', () => {
201
+ if (!this.commitMeta?.hash) {
202
+ return;
203
+ }
204
+ this.onBackToHistory?.({
205
+ hash: this.commitMeta.hash,
206
+ historyFilePath: this.historyFilePath,
207
+ });
208
+ });
169
209
  this.openEditorButton?.addEventListener('click', () => {
210
+ if (this.source !== 'workspace') {
211
+ return;
212
+ }
213
+
170
214
  const currentFile = this.getCurrentFile();
171
215
  if (!currentFile?.path) {
172
216
  return;
@@ -190,7 +234,32 @@ export class GitDiffViewController {
190
234
  ? event.target.closest('[data-load-full-diff]')
191
235
  : null;
192
236
  if (loadButton) {
193
- void this.loadCurrentFile({ forceFullPatch: true });
237
+ const filePath = loadButton.getAttribute('data-diff-file-path') || this.activeFilePath;
238
+ if (filePath) {
239
+ void this.loadFileForPath(filePath, { forceFullPatch: true });
240
+ }
241
+ return;
242
+ }
243
+
244
+ const toggleButton = event.target instanceof Element
245
+ ? event.target.closest('[data-diff-section-toggle]')
246
+ : null;
247
+ if (toggleButton) {
248
+ const filePath = toggleButton.getAttribute('data-diff-section-toggle');
249
+ if (filePath) {
250
+ void this.toggleFileSection(filePath);
251
+ }
252
+ return;
253
+ }
254
+
255
+ const indexButton = event.target instanceof Element
256
+ ? event.target.closest('[data-diff-index-path]')
257
+ : null;
258
+ if (indexButton) {
259
+ const filePath = indexButton.getAttribute('data-diff-index-path');
260
+ if (filePath) {
261
+ void this.handleIndexSelection(filePath);
262
+ }
194
263
  }
195
264
  });
196
265
  this.modeButtons.forEach((button) => {
@@ -203,6 +272,18 @@ export class GitDiffViewController {
203
272
  this.render();
204
273
  });
205
274
  });
275
+ this.layoutButtons.forEach((button) => {
276
+ button.addEventListener('click', () => {
277
+ const nextLayout = button.getAttribute('data-diff-layout');
278
+ if (!nextLayout || nextLayout === this.layoutMode) {
279
+ return;
280
+ }
281
+ void this.setLayoutMode(nextLayout);
282
+ });
283
+ });
284
+ this.scrollContainer?.addEventListener('scroll', () => {
285
+ this.handleScrollSelection();
286
+ });
206
287
  }
207
288
 
208
289
  hide() {
@@ -211,17 +292,36 @@ export class GitDiffViewController {
211
292
  this.content.innerHTML = '';
212
293
  }
213
294
  this.data = null;
295
+ this.source = 'workspace';
296
+ this.layoutMode = 'focused';
214
297
  this.currentIndex = 0;
298
+ this.activeFilePath = null;
215
299
  this.fileCache.clear();
216
- this.loadingFilePath = null;
300
+ this.fileErrors.clear();
301
+ this.loadingFiles.clear();
302
+ this.collapsedFiles.clear();
303
+ this.fileLoadPromises.clear();
304
+ this.requestScope = 'all';
305
+ this.commitHash = null;
306
+ this.commitMeta = null;
307
+ this.historyFilePath = null;
217
308
  this.pendingAction = null;
218
309
  this.repoStatus = null;
219
310
  this.syncToolbar();
220
311
  }
221
312
 
222
- async open({ filePath = null, scope = 'all' } = {}) {
313
+ async openWorkspaceDiff({ filePath = null, scope = 'all' } = {}) {
314
+ this.source = 'workspace';
315
+ this.layoutMode = 'focused';
316
+ this.commitHash = null;
317
+ this.commitMeta = null;
318
+ this.historyFilePath = null;
319
+ this.activeFilePath = filePath;
223
320
  this.fileCache.clear();
224
- this.loadingFilePath = null;
321
+ this.fileErrors.clear();
322
+ this.loadingFiles.clear();
323
+ this.collapsedFiles.clear();
324
+ this.fileLoadPromises.clear();
225
325
  this.requestScope = scope;
226
326
  this.renderLoading('Loading diff summary...');
227
327
 
@@ -244,6 +344,7 @@ export class GitDiffViewController {
244
344
  ? Math.max(0, data.files.findIndex((file) => file.path === filePath))
245
345
  : 0;
246
346
  this.currentIndex = initialIndex;
347
+ this.activeFilePath = data.files?.[initialIndex]?.path ?? null;
247
348
  if ((data.files?.length ?? 0) === 0) {
248
349
  this.render();
249
350
  return data;
@@ -257,6 +358,7 @@ export class GitDiffViewController {
257
358
  this.data = {
258
359
  files: [],
259
360
  metaOnly: false,
361
+ source: 'workspace',
260
362
  summary: { additions: 0, deletions: 0, filesChanged: 0 },
261
363
  };
262
364
  this.renderEmpty('Failed to load git diff');
@@ -264,8 +366,100 @@ export class GitDiffViewController {
264
366
  }
265
367
  }
266
368
 
369
+ async openCommitDiff({ hash, path = null, historyFilePath = null } = {}) {
370
+ this.source = 'commit';
371
+ this.layoutMode = 'stacked';
372
+ this.commitHash = String(hash ?? '').trim() || null;
373
+ this.commitMeta = null;
374
+ this.historyFilePath = String(historyFilePath ?? '').trim() || null;
375
+ this.activeFilePath = path || null;
376
+ this.fileCache.clear();
377
+ this.fileErrors.clear();
378
+ this.loadingFiles.clear();
379
+ this.collapsedFiles.clear();
380
+ this.fileLoadPromises.clear();
381
+ this.requestScope = 'all';
382
+ this.renderLoading('Loading commit summary...');
383
+
384
+ try {
385
+ const query = new URLSearchParams();
386
+ query.set('hash', this.commitHash || '');
387
+ query.set('metaOnly', 'true');
388
+
389
+ const response = await fetch(resolveApiUrl(`/git/commit?${query.toString()}`));
390
+ const data = await response.json();
391
+ if (!response.ok) {
392
+ throw new Error(data.error || 'Failed to load git commit');
393
+ }
394
+
395
+ this.data = data;
396
+ this.commitMeta = data.commit ?? null;
397
+ const initialIndex = path
398
+ ? Math.max(0, data.files.findIndex((file) => file.path === path))
399
+ : 0;
400
+ this.currentIndex = initialIndex;
401
+ this.activeFilePath = data.files?.[initialIndex]?.path ?? null;
402
+ this.collapsedFiles = new Set(
403
+ (data.files ?? [])
404
+ .map((file) => file.path)
405
+ .filter((filePath) => filePath && filePath !== this.activeFilePath),
406
+ );
407
+ if ((data.files?.length ?? 0) === 0) {
408
+ this.render();
409
+ return data;
410
+ }
411
+
412
+ if (this.activeFilePath) {
413
+ await this.loadFileForPath(this.activeFilePath, { render: false });
414
+ }
415
+ this.render();
416
+ return data;
417
+ } catch (error) {
418
+ console.error('[git-diff] Failed to load commit:', error);
419
+ this.toastController?.show('Failed to load git commit');
420
+ this.data = {
421
+ commit: null,
422
+ files: [],
423
+ metaOnly: false,
424
+ source: 'commit',
425
+ summary: { additions: 0, deletions: 0, filesChanged: 0 },
426
+ };
427
+ this.commitMeta = null;
428
+ this.renderEmpty('Failed to load git commit');
429
+ return this.data;
430
+ }
431
+ }
432
+
433
+ async open(payload = {}) {
434
+ return this.openWorkspaceDiff(payload);
435
+ }
436
+
437
+ async setLayoutMode(layoutMode) {
438
+ const normalizedLayout = layoutMode === 'stacked' ? 'stacked' : 'focused';
439
+ if (this.source !== 'commit') {
440
+ this.layoutMode = 'focused';
441
+ this.render();
442
+ return;
443
+ }
444
+
445
+ this.layoutMode = normalizedLayout;
446
+ if (this.activeFilePath) {
447
+ this.setActiveFilePath(this.activeFilePath);
448
+ }
449
+ if (this.layoutMode === 'focused') {
450
+ await this.loadCurrentFile();
451
+ return;
452
+ }
453
+
454
+ if (this.activeFilePath) {
455
+ this.collapsedFiles.delete(this.activeFilePath);
456
+ await this.loadFileForPath(this.activeFilePath, { render: false });
457
+ }
458
+ this.render();
459
+ }
460
+
267
461
  navigateFile(direction) {
268
- if (!this.data?.files?.length) {
462
+ if (!this.data?.files?.length || (this.source === 'commit' && this.layoutMode === 'stacked')) {
269
463
  return;
270
464
  }
271
465
 
@@ -275,6 +469,7 @@ export class GitDiffViewController {
275
469
  }
276
470
 
277
471
  this.currentIndex = nextIndex;
472
+ this.activeFilePath = this.data.files[nextIndex]?.path ?? null;
278
473
  this.scrollContainer?.scrollTo({ top: 0, behavior: 'auto' });
279
474
  void this.loadCurrentFile();
280
475
  }
@@ -330,21 +525,24 @@ export class GitDiffViewController {
330
525
  `;
331
526
  }
332
527
 
333
- renderUnifiedFile(file, index) {
528
+ renderFileHeader(file) {
334
529
  return `
335
- <section class="diff-file-block" data-diff-file-index="${index}">
336
- <div class="diff-file-header">
337
- <span class="diff-file-path">${escapeHtml(file.path)}</span>
338
- <span class="git-status-badge ${badgeClass(file.status)}">${escapeHtml(file.status)}</span>
339
- <span class="diff-file-header-stats"><span class="diff-stats-add">+${file.stats?.additions ?? 0}</span><span class="diff-stats-del">-${file.stats?.deletions ?? 0}</span></span>
340
- </div>
341
- ${file.isBinary ? `<div class="diff-binary-message">${escapeHtml(file.binaryMessage || 'Binary file changed')}</div>` : ''}
342
- ${file.hunks.map((hunk) => this.renderUnifiedHunk(hunk)).join('')}
343
- </section>
530
+ <div class="diff-file-header">
531
+ <span class="diff-file-path">${escapeHtml(file.path)}</span>
532
+ <span class="ui-status-badge ${badgeClass(file.status)}">${escapeHtml(file.status)}</span>
533
+ <span class="diff-file-header-stats"><span class="ui-stat-token ui-stat-token--add diff-stats-add">+${file.stats?.additions ?? 0}</span><span class="ui-stat-token ui-stat-token--del diff-stats-del">-${file.stats?.deletions ?? 0}</span></span>
534
+ </div>
535
+ `;
536
+ }
537
+
538
+ renderUnifiedFileBody(file) {
539
+ return `
540
+ ${file.isBinary ? `<div class="diff-binary-message">${escapeHtml(file.binaryMessage || 'Binary file changed')}</div>` : ''}
541
+ ${file.hunks.map((hunk) => this.renderUnifiedHunk(hunk)).join('')}
344
542
  `;
345
543
  }
346
544
 
347
- renderSplitFile(file, index) {
545
+ renderSplitFileBody(file) {
348
546
  const hunks = file.hunks.map((hunk) => {
349
547
  const rows = [];
350
548
  for (const block of createPairedBlocks(hunk.lines)) {
@@ -368,22 +566,201 @@ export class GitDiffViewController {
368
566
  }).join('');
369
567
 
370
568
  return `
371
- <section class="diff-file-block" data-diff-file-index="${index}">
372
- <div class="diff-file-header">
373
- <span class="diff-file-path">${escapeHtml(file.path)}</span>
374
- <span class="git-status-badge ${badgeClass(file.status)}">${escapeHtml(file.status)}</span>
375
- <span class="diff-file-header-stats"><span class="diff-stats-add">+${file.stats?.additions ?? 0}</span><span class="diff-stats-del">-${file.stats?.deletions ?? 0}</span></span>
569
+ <div class="diff-split">
570
+ <div class="diff-split-pane">
571
+ <div class="diff-split-pane-header">Before</div>
572
+ ${hunks}
376
573
  </div>
377
- <div class="diff-split">
378
- <div class="diff-split-pane">
379
- <div class="diff-split-pane-header">Before</div>
380
- ${hunks}
381
- </div>
574
+ </div>
575
+ `;
576
+ }
577
+
578
+ renderDiffDetail(detail, index, { includeHeader = true } = {}) {
579
+ if (!detail) {
580
+ return '<div class="diff-empty-state">Select a file to load its diff.</div>';
581
+ }
582
+
583
+ if (detail.tooLarge) {
584
+ return `
585
+ ${includeHeader ? this.renderFileHeader(detail) : ''}
586
+ <div class="diff-limit-card">
587
+ <strong>Large diff withheld</strong>
588
+ <span>This file diff is large enough to impact rendering performance.</span>
589
+ <button class="ui-button btn btn-secondary diff-load-full-btn" type="button" data-load-full-diff data-diff-file-path="${escapeHtml(detail.path)}">Load full diff</button>
590
+ </div>
591
+ `;
592
+ }
593
+
594
+ const contentMarkup = this.mode === 'split'
595
+ ? this.renderSplitFileBody(detail, index)
596
+ : this.renderUnifiedFileBody(detail, index);
597
+
598
+ return `${includeHeader ? this.renderFileHeader(detail) : ''}${contentMarkup}`;
599
+ }
600
+
601
+ renderFocusedFileBody() {
602
+ const currentFile = this.getCurrentFile();
603
+ if (!currentFile) {
604
+ return '<div class="diff-empty-state">No changes to display.</div>';
605
+ }
606
+
607
+ if (this.isFileLoading(currentFile.path)) {
608
+ return `
609
+ <section class="diff-file-block">
610
+ ${this.renderFileHeader(currentFile)}
611
+ <div class="diff-empty-state">Loading file diff...</div>
612
+ </section>
613
+ `;
614
+ }
615
+
616
+ const errorMessage = this.fileErrors.get(currentFile.path);
617
+ if (errorMessage) {
618
+ return `
619
+ <section class="diff-file-block">
620
+ ${this.renderFileHeader(currentFile)}
621
+ <div class="diff-empty-state">${escapeHtml(errorMessage)}</div>
622
+ </section>
623
+ `;
624
+ }
625
+
626
+ return `
627
+ <section class="diff-file-block" data-diff-file-index="${this.currentIndex}">
628
+ ${this.renderDiffDetail(this.getFileDetail(currentFile.path) ?? currentFile, this.currentIndex)}
629
+ </section>
630
+ `;
631
+ }
632
+
633
+ renderCommitHeader() {
634
+ if (this.source !== 'commit' || !this.commitMeta) {
635
+ return '';
636
+ }
637
+
638
+ return `
639
+ <section class="diff-commit-header">
640
+ <div class="diff-commit-subject">${escapeHtml(this.commitMeta.subject || this.commitMeta.shortHash || 'Commit')}</div>
641
+ <div class="diff-commit-meta">
642
+ <span>${escapeHtml(this.commitMeta.shortHash || '')}</span>
643
+ <span>${escapeHtml(this.commitMeta.authorName || 'Unknown')}</span>
644
+ <span title="${escapeHtml(this.commitMeta.authoredAt || '')}">${escapeHtml(this.commitMeta.relativeDateLabel || '')}</span>
645
+ ${this.commitMeta.isMergeCommit ? '<span>Merge commit</span>' : ''}
646
+ </div>
647
+ <div class="diff-commit-meta diff-commit-meta-secondary">
648
+ <span>${escapeHtml(this.commitMeta.hash || '')}</span>
649
+ <span>${Number(this.data?.summary?.filesChanged || 0)} file${Number(this.data?.summary?.filesChanged || 0) === 1 ? '' : 's'}</span>
382
650
  </div>
383
651
  </section>
384
652
  `;
385
653
  }
386
654
 
655
+ renderCommitIndex() {
656
+ const files = this.data?.files ?? [];
657
+ const items = files.map((file, index) => {
658
+ const isActive = this.activeFilePath === file.path;
659
+ const dirPath = getPathDir(file.path);
660
+ return `
661
+ <button
662
+ class="ui-record-surface diff-index-item${isActive ? ' active' : ''}"
663
+ type="button"
664
+ data-diff-index-path="${escapeHtml(file.path)}"
665
+ aria-current="${isActive ? 'true' : 'false'}"
666
+ >
667
+ <span class="ui-record-header diff-index-item-top">
668
+ <span class="ui-record-title diff-index-item-name">${escapeHtml(getPathLeaf(file.path))}</span>
669
+ <span class="ui-status-badge ${badgeClass(file.status)}">${escapeHtml(file.status)}</span>
670
+ </span>
671
+ ${dirPath ? `<span class="ui-record-subtitle diff-index-item-path">${escapeHtml(dirPath)}</span>` : ''}
672
+ <span class="ui-record-meta diff-index-item-meta">
673
+ <span>${index + 1}</span>
674
+ <span class="ui-stat-token ui-stat-token--add diff-stats-add">+${file.stats?.additions ?? 0}</span>
675
+ <span class="ui-stat-token ui-stat-token--del diff-stats-del">-${file.stats?.deletions ?? 0}</span>
676
+ </span>
677
+ </button>
678
+ `;
679
+ }).join('');
680
+
681
+ return `
682
+ <aside class="diff-commit-index" aria-label="Changed files in commit">
683
+ <div class="diff-commit-index-header">Changed Files</div>
684
+ <div class="diff-commit-index-list">
685
+ ${items}
686
+ </div>
687
+ </aside>
688
+ `;
689
+ }
690
+
691
+ renderStackedSection(file, index) {
692
+ const isCollapsed = this.isFileCollapsed(file.path);
693
+ const isActive = this.activeFilePath === file.path;
694
+ const isLoading = this.isFileLoading(file.path);
695
+ const errorMessage = this.fileErrors.get(file.path);
696
+ const detail = this.getFileDetail(file.path) ?? file;
697
+
698
+ let bodyMarkup = '';
699
+ if (isCollapsed) {
700
+ bodyMarkup = '';
701
+ } else if (isLoading) {
702
+ bodyMarkup = '<div class="diff-empty-state">Loading file diff...</div>';
703
+ } else if (errorMessage) {
704
+ bodyMarkup = `<div class="diff-empty-state">${escapeHtml(errorMessage)}</div>`;
705
+ } else {
706
+ bodyMarkup = this.renderDiffDetail(detail, index, { includeHeader: false });
707
+ }
708
+
709
+ return `
710
+ <section
711
+ class="diff-commit-section${isActive ? ' active' : ''}${isCollapsed ? ' collapsed' : ''}"
712
+ id="${createSectionId(file.path)}"
713
+ data-diff-section-path="${escapeHtml(file.path)}"
714
+ >
715
+ <button
716
+ class="diff-commit-section-header"
717
+ type="button"
718
+ data-diff-section-toggle="${escapeHtml(file.path)}"
719
+ >
720
+ <span class="diff-commit-section-main">
721
+ ${chevronSvg(isCollapsed)}
722
+ <span class="diff-commit-section-copy">
723
+ <span class="diff-commit-section-name">${escapeHtml(getPathLeaf(file.path))}</span>
724
+ ${getPathDir(file.path) ? `<span class="diff-commit-section-path">${escapeHtml(getPathDir(file.path))}</span>` : ''}
725
+ </span>
726
+ </span>
727
+ <span class="diff-commit-section-meta">
728
+ <span class="ui-status-badge ${badgeClass(file.status)}">${escapeHtml(file.status)}</span>
729
+ <span class="ui-stat-token ui-stat-token--add diff-stats-add">+${file.stats?.additions ?? 0}</span>
730
+ <span class="ui-stat-token ui-stat-token--del diff-stats-del">-${file.stats?.deletions ?? 0}</span>
731
+ </span>
732
+ </button>
733
+ <div class="diff-commit-section-body${isCollapsed ? ' hidden' : ''}">
734
+ ${bodyMarkup}
735
+ </div>
736
+ </section>
737
+ `;
738
+ }
739
+
740
+ renderCommitBody() {
741
+ if (this.layoutMode === 'focused') {
742
+ return `
743
+ <div class="diff-commit-shell diff-commit-shell-focused">
744
+ ${this.renderCommitIndex()}
745
+ <div class="diff-commit-main">
746
+ ${this.renderFocusedFileBody()}
747
+ </div>
748
+ </div>
749
+ `;
750
+ }
751
+
752
+ return `
753
+ <div class="diff-commit-shell diff-commit-shell-stacked">
754
+ ${this.renderCommitIndex()}
755
+ <div class="diff-commit-main">
756
+ <div class="diff-commit-sections">
757
+ ${(this.data?.files ?? []).map((file, index) => this.renderStackedSection(file, index)).join('')}
758
+ </div>
759
+ </div>
760
+ </div>
761
+ `;
762
+ }
763
+
387
764
  getCurrentFile() {
388
765
  const files = this.data?.files ?? [];
389
766
  if (files.length === 0) {
@@ -393,9 +770,34 @@ export class GitDiffViewController {
393
770
  return files[this.currentIndex] ?? files[0] ?? null;
394
771
  }
395
772
 
773
+ getFileByPath(path) {
774
+ return (this.data?.files ?? []).find((file) => file.path === path) ?? null;
775
+ }
776
+
777
+ setActiveFilePath(path, { syncIndex = true } = {}) {
778
+ this.activeFilePath = path;
779
+ if (!syncIndex) {
780
+ return;
781
+ }
782
+
783
+ const nextIndex = Math.max(0, (this.data?.files ?? []).findIndex((file) => file.path === path));
784
+ if (nextIndex >= 0) {
785
+ this.currentIndex = nextIndex;
786
+ }
787
+ }
788
+
789
+ getCacheKeyForPath(path) {
790
+ if (!path) {
791
+ return null;
792
+ }
793
+ if (this.source === 'commit') {
794
+ return `commit:${this.commitHash}:${path}`;
795
+ }
796
+ return `workspace:${this.requestScope}:${path}`;
797
+ }
798
+
396
799
  getCurrentCacheKey() {
397
- const currentFile = this.getCurrentFile();
398
- return currentFile?.path ? `${this.requestScope}:${currentFile.path}` : null;
800
+ return this.getCacheKeyForPath(this.getCurrentFile()?.path ?? null);
399
801
  }
400
802
 
401
803
  getCurrentFileDetail() {
@@ -403,7 +805,28 @@ export class GitDiffViewController {
403
805
  return cacheKey ? this.fileCache.get(cacheKey) : null;
404
806
  }
405
807
 
808
+ getFileDetail(path) {
809
+ const cacheKey = this.getCacheKeyForPath(path);
810
+ return cacheKey ? this.fileCache.get(cacheKey) : null;
811
+ }
812
+
813
+ isFileCollapsed(path) {
814
+ return this.collapsedFiles.has(path);
815
+ }
816
+
817
+ isFileLoading(path) {
818
+ return this.loadingFiles.has(path);
819
+ }
820
+
406
821
  getCurrentActionState() {
822
+ if (this.source === 'commit') {
823
+ return {
824
+ canCommit: false,
825
+ canStage: false,
826
+ canUnstage: false,
827
+ };
828
+ }
829
+
407
830
  const currentFile = this.getCurrentFile();
408
831
  const detail = this.getCurrentFileDetail() ?? currentFile;
409
832
  const stagedCount = Number(this.repoStatus?.summary?.staged || 0);
@@ -423,6 +846,10 @@ export class GitDiffViewController {
423
846
  }
424
847
 
425
848
  getPrimaryAction() {
849
+ if (this.source === 'commit') {
850
+ return null;
851
+ }
852
+
426
853
  const actionState = this.getCurrentActionState();
427
854
  if (actionState.canStage && !actionState.canUnstage) {
428
855
  return 'stage';
@@ -443,6 +870,10 @@ export class GitDiffViewController {
443
870
  }
444
871
 
445
872
  async handleFileAction(action) {
873
+ if (this.source === 'commit') {
874
+ return;
875
+ }
876
+
446
877
  const currentFile = this.getCurrentFile();
447
878
  if (!currentFile?.path || this.pendingAction) {
448
879
  return;
@@ -470,135 +901,267 @@ export class GitDiffViewController {
470
901
  this.syncToolbar();
471
902
  }
472
903
 
473
- async loadCurrentFile({ forceFullPatch = false } = {}) {
474
- const currentFile = this.getCurrentFile();
475
- if (!currentFile?.path) {
904
+ async handleIndexSelection(filePath) {
905
+ const file = this.getFileByPath(filePath);
906
+ if (!file) {
907
+ return;
908
+ }
909
+
910
+ this.setActiveFilePath(filePath);
911
+ if (this.source === 'commit' && this.layoutMode === 'stacked') {
912
+ this.collapsedFiles.delete(filePath);
913
+ await this.loadFileForPath(filePath, { render: false });
476
914
  this.render();
477
- return null;
915
+ this.scrollToFileSection(filePath);
916
+ return;
478
917
  }
479
918
 
480
- const cacheKey = this.getCurrentCacheKey();
481
- const cachedFile = cacheKey ? this.fileCache.get(cacheKey) : null;
482
- if (cachedFile && (!cachedFile.tooLarge || !forceFullPatch)) {
483
- this.loadingFilePath = null;
919
+ await this.loadFileForPath(filePath);
920
+ }
921
+
922
+ async toggleFileSection(filePath) {
923
+ if (this.source !== 'commit' || this.layoutMode !== 'stacked') {
924
+ return;
925
+ }
926
+
927
+ this.setActiveFilePath(filePath);
928
+ if (this.collapsedFiles.has(filePath)) {
929
+ this.collapsedFiles.delete(filePath);
930
+ await this.loadFileForPath(filePath, { render: false });
484
931
  this.render();
485
- return cachedFile;
932
+ this.scrollToFileSection(filePath);
933
+ return;
486
934
  }
487
935
 
488
- this.loadingFilePath = currentFile.path;
936
+ this.collapsedFiles.add(filePath);
489
937
  this.render();
938
+ }
490
939
 
491
- try {
492
- const query = new URLSearchParams();
493
- query.set('scope', this.requestScope);
494
- query.set('path', currentFile.path);
495
- if (forceFullPatch) {
496
- query.set('allowLargePatch', 'true');
940
+ scrollToFileSection(filePath) {
941
+ if (!this.content) {
942
+ return;
943
+ }
944
+
945
+ const targetId = createSectionId(filePath);
946
+ const scrollToTarget = () => {
947
+ const section = document.getElementById?.(targetId) ?? null;
948
+ if (!section) {
949
+ return;
497
950
  }
498
951
 
499
- const response = await fetch(resolveApiUrl(`/git/diff?${query.toString()}`));
500
- const data = await response.json();
501
- if (!response.ok) {
502
- throw new Error(data.error || 'Failed to load file diff');
952
+ if (this.scrollContainer?.scrollTo && this.scrollContainer.getBoundingClientRect && section.getBoundingClientRect) {
953
+ const containerRect = this.scrollContainer.getBoundingClientRect();
954
+ const sectionRect = section.getBoundingClientRect();
955
+ const currentTop = Number(this.scrollContainer.scrollTop) || 0;
956
+ const nextTop = Math.max(0, currentTop + (sectionRect.top - containerRect.top) - 8);
957
+ this.scrollContainer.scrollTo({ top: nextTop, behavior: 'smooth' });
958
+ return;
503
959
  }
504
960
 
505
- const detail = {
506
- ...currentFile,
507
- ...(data.files?.[0] ?? {}),
508
- };
509
- if (cacheKey) {
510
- this.fileCache.set(cacheKey, detail);
961
+ section.scrollIntoView?.({ behavior: 'smooth', block: 'start' });
962
+ };
963
+
964
+ if (typeof requestAnimationFrame === 'function') {
965
+ requestAnimationFrame(scrollToTarget);
966
+ return;
967
+ }
968
+
969
+ setTimeout(scrollToTarget, 0);
970
+ }
971
+
972
+ handleScrollSelection() {
973
+ if (this.source !== 'commit' || this.layoutMode !== 'stacked' || !this.scrollContainer || !this.content) {
974
+ return;
975
+ }
976
+
977
+ const sections = Array.from(this.content.querySelectorAll?.('[data-diff-section-path]') ?? []);
978
+ if (sections.length === 0) {
979
+ return;
980
+ }
981
+
982
+ const containerRect = this.scrollContainer.getBoundingClientRect?.();
983
+ if (!containerRect) {
984
+ return;
985
+ }
986
+
987
+ const threshold = containerRect.top + 120;
988
+ let nextPath = null;
989
+ for (const section of sections) {
990
+ const rect = section.getBoundingClientRect?.();
991
+ if (!rect) {
992
+ continue;
993
+ }
994
+ const sectionPath = section.getAttribute?.('data-diff-section-path');
995
+ if (!sectionPath) {
996
+ continue;
511
997
  }
512
- this.loadingFilePath = null;
998
+ if (rect.top <= threshold) {
999
+ nextPath = sectionPath;
1000
+ } else if (!nextPath) {
1001
+ nextPath = sectionPath;
1002
+ break;
1003
+ } else {
1004
+ break;
1005
+ }
1006
+ }
1007
+
1008
+ if (nextPath && nextPath !== this.activeFilePath) {
1009
+ this.setActiveFilePath(nextPath);
513
1010
  this.render();
514
- return detail;
515
- } catch (error) {
516
- console.error('[git-diff] Failed to load file diff:', error);
517
- this.toastController?.show('Failed to load file diff');
518
- this.loadingFilePath = null;
1011
+ }
1012
+ }
1013
+
1014
+ async loadCurrentFile({ forceFullPatch = false } = {}) {
1015
+ const currentFile = this.getCurrentFile();
1016
+ if (!currentFile?.path) {
519
1017
  this.render();
520
1018
  return null;
521
1019
  }
1020
+
1021
+ return this.loadFileForPath(currentFile.path, { forceFullPatch });
522
1022
  }
523
1023
 
524
- renderCurrentFile() {
525
- const currentFile = this.getCurrentFile();
526
- if (!currentFile) {
527
- return '<div class="diff-empty-state">No changes to display.</div>';
1024
+ async loadFileForPath(filePath, { forceFullPatch = false, render = true } = {}) {
1025
+ const file = this.getFileByPath(filePath);
1026
+ if (!file?.path) {
1027
+ if (render) {
1028
+ this.render();
1029
+ }
1030
+ return null;
528
1031
  }
529
1032
 
530
- const detail = this.getCurrentFileDetail();
531
- if (this.loadingFilePath === currentFile.path) {
532
- return `
533
- <section class="diff-file-block">
534
- <div class="diff-file-header">
535
- <span class="diff-file-path">${escapeHtml(currentFile.path)}</span>
536
- <span class="git-status-badge ${badgeClass(currentFile.status)}">${escapeHtml(currentFile.status)}</span>
537
- </div>
538
- <div class="diff-empty-state">Loading file diff...</div>
539
- </section>
540
- `;
1033
+ this.setActiveFilePath(filePath);
1034
+ const cacheKey = this.getCacheKeyForPath(filePath);
1035
+ const cachedFile = cacheKey ? this.fileCache.get(cacheKey) : null;
1036
+ if (cachedFile && (!cachedFile.tooLarge || !forceFullPatch)) {
1037
+ if (render) {
1038
+ this.render();
1039
+ }
1040
+ return cachedFile;
541
1041
  }
542
1042
 
543
- if (!detail) {
544
- return `
545
- <section class="diff-file-block">
546
- <div class="diff-file-header">
547
- <span class="diff-file-path">${escapeHtml(currentFile.path)}</span>
548
- <span class="git-status-badge ${badgeClass(currentFile.status)}">${escapeHtml(currentFile.status)}</span>
549
- </div>
550
- <div class="diff-empty-state">Select a file to load its diff.</div>
551
- </section>
552
- `;
1043
+ const requestKey = `${filePath}:${forceFullPatch ? 'full' : 'partial'}`;
1044
+ if (this.fileLoadPromises.has(requestKey)) {
1045
+ return this.fileLoadPromises.get(requestKey);
553
1046
  }
554
1047
 
555
- if (detail.tooLarge) {
556
- return `
557
- <section class="diff-file-block">
558
- <div class="diff-file-header">
559
- <span class="diff-file-path">${escapeHtml(detail.path)}</span>
560
- <span class="git-status-badge ${badgeClass(detail.status)}">${escapeHtml(detail.status)}</span>
561
- <span class="diff-file-header-stats"><span class="diff-stats-add">+${detail.stats?.additions ?? 0}</span><span class="diff-stats-del">-${detail.stats?.deletions ?? 0}</span></span>
562
- </div>
563
- <div class="diff-limit-card">
564
- <strong>Large diff withheld</strong>
565
- <span>This file diff is large enough to impact rendering performance.</span>
566
- <button class="btn btn-secondary diff-load-full-btn" type="button" data-load-full-diff>Load full diff</button>
567
- </div>
568
- </section>
569
- `;
1048
+ this.loadingFiles.add(filePath);
1049
+ this.fileErrors.delete(filePath);
1050
+ if (render) {
1051
+ this.render();
570
1052
  }
571
1053
 
572
- return this.mode === 'split'
573
- ? this.renderSplitFile(detail, this.currentIndex)
574
- : this.renderUnifiedFile(detail, this.currentIndex);
1054
+ const requestPromise = (async () => {
1055
+ try {
1056
+ let detail;
1057
+ if (this.source === 'commit') {
1058
+ const query = new URLSearchParams();
1059
+ query.set('hash', this.commitHash || '');
1060
+ query.set('path', filePath);
1061
+ if (forceFullPatch) {
1062
+ query.set('allowLargePatch', 'true');
1063
+ }
1064
+
1065
+ const response = await fetch(resolveApiUrl(`/git/commit?${query.toString()}`));
1066
+ const data = await response.json();
1067
+ if (!response.ok) {
1068
+ throw new Error(data.error || 'Failed to load commit file diff');
1069
+ }
1070
+
1071
+ detail = {
1072
+ ...file,
1073
+ ...(data.files?.[0] ?? {}),
1074
+ };
1075
+ } else {
1076
+ const query = new URLSearchParams();
1077
+ query.set('scope', this.requestScope);
1078
+ query.set('path', filePath);
1079
+ if (forceFullPatch) {
1080
+ query.set('allowLargePatch', 'true');
1081
+ }
1082
+
1083
+ const response = await fetch(resolveApiUrl(`/git/diff?${query.toString()}`));
1084
+ const data = await response.json();
1085
+ if (!response.ok) {
1086
+ throw new Error(data.error || 'Failed to load file diff');
1087
+ }
1088
+
1089
+ detail = {
1090
+ ...file,
1091
+ ...(data.files?.[0] ?? {}),
1092
+ };
1093
+ }
1094
+
1095
+ if (cacheKey) {
1096
+ this.fileCache.set(cacheKey, detail);
1097
+ }
1098
+ this.fileErrors.delete(filePath);
1099
+ return detail;
1100
+ } catch (error) {
1101
+ console.error('[git-diff] Failed to load file diff:', error);
1102
+ const message = this.source === 'commit' ? 'Failed to load commit file diff' : 'Failed to load file diff';
1103
+ this.fileErrors.set(filePath, message);
1104
+ this.toastController?.show(message);
1105
+ return null;
1106
+ } finally {
1107
+ this.loadingFiles.delete(filePath);
1108
+ this.fileLoadPromises.delete(requestKey);
1109
+ this.render();
1110
+ }
1111
+ })();
1112
+
1113
+ this.fileLoadPromises.set(requestKey, requestPromise);
1114
+ return requestPromise;
575
1115
  }
576
1116
 
577
1117
  syncToolbar() {
578
1118
  const totalFiles = this.data?.files?.length ?? 0;
579
1119
  const visibleIndex = totalFiles === 0 ? 0 : this.currentIndex + 1;
1120
+ const isCommitSource = this.source === 'commit';
1121
+ const isStackedCommit = isCommitSource && this.layoutMode === 'stacked';
1122
+
580
1123
  if (this.fileIndicator) {
581
- this.fileIndicator.textContent = totalFiles > 0
582
- ? `${visibleIndex} / ${totalFiles} files`
583
- : '0 / 0 files';
1124
+ if (isStackedCommit) {
1125
+ this.fileIndicator.textContent = `${totalFiles} file${totalFiles === 1 ? '' : 's'}`;
1126
+ } else {
1127
+ this.fileIndicator.textContent = totalFiles > 0
1128
+ ? `${visibleIndex} / ${totalFiles} files`
1129
+ : '0 / 0 files';
1130
+ }
584
1131
  }
585
1132
 
586
1133
  if (this.stats) {
587
1134
  const additions = this.data?.summary?.additions ?? 0;
588
1135
  const deletions = this.data?.summary?.deletions ?? 0;
589
1136
  this.stats.innerHTML = `
590
- <span class="diff-stats-add">+${additions}</span>
591
- <span class="diff-stats-del">-${deletions}</span>
1137
+ <span class="ui-stat-token ui-stat-token--add diff-stats-add">+${additions}</span>
1138
+ <span class="ui-stat-token ui-stat-token--del diff-stats-del">-${deletions}</span>
592
1139
  `;
593
1140
  }
594
1141
 
595
1142
  this.modeButtons.forEach((button) => {
1143
+ button.classList.remove('hidden');
596
1144
  button.classList.toggle('active', button.getAttribute('data-diff-mode') === this.mode);
597
1145
  });
1146
+ this.layoutButtons.forEach((button) => {
1147
+ button.classList.toggle('active', button.getAttribute('data-diff-layout') === this.layoutMode);
1148
+ });
1149
+
598
1150
  const hasCurrentFile = Boolean(this.getCurrentFile()?.path);
599
1151
  const actionState = this.getCurrentActionState();
600
1152
  const primaryAction = this.getPrimaryAction();
601
- this.openEditorButton?.toggleAttribute('disabled', !hasCurrentFile);
1153
+
1154
+ this.backToHistoryButton?.classList.toggle('hidden', !isCommitSource);
1155
+ this.gitActionsGroup?.classList.toggle('hidden', isCommitSource);
1156
+ this.editorActionsGroup?.classList.toggle('hidden', isCommitSource);
1157
+ this.actionsDivider?.classList.toggle('hidden', isCommitSource);
1158
+ this.layoutToggle?.classList.toggle('hidden', !isCommitSource);
1159
+ this.stats?.classList.remove('hidden');
1160
+
1161
+ if (this.openEditorButton) {
1162
+ this.openEditorButton.textContent = 'Open in Editor';
1163
+ }
1164
+ this.openEditorButton?.toggleAttribute('disabled', !hasCurrentFile || isCommitSource);
602
1165
  if (this.primaryActionButton) {
603
1166
  this.primaryActionButton.textContent = this.pendingAction === primaryAction
604
1167
  ? 'Working...'
@@ -607,7 +1170,7 @@ export class GitDiffViewController {
607
1170
  : 'Stage';
608
1171
  this.primaryActionButton.toggleAttribute(
609
1172
  'disabled',
610
- !hasCurrentFile || !primaryAction || Boolean(this.pendingAction),
1173
+ isCommitSource || !hasCurrentFile || !primaryAction || Boolean(this.pendingAction),
611
1174
  );
612
1175
  }
613
1176
  if (this.commitButton) {
@@ -615,10 +1178,14 @@ export class GitDiffViewController {
615
1178
  }
616
1179
  this.commitButton?.toggleAttribute(
617
1180
  'disabled',
618
- !actionState.canCommit || Boolean(this.pendingAction),
1181
+ isCommitSource || !actionState.canCommit || Boolean(this.pendingAction),
619
1182
  );
620
- this.prevButton?.toggleAttribute('disabled', this.currentIndex <= 0);
621
- this.nextButton?.toggleAttribute('disabled', totalFiles === 0 || this.currentIndex >= totalFiles - 1);
1183
+ this.prevButton?.classList.remove('hidden');
1184
+ this.nextButton?.classList.remove('hidden');
1185
+ this.prevButton?.classList.toggle('hidden', isStackedCommit);
1186
+ this.nextButton?.classList.toggle('hidden', isStackedCommit);
1187
+ this.prevButton?.toggleAttribute('disabled', isStackedCommit || this.currentIndex <= 0);
1188
+ this.nextButton?.toggleAttribute('disabled', isStackedCommit || totalFiles === 0 || this.currentIndex >= totalFiles - 1);
622
1189
  }
623
1190
 
624
1191
  render() {
@@ -626,7 +1193,7 @@ export class GitDiffViewController {
626
1193
 
627
1194
  const files = this.data?.files ?? [];
628
1195
  if (files.length === 0) {
629
- this.renderEmpty('No changes to display.');
1196
+ this.renderEmpty(this.source === 'commit' ? 'No commit changes to display.' : 'No changes to display.');
630
1197
  return;
631
1198
  }
632
1199
 
@@ -634,11 +1201,41 @@ export class GitDiffViewController {
634
1201
  return;
635
1202
  }
636
1203
 
637
- this.content.innerHTML = this.renderCurrentFile();
1204
+ if (this.source === 'commit') {
1205
+ this.content.innerHTML = `${this.renderCommitHeader()}${this.renderCommitBody()}`;
1206
+ } else {
1207
+ this.content.innerHTML = this.renderFocusedFileBody();
1208
+ }
638
1209
  this.syncToolbar();
639
1210
  }
640
1211
 
641
- getToolbarTitle({ filePath = null, scope = 'all' } = {}) {
1212
+ getToolbarTitle({ commitHash = null, filePath = null, path = null, scope = 'all', source = 'workspace' } = {}) {
1213
+ if (source === 'commit' || this.source === 'commit') {
1214
+ if (this.layoutMode === 'stacked') {
1215
+ if (this.commitMeta?.shortHash) {
1216
+ return `Commit ${this.commitMeta.shortHash}`;
1217
+ }
1218
+ if (commitHash) {
1219
+ return `Commit ${String(commitHash).slice(0, 7)}`;
1220
+ }
1221
+ return 'Commit Diff';
1222
+ }
1223
+
1224
+ if (path) {
1225
+ return getPathLeaf(path);
1226
+ }
1227
+ if (this.activeFilePath) {
1228
+ return getPathLeaf(this.activeFilePath);
1229
+ }
1230
+ if (this.commitMeta?.shortHash) {
1231
+ return `Commit ${this.commitMeta.shortHash}`;
1232
+ }
1233
+ if (commitHash) {
1234
+ return `Commit ${String(commitHash).slice(0, 7)}`;
1235
+ }
1236
+ return 'Commit Diff';
1237
+ }
1238
+
642
1239
  if (filePath) {
643
1240
  return getPathLeaf(filePath);
644
1241
  }