@hienlh/ppm 0.20.10 → 0.21.0

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 (982) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/CLAUDE.md +42 -1
  3. package/LICENSE +5 -0
  4. package/THIRD-PARTY-NOTICES.md +83 -0
  5. package/assets/skills/ppm/SKILL.md +1 -1
  6. package/assets/skills/ppm/references/cli-reference.md +4 -4
  7. package/assets/skills/ppm/references/http-api.md +1 -1
  8. package/bun.lock +38 -7
  9. package/dist/web/assets/KaTeX_Size3-Regular-gV2CO0n9.woff2 +0 -0
  10. package/dist/web/assets/accounts-settings-section-BuxD9zH3.js +1 -0
  11. package/dist/web/assets/ai-resource-editor-F09pf8Hd.js +1 -0
  12. package/dist/web/assets/ai-settings-section-Dd9tOUp0.js +1 -0
  13. package/dist/web/assets/ai-settings-section-FrU2X8Fu.js +1 -0
  14. package/dist/web/assets/{angular-html-D4qjt-75.js → angular-html-DkR4iCth.js} +1 -1
  15. package/dist/web/assets/{angular-ts-DvLn04T8.js → angular-ts-DcyL4Chx.js} +1 -1
  16. package/dist/web/assets/api-client-BUCo1lms.js +1 -0
  17. package/dist/web/assets/{api-client-DCzgxFNY.js → api-client-bfB7cXRM.js} +1 -1
  18. package/dist/web/assets/{api-settings-t5xLrBkQ.js → api-settings-BcNjZIvG.js} +1 -1
  19. package/dist/web/assets/{api-themes-CJmyQeMk.js → api-themes-DBfyVUtX.js} +1 -1
  20. package/dist/web/assets/{apl-DQOoPzqd.js → apl-BVlrVtjt.js} +1 -1
  21. package/dist/web/assets/appearance-settings-section-whgnq3ss.js +1 -0
  22. package/dist/web/assets/architecture-PBZL5I3N-5K0wEkAn.js +1 -0
  23. package/dist/web/assets/{astro-C2zFJ1Er.js → astro-MjJlozLj.js} +1 -1
  24. package/dist/web/assets/audio-preview-Bc54GCAV.js +1 -0
  25. package/dist/web/assets/{blade-CBD8sEa1.js → blade-DnJWi1fz.js} +1 -1
  26. package/dist/web/assets/{bsl-bs2JpeTQ.js → bsl-DCmJxSIz.js} +1 -1
  27. package/dist/web/assets/{button-DHI8IY_N.js → button-VW4QGKCn.js} +1 -1
  28. package/dist/web/assets/{cairo-DT2g4i_6.js → cairo-C8dDenub.js} +1 -1
  29. package/dist/web/assets/chat-tab-Cr6_KSGO.js +15 -0
  30. package/dist/web/assets/{cobol-B2rp6LA1.js → cobol-DPx_nifl.js} +1 -1
  31. package/dist/web/assets/code-editor-DfmlGamv.js +7 -0
  32. package/dist/web/assets/codex-daily-guard-CfybHv_c.js +1 -0
  33. package/dist/web/assets/{coffee-D5ShQC08.js → coffee-DvFzqhgN.js} +1 -1
  34. package/dist/web/assets/conflict-editor-DenQUOT2.js +19 -0
  35. package/dist/web/assets/context-menu-DOODKZdF.js +1 -0
  36. package/dist/web/assets/{cpp-BmKOH-E0.js → cpp-BLJN0umi.js} +1 -1
  37. package/dist/web/assets/{createLucideIcon-CLMdC3Kl.js → createLucideIcon-DoiEKeJ_.js} +1 -1
  38. package/dist/web/assets/{crystal-B7u_ZTpu.js → crystal-BXR-9fGw.js} +1 -1
  39. package/dist/web/assets/csv-preview-CClrJOuR.js +2 -0
  40. package/dist/web/assets/{data-grid-overlay-editor-DJWgclot.js → data-grid-overlay-editor-D4fhcMfT.js} +1 -1
  41. package/dist/web/assets/{data-grid-types-Uu77aFvI.js → data-grid-types-OgUxMLdQ.js} +1 -1
  42. package/dist/web/assets/database-viewer-DItjm8wB.js +1 -0
  43. package/dist/web/assets/dialog-DQTn55Mt.js +1 -0
  44. package/dist/web/assets/diff-viewer-BpNj7pN9.js +4 -0
  45. package/dist/web/assets/{dist-BTdRgQig.js → dist-CrBOCtCW.js} +1 -1
  46. package/dist/web/assets/docx-preview-DYBkiUaE.js +12 -0
  47. package/dist/web/assets/{edge--MpXROh5.js → edge-rWOlCmXT.js} +1 -1
  48. package/dist/web/assets/{edit-diff-preview-ESj6hMoD.js → edit-diff-preview-COtmo54G.js} +3 -3
  49. package/dist/web/assets/editor-font-BDrdiGf1.js +1 -0
  50. package/dist/web/assets/editor-language-service-DxkZ51E5.js +1 -0
  51. package/dist/web/assets/{elixir-DL8mOfzH.js → elixir-E7Y82okW.js} +1 -1
  52. package/dist/web/assets/{elm-eVlzIFEZ.js → elm-DTPGbc-w.js} +1 -1
  53. package/dist/web/assets/{erb-BgvaH9l0.js → erb-DHqLHrE6.js} +1 -1
  54. package/dist/web/assets/{erlang-CEf8Sfhs.js → erlang-Byg0nNiV.js} +1 -1
  55. package/dist/web/assets/{esm-C5xqy163.js → esm-D_DmOM7n.js} +2 -2
  56. package/dist/web/assets/explorer-body-D-5z464e.js +2 -0
  57. package/dist/web/assets/explorer-window-content-7-1wuRul.js +1 -0
  58. package/dist/web/assets/extension-manager-section-BhwB6nqr.js +1 -0
  59. package/dist/web/assets/extension-webview-DI4VL2tJ.js +12 -0
  60. package/dist/web/assets/file-icons-EzPL0q-k.js +1 -0
  61. package/dist/web/assets/file-icons.generated-CfaJuvZu.css +1 -0
  62. package/dist/web/assets/file-store-DMABxOkV.js +1 -0
  63. package/dist/web/assets/files-settings-section-CZzABuKz.js +1 -0
  64. package/dist/web/assets/format-file-meta-DOpzJJhS.js +1 -0
  65. package/dist/web/assets/{fortran-fixed-form-yAUsSjab.js → fortran-fixed-form-CY1n0Xf6.js} +1 -1
  66. package/dist/web/assets/{fsharp-BEWvY_ZR.js → fsharp-_vEDSCJz.js} +1 -1
  67. package/dist/web/assets/{gdresource-CYZFZ057.js → gdresource-B6XT0wAC.js} +1 -1
  68. package/dist/web/assets/geist-cyrillic-ext-wght-italic-BYAq_K0C.woff2 +0 -0
  69. package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  70. package/dist/web/assets/geist-cyrillic-wght-italic-Da0gXVk3.woff2 +0 -0
  71. package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  72. package/dist/web/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
  73. package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  74. package/dist/web/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
  75. package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  76. package/dist/web/assets/geist-vietnamese-wght-italic-0fly6zkB.woff2 +0 -0
  77. package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  78. package/dist/web/assets/general-settings-section-BcxwiZ0X.js +1 -0
  79. package/dist/web/assets/{git-commit-DedchUJ6.js → git-commit-Wk9ovq59.js} +1 -1
  80. package/dist/web/assets/git-log-panel-CRN4JVOx.js +1 -0
  81. package/dist/web/assets/{git-rebase-DPvHNzQr.js → git-rebase-DSarGPvK.js} +1 -1
  82. package/dist/web/assets/git-repo-store-Dy69YCHN.js +1 -0
  83. package/dist/web/assets/gitGraph-HDMCJU4V-DkVT2MAM.js +1 -0
  84. package/dist/web/assets/glide-data-grid-BvgAqSUr.js +141 -0
  85. package/dist/web/assets/{glimmer-js-B4hPYBMX.js → glimmer-js-CkYI35_P.js} +1 -1
  86. package/dist/web/assets/{glimmer-ts-C0WfcQnO.js → glimmer-ts-BqmIZcds.js} +1 -1
  87. package/dist/web/assets/{glsl-DHW88hTv.js → glsl-Be-yBCF5.js} +1 -1
  88. package/dist/web/assets/{graphql-CEvXbo6e.js → graphql-a5DrENHY.js} +1 -1
  89. package/dist/web/assets/group-chat-tab-DFa5mAx5.js +1 -0
  90. package/dist/web/assets/{hack-lKfhn1vw.js → hack-BLAg20aD.js} +1 -1
  91. package/dist/web/assets/{haml-AjKlANaB.js → haml-Dj6bGOQH.js} +1 -1
  92. package/dist/web/assets/{handlebars-B8fZzj2G.js → handlebars-dmEa36Oh.js} +1 -1
  93. package/dist/web/assets/{html-derivative-VZmoMdQD.js → html-derivative-lLi3-RNT.js} +1 -1
  94. package/dist/web/assets/{html-H_S3FJMj.js → html-yacZYzSE.js} +1 -1
  95. package/dist/web/assets/{http-DBxROFKc.js → http-1KaxcE4e.js} +1 -1
  96. package/dist/web/assets/{hurl-Hf7XWQHN.js → hurl-ST-dEEZR.js} +1 -1
  97. package/dist/web/assets/{hxml-BRhRKwSo.js → hxml-CpDtuq__.js} +1 -1
  98. package/dist/web/assets/icons-DQjqk0lJ.js +1 -0
  99. package/dist/web/assets/image-preview-CJVxL0uH.js +1 -0
  100. package/dist/web/assets/index-D7DbXD3G.css +1 -0
  101. package/dist/web/assets/index-ZtfxZOyb.js +52 -0
  102. package/dist/web/assets/info-3K5VOQVL-BBsmKGzA.js +1 -0
  103. package/dist/web/assets/input-D-dR8RI6.js +1 -0
  104. package/dist/web/assets/{jinja-D3jMH0jG.js → jinja-Cjw-evAn.js} +1 -1
  105. package/dist/web/assets/{jira-watcher-section-DZvWeUAW.js → jira-watcher-section-DIC1yIV3.js} +1 -1
  106. package/dist/web/assets/{jison-CZtpkLiY.js → jison-DfATMYoY.js} +1 -1
  107. package/dist/web/assets/{julia-DwFjOpos.js → julia-DDCaxiqT.js} +1 -1
  108. package/dist/web/assets/{just-BEfj8dHN.js → just-CJL529u6.js} +1 -1
  109. package/dist/web/assets/keybindings-store-tVfhPANS.js +1 -0
  110. package/dist/web/assets/keyboard-shortcuts-section-BW03P3AF.js +1 -0
  111. package/dist/web/assets/{latex-C6Rb_zGG.js → latex-Zc4EpLpW.js} +1 -1
  112. package/dist/web/assets/{lib-CFTK00ux.js → lib-BVwmtv2i.js} +1 -1
  113. package/dist/web/assets/{liquid-DTVs9cD3.js → liquid-B_6KMNYS.js} +1 -1
  114. package/dist/web/assets/{lua-C1zfiqhG.js → lua-BtS2idK7.js} +1 -1
  115. package/dist/web/assets/markdown-renderer-CvL1pWeK.js +3 -0
  116. package/dist/web/assets/markdown-renderer-sJNNVhlS.js +1 -0
  117. package/dist/web/assets/{marko-_hrXozl2.js → marko-Wk6LBnck.js} +1 -1
  118. package/dist/web/assets/{mdc-AX9XWu8K.js → mdc-cRaXBrzL.js} +1 -1
  119. package/dist/web/assets/{media-url-D43IHXnP.js → media-url-DL8OCGGg.js} +1 -1
  120. package/dist/web/assets/{mobile-bottom-sheet-GSto0_0m.js → mobile-bottom-sheet-CoUauvLF.js} +1 -1
  121. package/dist/web/assets/mobile-explorer-sheet-CZ0HZ2E_.js +1 -0
  122. package/dist/web/assets/monaco-dotenv-language-BDYnKcnr.js +1 -0
  123. package/dist/web/assets/monaspace-argon-latin-400-italic-DHf095HZ.woff2 +0 -0
  124. package/dist/web/assets/monaspace-argon-latin-400-italic-DZMiIHEH.woff +0 -0
  125. package/dist/web/assets/monaspace-argon-latin-400-normal-DZUN4ACH.woff +0 -0
  126. package/dist/web/assets/monaspace-argon-latin-400-normal-RS-2TGNg.woff2 +0 -0
  127. package/dist/web/assets/monaspace-argon-latin-700-normal-4y--rLW1.woff +0 -0
  128. package/dist/web/assets/monaspace-argon-latin-700-normal-D9kWRRK5.woff2 +0 -0
  129. package/dist/web/assets/monaspace-krypton-latin-400-italic-BoBCEexI.woff2 +0 -0
  130. package/dist/web/assets/monaspace-krypton-latin-400-italic-LWEicbvC.woff +0 -0
  131. package/dist/web/assets/monaspace-krypton-latin-400-normal-D9XlxC9R.woff +0 -0
  132. package/dist/web/assets/monaspace-krypton-latin-400-normal-DsuVXUab.woff2 +0 -0
  133. package/dist/web/assets/nerd-symbols-codicons-DSvMY_FK.woff2 +0 -0
  134. package/dist/web/assets/nerd-symbols-devicons-BBab8P54.woff2 +0 -0
  135. package/dist/web/assets/nerd-symbols-font-awesome-BzNW1pRA.woff2 +0 -0
  136. package/dist/web/assets/nerd-symbols-font-awesome-ext-D30e--UY.woff2 +0 -0
  137. package/dist/web/assets/nerd-symbols-font-awesome-legacy-D_qekXx9.woff2 +0 -0
  138. package/dist/web/assets/nerd-symbols-font-logos-gdu3INfy.woff2 +0 -0
  139. package/dist/web/assets/nerd-symbols-iec-power-Cw6TNeDf.woff2 +0 -0
  140. package/dist/web/assets/nerd-symbols-material-l-CXi9Ay.woff2 +0 -0
  141. package/dist/web/assets/nerd-symbols-misc-BaVfdyeB.woff2 +0 -0
  142. package/dist/web/assets/nerd-symbols-octicons-CJLTTzKm.woff2 +0 -0
  143. package/dist/web/assets/nerd-symbols-pomicons-D7T3Ya3H.woff2 +0 -0
  144. package/dist/web/assets/nerd-symbols-powerline-Cgg0sdGS.woff2 +0 -0
  145. package/dist/web/assets/nerd-symbols-seti-DYiUFq6z.woff2 +0 -0
  146. package/dist/web/assets/nerd-symbols-weather-D4Jrp5XD.woff2 +0 -0
  147. package/dist/web/assets/{nextflow-xJ5dkaQ2.js → nextflow-Bos2wvDV.js} +1 -1
  148. package/dist/web/assets/{nginx-BfbjvmIV.js → nginx-DMlOwzdr.js} +1 -1
  149. package/dist/web/assets/{nim-KrUnNSwZ.js → nim-D2dZQA88.js} +1 -1
  150. package/dist/web/assets/notification-store-BZbsPnW0.js +1 -0
  151. package/dist/web/assets/notifications-settings-section-DPUROMw-.js +1 -0
  152. package/dist/web/assets/{number-overlay-editor-CGZ1ObrN.js → number-overlay-editor-DZ2i_Bnb.js} +1 -1
  153. package/dist/web/assets/{overview-panel-Ni1Wqr3E.js → overview-panel-R146OIom.js} +1 -1
  154. package/dist/web/assets/packet-RMMSAZCW-DwmYPOlx.js +1 -0
  155. package/dist/web/assets/panel-store-BVLBRn6M.js +1 -0
  156. package/dist/web/assets/pdf-preview-BWUPGLp6.js +1 -0
  157. package/dist/web/assets/{perl-DAexWIeo.js → perl-C5-Z6fPn.js} +1 -1
  158. package/dist/web/assets/{php-DXc7GdU9.js → php-BXNNhkMH.js} +1 -1
  159. package/dist/web/assets/pie-UPGHQEXC-D0oogIFi.js +1 -0
  160. package/dist/web/assets/portal-container-context-BarKmT4S.js +1 -0
  161. package/dist/web/assets/{postgres-viewer-DmbVhmJ8.js → postgres-viewer-CjOvaruz.js} +3 -3
  162. package/dist/web/assets/ppmbot-settings-section-DrvWh8l8.js +1 -0
  163. package/dist/web/assets/problems-panel-B7BWVhdy.js +1 -0
  164. package/dist/web/assets/process-table-BRMS1MrX.js +1 -0
  165. package/dist/web/assets/{project-store-DCDLF-x3.js → project-store-BhMbVln3.js} +1 -1
  166. package/dist/web/assets/proxy-settings-section-Bv0Ny-Yy.js +1 -0
  167. package/dist/web/assets/{pug-CHds8FDl.js → pug-C1zf1yWy.js} +1 -1
  168. package/dist/web/assets/{qml-DBt6oNnU.js → qml-OW58jGpD.js} +1 -1
  169. package/dist/web/assets/query-audit-section-BcHJZcVC.js +1 -0
  170. package/dist/web/assets/radar-KQ55EAFF-CQIJOQGa.js +1 -0
  171. package/dist/web/assets/{razor-DVDe2z8Z.js → razor-DzjSaobM.js} +1 -1
  172. package/dist/web/assets/{react-Bf5xrFLG.js → react-Bghu0NUO.js} +1 -1
  173. package/dist/web/assets/remote-desktop-mobile-sheet-ByjaeZKX.js +2 -0
  174. package/dist/web/assets/remote-desktop-mobile-view-D13mtr9F.js +1 -0
  175. package/dist/web/assets/remote-desktop-readiness-gate-BTzss2wX.js +1 -0
  176. package/dist/web/assets/remote-desktop-window-content-CbqTCaC6.js +1 -0
  177. package/dist/web/assets/{rst-s3rP0H8p.js → rst-RfuihOUW.js} +1 -1
  178. package/dist/web/assets/{ruby-sRcfbjlr.js → ruby-CNO3pli1.js} +1 -1
  179. package/dist/web/assets/{run-in-terminal-Yt_lq4T9.js → run-in-terminal-Cb_hVU8x.js} +1 -1
  180. package/dist/web/assets/{sas-CuyZeQJw.js → sas-DZY5BtXx.js} +1 -1
  181. package/dist/web/assets/schedules-settings-section-DO8xAOVj.js +1 -0
  182. package/dist/web/assets/scroll-area-LtNV8g5o.js +1 -0
  183. package/dist/web/assets/{scss-B9m4FneT.js → scss--4g-REcN.js} +1 -1
  184. package/dist/web/assets/{send-to-chat-01eMNs3j.js → send-to-chat-Cnpru1M0.js} +1 -1
  185. package/dist/web/assets/separator-Cds1yxy8.js +1 -0
  186. package/dist/web/assets/settings-body-Rnu-FcX-.js +2 -0
  187. package/dist/web/assets/settings-store-DZPgPtEA.js +2 -0
  188. package/dist/web/assets/settings-tab-C6PHxs0Z.js +1 -0
  189. package/dist/web/assets/settings-window-content-CQ4gT2qj.js +1 -0
  190. package/dist/web/assets/{shaderlab-BuCltaXx.js → shaderlab-Cu4sBiVn.js} +1 -1
  191. package/dist/web/assets/{shellsession-DG_WIFRW.js → shellsession-DWzJfEv7.js} +1 -1
  192. package/dist/web/assets/{soy-CKNCwmqR.js → soy-BnqE-5Ff.js} +1 -1
  193. package/dist/web/assets/{sparql-BEH92-9e.js → sparql-Ctg__NhZ.js} +1 -1
  194. package/dist/web/assets/{sql-query-editor-BTMEy88p.js → sql-query-editor-D9k19T_M.js} +1 -1
  195. package/dist/web/assets/sqlite-viewer-DoV9hnWJ.js +1 -0
  196. package/dist/web/assets/{stata-Bt5IUWCl.js → stata-Qk2h66XW.js} +1 -1
  197. package/dist/web/assets/{streaming-store-Dw3ZR1E4.js → streaming-store-uDu3PoN1.js} +1 -1
  198. package/dist/web/assets/{surrealql-B5M94PT2.js → surrealql-8QEX7EfH.js} +1 -1
  199. package/dist/web/assets/{svelte-BqLoF5fB.js → svelte-D_mubC5-.js} +1 -1
  200. package/dist/web/assets/system-monitor-body-2vQ1kMxE.js +2 -0
  201. package/dist/web/assets/system-monitor-tab-krAcvwF7.js +1 -0
  202. package/dist/web/assets/system-monitor-window-content-qXLcicFM.js +1 -0
  203. package/dist/web/assets/tab-host-window-content-7fPZNEni.js +1 -0
  204. package/dist/web/assets/{tab-store-Dsk4jnlN.js → tab-store-DGJGnbwv.js} +1 -1
  205. package/dist/web/assets/team-member-sheet-2FnRmk1a.js +2 -0
  206. package/dist/web/assets/team-member-window-content-BgvJFypM.js +1 -0
  207. package/dist/web/assets/{templ-BxGWIwYz.js → templ-C1jV0fsO.js} +1 -1
  208. package/dist/web/assets/terminal-tab-Cs0sGljx.js +3 -0
  209. package/dist/web/assets/{tex-B9CPrNBA.js → tex-D_StFXy_.js} +1 -1
  210. package/dist/web/assets/tool-cards-DU_S2o51.js +9 -0
  211. package/dist/web/assets/treemap-KZPCXAKY-BhEtjljr.js +1 -0
  212. package/dist/web/assets/{ts-tags-CObhnP_s.js → ts-tags-B5m47rEm.js} +1 -1
  213. package/dist/web/assets/{twig-ZcDaz0E8.js → twig-C_br6GIl.js} +1 -1
  214. package/dist/web/assets/{use-blob-url-D-NnFGAr.js → use-blob-url-C-SGi_Hb.js} +1 -1
  215. package/dist/web/assets/use-inline-blame-B4trxGcR.js +16 -0
  216. package/dist/web/assets/{use-is-mobile-BsqeOLv4.js → use-is-mobile-BQ9Bv5Ga.js} +1 -1
  217. package/dist/web/assets/use-lsp-CV0vzILO.js +6 -0
  218. package/dist/web/assets/use-monaco-theme-DBqbWjWX.js +1 -0
  219. package/dist/web/assets/use-open-team-member-DENsjp0s.js +1 -0
  220. package/dist/web/assets/use-remote-desktop-display-choice-BK_f787P.js +1 -0
  221. package/dist/web/assets/{use-visual-viewport-hdC_hRtB.js → use-visual-viewport-CbwnktSG.js} +1 -1
  222. package/dist/web/assets/{use-websocket-CUKjQFAl.js → use-websocket-LgXiX1qN.js} +1 -1
  223. package/dist/web/assets/vendor-markdown-CuWCHIVb.js +291 -0
  224. package/dist/web/assets/{vendor-mermaid-BoRFiriK.js → vendor-mermaid-Cbig5zA6.js} +1 -1
  225. package/dist/web/assets/{vendor-ui-D1NQnrtd.js → vendor-ui-BBdkypKW.js} +1 -1
  226. package/dist/web/assets/video-preview-BDNwumbW.js +1 -0
  227. package/dist/web/assets/{vue-TgfQfAF8.js → vue-DQwCnLdr.js} +1 -1
  228. package/dist/web/assets/{vue-html-DbAh9aHW.js → vue-html-T_EoGpPJ.js} +1 -1
  229. package/dist/web/assets/{vue-vine-DQ8US6vO.js → vue-vine-DmxLqX50.js} +1 -1
  230. package/dist/web/assets/{window-pip-registry-DfPfSFQg.js → window-pip-registry-3l4hoxuD.js} +1 -1
  231. package/dist/web/assets/{window-store-BSXqIkwB.js → window-store-UC1jJeLM.js} +1 -1
  232. package/dist/web/assets/ws-auth-DEAJiGCR.js +1 -0
  233. package/dist/web/assets/{xml-CXzUNYMl.js → xml-Bs6Bw8is.js} +1 -1
  234. package/dist/web/assets/{xsl-CdnFww1s.js → xsl-f5ZNhRCc.js} +1 -1
  235. package/dist/web/index.html +107 -73
  236. package/dist/web/sw.js +1 -1
  237. package/docs/project-roadmap.md +2 -0
  238. package/licenses/Apache-2.0.txt +73 -0
  239. package/licenses/CC-BY-4.0.txt +156 -0
  240. package/licenses/MIT.txt +18 -0
  241. package/licenses/OFL-1.1.txt +43 -0
  242. package/licenses/Unlicense.txt +10 -0
  243. package/package.json +14 -7
  244. package/packages/ext-git-graph/src/blame-view.ts +4 -5
  245. package/packages/ext-git-graph/src/commit-detail-escaping.test.ts +205 -0
  246. package/packages/ext-git-graph/src/commit-detail-file-cap.test.ts +65 -0
  247. package/packages/ext-git-graph/src/commit-message-html.test.ts +214 -0
  248. package/packages/ext-git-graph/src/commit-message-html.ts +190 -0
  249. package/packages/ext-git-graph/src/commit-request-generation.test.ts +57 -0
  250. package/packages/ext-git-graph/src/compare-view.ts +4 -5
  251. package/packages/ext-git-graph/src/extension.ts +148 -36
  252. package/packages/ext-git-graph/src/file-history-view.ts +4 -5
  253. package/packages/ext-git-graph/src/log-args.test.ts +57 -0
  254. package/packages/ext-git-graph/src/ppm-api.ts +39 -6
  255. package/packages/ext-git-graph/src/project-scope.test.ts +77 -0
  256. package/packages/ext-git-graph/src/project-scope.ts +69 -0
  257. package/packages/ext-git-graph/src/shortstat-parser.test.ts +53 -0
  258. package/packages/ext-git-graph/src/shortstat-parser.ts +45 -0
  259. package/packages/ext-git-graph/src/types.ts +2 -0
  260. package/packages/ext-git-graph/src/webview-html.test.ts +407 -0
  261. package/packages/ext-git-graph/src/webview-html.ts +631 -108
  262. package/packages/ext-git-graph/src/webview-shell.test.ts +63 -0
  263. package/packages/ext-git-graph/src/webview-shell.ts +48 -7
  264. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  265. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  266. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  267. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
  268. package/scripts/check-ppm-dir-usage.sh +0 -0
  269. package/scripts/copy-monaco.ts +63 -0
  270. package/scripts/gen-file-icons.ts +485 -0
  271. package/scripts/gen-nerd-font.ts +311 -0
  272. package/scripts/gen-product-icons.ts +442 -0
  273. package/scripts/install.sh +0 -0
  274. package/scripts/monaco-staging.ts +32 -0
  275. package/scripts/precompress-web.ts +77 -0
  276. package/scripts/release.sh +0 -0
  277. package/scripts/third-party-notices.ts +160 -0
  278. package/scripts/vite-monaco-dev-assets.ts +63 -0
  279. package/src/providers/claude-agent-sdk.ts +32 -2
  280. package/src/server/index.ts +17 -0
  281. package/src/server/routes/chat.ts +16 -6
  282. package/src/server/routes/git.ts +113 -1
  283. package/src/server/routes/lsp.ts +58 -0
  284. package/src/server/routes/project-scoped.ts +2 -0
  285. package/src/server/routes/static-encoding.ts +73 -0
  286. package/src/server/routes/static-fallback.ts +51 -0
  287. package/src/server/routes/static.ts +41 -5
  288. package/src/server/ws/lsp.ts +433 -0
  289. package/src/services/chat-search.service.ts +211 -26
  290. package/src/services/edge-forwarder.ts +191 -191
  291. package/src/services/fs-ops/fs-real-path.ts +23 -0
  292. package/src/services/git-blame/commit-line-diff.ts +124 -0
  293. package/src/services/git-blame/git-blame.service.ts +96 -1
  294. package/src/services/git-repos/git-repo-discovery.ts +152 -0
  295. package/src/services/lsp/lsp-capabilities.ts +160 -0
  296. package/src/services/lsp/lsp-manager.ts +442 -0
  297. package/src/services/lsp/lsp-protocol.ts +170 -0
  298. package/src/services/lsp/lsp-session.ts +466 -0
  299. package/src/services/lsp/server-registry.ts +401 -0
  300. package/src/services/search-index-db.service.ts +10 -2
  301. package/src/services/windows-process-tree.ts +351 -351
  302. package/src/shared/blame.ts +51 -0
  303. package/src/shared/lsp-uri.ts +108 -0
  304. package/src/web/app.tsx +6 -0
  305. package/src/web/components/ai-resources/ai-resource-editor.tsx +1 -1
  306. package/src/web/components/ai-resources/ai-resources-panel.tsx +1 -1
  307. package/src/web/components/ai-resources/mcp-group.tsx +1 -1
  308. package/src/web/components/ai-resources/new-resource-menu.tsx +1 -1
  309. package/src/web/components/ai-resources/resource-visuals.tsx +1 -1
  310. package/src/web/components/auth/login-screen.tsx +1 -1
  311. package/src/web/components/auth/support-dialog.tsx +1 -1
  312. package/src/web/components/chat/attachment-chips.tsx +113 -5
  313. package/src/web/components/chat/background-command-bar.tsx +1 -1
  314. package/src/web/components/chat/background-output-panel.tsx +1 -1
  315. package/src/web/components/chat/change-edit-list.tsx +1 -1
  316. package/src/web/components/chat/change-file-row.tsx +1 -1
  317. package/src/web/components/chat/chat-history-bar.tsx +2 -2
  318. package/src/web/components/chat/chat-history-panel.tsx +1 -1
  319. package/src/web/components/chat/chat-placeholder.tsx +1 -1
  320. package/src/web/components/chat/chat-scroll-nav.tsx +1 -1
  321. package/src/web/components/chat/chat-tab.tsx +1 -1
  322. package/src/web/components/chat/chat-toolbar-overflow-menu.tsx +1 -1
  323. package/src/web/components/chat/chat-welcome.tsx +1 -1
  324. package/src/web/components/chat/codex-usage-panel.tsx +1 -1
  325. package/src/web/components/chat/file-picker.tsx +1 -1
  326. package/src/web/components/chat/image-preview-states.tsx +1 -1
  327. package/src/web/components/chat/message-action-bar.tsx +1 -1
  328. package/src/web/components/chat/message-input.tsx +1 -1
  329. package/src/web/components/chat/message-list.tsx +1 -1
  330. package/src/web/components/chat/mode-selector.tsx +1 -1
  331. package/src/web/components/chat/model-selector.tsx +1 -1
  332. package/src/web/components/chat/model-thinking-selector.tsx +1 -1
  333. package/src/web/components/chat/pre-compact-button.tsx +1 -1
  334. package/src/web/components/chat/provider-selector.tsx +1 -1
  335. package/src/web/components/chat/send-message-card.tsx +1 -1
  336. package/src/web/components/chat/session-context-menu.tsx +1 -1
  337. package/src/web/components/chat/session-debug-dialog.tsx +1 -1
  338. package/src/web/components/chat/session-history-list.tsx +1 -1
  339. package/src/web/components/chat/session-list-panel.tsx +1 -1
  340. package/src/web/components/chat/session-picker.tsx +1 -1
  341. package/src/web/components/chat/slash-command-picker.tsx +1 -1
  342. package/src/web/components/chat/task-tracker.tsx +1 -1
  343. package/src/web/components/chat/team-activity-panel.tsx +1 -1
  344. package/src/web/components/chat/team-member-activity-row.tsx +1 -1
  345. package/src/web/components/chat/team-member-list.tsx +1 -1
  346. package/src/web/components/chat/team-member-sheet.tsx +1 -1
  347. package/src/web/components/chat/team-member-window-content.tsx +1 -1
  348. package/src/web/components/chat/team-working-bar.tsx +1 -1
  349. package/src/web/components/chat/tool-cards.tsx +2 -2
  350. package/src/web/components/chat/turn-change-sheet.tsx +1 -1
  351. package/src/web/components/chat/turn-change-tray.tsx +1 -1
  352. package/src/web/components/chat/turn-cost-warning.tsx +1 -1
  353. package/src/web/components/chat/usage-badge.tsx +1 -1
  354. package/src/web/components/chat/usage-panel-shell.tsx +1 -1
  355. package/src/web/components/chat/version-switcher.tsx +1 -1
  356. package/src/web/components/database/connection-import-export.tsx +1 -1
  357. package/src/web/components/database/connection-list.tsx +1 -1
  358. package/src/web/components/database/connection-row.tsx +1 -1
  359. package/src/web/components/database/database-sidebar.tsx +1 -1
  360. package/src/web/components/database/database-viewer.tsx +1 -1
  361. package/src/web/components/database/export-button.tsx +1 -1
  362. package/src/web/components/database/glide-context-menu.tsx +1 -1
  363. package/src/web/components/database/glide-data-grid.tsx +1 -1
  364. package/src/web/components/database/glide-data-preview-panel.tsx +2 -2
  365. package/src/web/components/database/glide-grid-pagination.tsx +1 -1
  366. package/src/web/components/database/glide-grid-toolbar.tsx +1 -1
  367. package/src/web/components/database/glide-header-menu.tsx +1 -1
  368. package/src/web/components/database/glide-save-bar.tsx +1 -1
  369. package/src/web/components/database/schema-table-tree.tsx +1 -1
  370. package/src/web/components/editor/audio-preview.tsx +1 -1
  371. package/src/web/components/editor/code-editor.tsx +167 -21
  372. package/src/web/components/editor/compare-picker.tsx +1 -1
  373. package/src/web/components/editor/conflict-editor.tsx +15 -6
  374. package/src/web/components/editor/csv-preview.tsx +1 -1
  375. package/src/web/components/editor/diff-viewer.tsx +59 -37
  376. package/src/web/components/editor/docx-preview.tsx +1 -1
  377. package/src/web/components/editor/editor-breadcrumb-external.tsx +1 -1
  378. package/src/web/components/editor/editor-breadcrumb.tsx +1 -1
  379. package/src/web/components/editor/editor-language-picker.tsx +3 -1
  380. package/src/web/components/editor/editor-language-service.tsx +77 -0
  381. package/src/web/components/editor/editor-mobile-toolbar.tsx +13 -2
  382. package/src/web/components/editor/editor-placeholder.tsx +1 -1
  383. package/src/web/components/editor/editor-toolbar.tsx +1 -1
  384. package/src/web/components/editor/image-preview.tsx +1 -1
  385. package/src/web/components/editor/lsp-status.tsx +241 -0
  386. package/src/web/components/editor/pdf-preview.tsx +1 -1
  387. package/src/web/components/editor/video-player/video-player-controls.tsx +1 -1
  388. package/src/web/components/editor/video-player/video-player.tsx +1 -1
  389. package/src/web/components/editor/video-player/video-settings-menu.tsx +1 -1
  390. package/src/web/components/editor/video-preview.tsx +1 -1
  391. package/src/web/components/explorer/file-tree.tsx +1 -1
  392. package/src/web/components/explorer/inline-tree-input.tsx +1 -1
  393. package/src/web/components/explorer/search-panel.tsx +3 -2
  394. package/src/web/components/explorer/tree-node-context-menu.tsx +1 -1
  395. package/src/web/components/explorer/tree-node.tsx +5 -12
  396. package/src/web/components/extensions/extension-quickpick.tsx +1 -1
  397. package/src/web/components/extensions/extension-tree-view.tsx +1 -1
  398. package/src/web/components/extensions/extension-webview.tsx +53 -20
  399. package/src/web/components/extensions/webview-theme.ts +121 -0
  400. package/src/web/components/floating-window/pip/pip-caption-button.tsx +1 -1
  401. package/src/web/components/git/create-worktree-dialog.tsx +5 -3
  402. package/src/web/components/git/git-log-panel.tsx +4 -2
  403. package/src/web/components/git/git-placeholder.tsx +1 -1
  404. package/src/web/components/git/git-ref-badge.tsx +1 -1
  405. package/src/web/components/git/git-repo-picker.tsx +145 -0
  406. package/src/web/components/git/git-status-panel.tsx +231 -250
  407. package/src/web/components/git/git-worktree-panel.tsx +6 -4
  408. package/src/web/components/git/hunk-stage-dialog.tsx +5 -3
  409. package/src/web/components/group-chat/group-chat-tab.tsx +1 -1
  410. package/src/web/components/group-chat/group-create-dialog.tsx +1 -1
  411. package/src/web/components/group-chat/group-full-transcript-view.tsx +1 -1
  412. package/src/web/components/group-chat/group-list.tsx +1 -1
  413. package/src/web/components/group-chat/group-member-edit-dialog.tsx +1 -1
  414. package/src/web/components/group-chat/group-member-roster.tsx +1 -1
  415. package/src/web/components/group-chat/group-message-item.tsx +1 -1
  416. package/src/web/components/group-chat/group-transcript-messages.tsx +1 -1
  417. package/src/web/components/jira/jira-config-form.tsx +1 -1
  418. package/src/web/components/jira/jira-filter-builder.tsx +1 -1
  419. package/src/web/components/jira/jira-panel.tsx +1 -1
  420. package/src/web/components/jira/jira-results-panel.tsx +1 -1
  421. package/src/web/components/jira/jira-ticket-card.tsx +1 -1
  422. package/src/web/components/jira/jira-ticket-detail.tsx +1 -1
  423. package/src/web/components/jira/jira-watcher-form.tsx +1 -1
  424. package/src/web/components/jira/jira-watcher-list.tsx +1 -1
  425. package/src/web/components/layout/add-project-form.tsx +1 -1
  426. package/src/web/components/layout/cloud-alias-row.tsx +1 -1
  427. package/src/web/components/layout/cloud-share-named-tunnel-row.tsx +1 -1
  428. package/src/web/components/layout/cloud-share-popover.tsx +1 -1
  429. package/src/web/components/layout/command-palette-filter-chips.tsx +1 -1
  430. package/src/web/components/layout/command-palette.tsx +46 -8
  431. package/src/web/components/layout/dock-header.tsx +4 -4
  432. package/src/web/components/layout/dock-panel.tsx +3 -3
  433. package/src/web/components/layout/draggable-tab.tsx +20 -3
  434. package/src/web/components/layout/editor-panel.tsx +1 -1
  435. package/src/web/components/layout/mobile-drawer-tab-bar.tsx +10 -1
  436. package/src/web/components/layout/mobile-drawer.tsx +1 -1
  437. package/src/web/components/layout/mobile-nav.tsx +3 -3
  438. package/src/web/components/layout/mobile-tab-switcher-sheet.tsx +13 -4
  439. package/src/web/components/layout/nav-section-rail.tsx +1 -1
  440. package/src/web/components/layout/notification-bell-popover.tsx +1 -1
  441. package/src/web/components/layout/panel-layout.tsx +1 -1
  442. package/src/web/components/layout/project-bottom-sheet.tsx +4 -1
  443. package/src/web/components/layout/project-sort.ts +1 -1
  444. package/src/web/components/layout/project-switcher.tsx +1 -1
  445. package/src/web/components/layout/reparenting-tab.tsx +1 -1
  446. package/src/web/components/layout/sidebar.tsx +1 -1
  447. package/src/web/components/layout/status-bar.tsx +4 -1
  448. package/src/web/components/layout/tab-bar.tsx +9 -23
  449. package/src/web/components/layout/tab-content.tsx +6 -1
  450. package/src/web/components/layout/tab-pool.tsx +1 -0
  451. package/src/web/components/layout/tab-pop-out-menu-item.tsx +1 -1
  452. package/src/web/components/layout/upgrade-button.tsx +1 -1
  453. package/src/web/components/layout/wake-lock-indicator.tsx +1 -1
  454. package/src/web/components/os-explorer/explorer-body.tsx +1 -1
  455. package/src/web/components/os-explorer/explorer-breadcrumb.tsx +1 -1
  456. package/src/web/components/os-explorer/explorer-sidebar.tsx +1 -1
  457. package/src/web/components/os-explorer/explorer-sort-menu.tsx +1 -1
  458. package/src/web/components/os-explorer/explorer-toolbar.tsx +1 -1
  459. package/src/web/components/os-explorer/icons/file-type-icon-map.ts +10 -94
  460. package/src/web/components/os-explorer/icons/file-type-icon.tsx +17 -13
  461. package/src/web/components/os-explorer/mobile/mobile-bottom-toolbar.tsx +1 -1
  462. package/src/web/components/os-explorer/mobile/mobile-explorer-top-bar.tsx +1 -1
  463. package/src/web/components/os-explorer/mobile/mobile-more-sheet.tsx +1 -1
  464. package/src/web/components/os-explorer/mobile/mobile-places-sheet.tsx +1 -1
  465. package/src/web/components/os-explorer/mobile/mobile-places-strip.tsx +1 -1
  466. package/src/web/components/os-explorer/properties-dialog.tsx +1 -1
  467. package/src/web/components/os-explorer/skins/macos-window-chrome.tsx +1 -1
  468. package/src/web/components/os-explorer/skins/windows-window-chrome.tsx +1 -1
  469. package/src/web/components/os-explorer/upload/upload-batch-card.tsx +1 -1
  470. package/src/web/components/os-explorer/upload/upload-batch-row.tsx +1 -1
  471. package/src/web/components/os-explorer/use-coarse-long-press.ts +8 -0
  472. package/src/web/components/os-explorer/views/column-view-mobile.tsx +1 -1
  473. package/src/web/components/os-explorer/views/icons-view-tile.tsx +1 -1
  474. package/src/web/components/os-explorer/views/list-row.tsx +1 -1
  475. package/src/web/components/os-explorer/views/list-view.tsx +1 -1
  476. package/src/web/components/postgres/postgres-viewer.tsx +1 -1
  477. package/src/web/components/problems/problems-panel.tsx +230 -0
  478. package/src/web/components/problems/problems-status.tsx +53 -0
  479. package/src/web/components/projects/dir-suggest.tsx +1 -1
  480. package/src/web/components/projects/project-list.tsx +1 -1
  481. package/src/web/components/remote-desktop/remote-desktop-mobile-toolbar.tsx +1 -1
  482. package/src/web/components/remote-desktop/remote-desktop-mobile-view.tsx +1 -1
  483. package/src/web/components/remote-desktop/remote-desktop-readiness-gate.tsx +1 -1
  484. package/src/web/components/remote-desktop/remote-desktop-warning-gate.tsx +1 -1
  485. package/src/web/components/remote-desktop/remote-desktop-window-content.tsx +1 -1
  486. package/src/web/components/root-error-boundary.tsx +116 -0
  487. package/src/web/components/settings/accounts/account-add-dialog.tsx +1 -1
  488. package/src/web/components/settings/accounts/account-card.tsx +1 -1
  489. package/src/web/components/settings/accounts/account-export-dialog.tsx +1 -1
  490. package/src/web/components/settings/accounts/account-export-simulation.tsx +1 -1
  491. package/src/web/components/settings/accounts/account-import-dialog.tsx +1 -1
  492. package/src/web/components/settings/accounts/account-profile-panel.tsx +1 -1
  493. package/src/web/components/settings/accounts/account-rotation-settings.tsx +1 -1
  494. package/src/web/components/settings/accounts/account-token-test-dialog.tsx +1 -1
  495. package/src/web/components/settings/accounts/account-usage-pattern-chart.tsx +1 -1
  496. package/src/web/components/settings/accounts/accounts-pane-header.tsx +1 -1
  497. package/src/web/components/settings/accounts/accounts-settings-section.tsx +1 -1
  498. package/src/web/components/settings/accounts/claude-accounts-section.tsx +9 -1
  499. package/src/web/components/settings/accounts/codex-accounts-section.tsx +10 -1
  500. package/src/web/components/settings/accounts/codex-add-account-dialog.tsx +1 -1
  501. package/src/web/components/settings/accounts/codex-backup-dialog.tsx +1 -1
  502. package/src/web/components/settings/ai-settings-section.tsx +1 -1
  503. package/src/web/components/settings/appearance-settings-section.tsx +56 -1
  504. package/src/web/components/settings/change-password-section.tsx +1 -1
  505. package/src/web/components/settings/extension-manager-section.tsx +1 -1
  506. package/src/web/components/settings/general-settings-section.tsx +1 -1
  507. package/src/web/components/settings/glob-list-editor.tsx +1 -1
  508. package/src/web/components/settings/keyboard-shortcuts-section.tsx +1 -1
  509. package/src/web/components/settings/mcp-server-dialog.tsx +1 -1
  510. package/src/web/components/settings/notifications-settings-section.tsx +1 -1
  511. package/src/web/components/settings/ppmbot-settings-section.tsx +1 -1
  512. package/src/web/components/settings/proxy-settings-section.tsx +1 -1
  513. package/src/web/components/settings/proxy-test-section.tsx +1 -1
  514. package/src/web/components/settings/query-audit-section.tsx +1 -1
  515. package/src/web/components/settings/schedules/schedule-row.tsx +1 -1
  516. package/src/web/components/settings/schedules/schedules-settings-section.tsx +1 -1
  517. package/src/web/components/settings/settings-body.tsx +1 -1
  518. package/src/web/components/settings/settings-categories.ts +14 -3
  519. package/src/web/components/settings/settings-category-list.tsx +1 -1
  520. package/src/web/components/settings/settings-section-content.tsx +1 -1
  521. package/src/web/components/settings/tag-settings-section.tsx +1 -1
  522. package/src/web/components/settings/theme-grid.tsx +1 -1
  523. package/src/web/components/settings/theme-manager-section.tsx +1 -1
  524. package/src/web/components/settings/theme-picker.tsx +1 -1
  525. package/src/web/components/shared/bug-report-popup.tsx +1 -1
  526. package/src/web/components/shared/connection-lost-overlay.tsx +1 -1
  527. package/src/web/components/shared/diagram-overlay.tsx +1 -1
  528. package/src/web/components/shared/image-overlay.tsx +1 -1
  529. package/src/web/components/shared/theme-mode-menu.tsx +1 -1
  530. package/src/web/components/sqlite/sqlite-data-grid.tsx +1 -1
  531. package/src/web/components/sqlite/sqlite-table-list.tsx +1 -1
  532. package/src/web/components/sqlite/sqlite-viewer.tsx +1 -1
  533. package/src/web/components/system/process-group-row.tsx +1 -1
  534. package/src/web/components/system/process-row.tsx +1 -1
  535. package/src/web/components/system/process-table-toolbar.tsx +1 -1
  536. package/src/web/components/system/resource-status-bar.tsx +1 -1
  537. package/src/web/components/system/sortable-header.tsx +1 -1
  538. package/src/web/components/system/system-monitor-body.tsx +1 -1
  539. package/src/web/components/terminal/terminal-finish-login.tsx +1 -1
  540. package/src/web/components/terminal/terminal-links-sheet.tsx +1 -1
  541. package/src/web/components/terminal/terminal-mobile-toolbar.tsx +1 -1
  542. package/src/web/components/terminal/terminal-placeholder.tsx +1 -1
  543. package/src/web/components/terminal/terminal-tab.tsx +1 -1
  544. package/src/web/components/tunnels/named-tunnel/named-tunnel-login-step.tsx +1 -1
  545. package/src/web/components/tunnels/named-tunnel/named-tunnel-section.tsx +1 -1
  546. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +1 -1
  547. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-popup.tsx +1 -1
  548. package/src/web/components/tunnels/tunnel-manager-tab.tsx +1 -1
  549. package/src/web/components/ui/accordion.tsx +1 -1
  550. package/src/web/components/ui/adaptive-context-menu.tsx +9 -2
  551. package/src/web/components/ui/browse-button.tsx +1 -1
  552. package/src/web/components/ui/context-menu.tsx +1 -1
  553. package/src/web/components/ui/dialog.tsx +1 -1
  554. package/src/web/components/ui/dropdown-menu.tsx +1 -1
  555. package/src/web/components/ui/file-browser-picker.tsx +4 -6
  556. package/src/web/components/ui/select.tsx +1 -1
  557. package/src/web/components/ui/sidebar-header.tsx +1 -1
  558. package/src/web/components/ui/sonner.tsx +1 -1
  559. package/src/web/hooks/use-git-repo.ts +124 -0
  560. package/src/web/hooks/use-global-keybindings.ts +11 -6
  561. package/src/web/hooks/use-inline-blame.ts +161 -11
  562. package/src/web/hooks/use-is-touch-only.ts +46 -0
  563. package/src/web/hooks/use-lsp.ts +182 -0
  564. package/src/web/hooks/use-terminal.ts +60 -2
  565. package/src/web/hooks/use-touch-tab-drag.ts +18 -2
  566. package/src/web/hooks/use-url-sync.ts +15 -1
  567. package/src/web/index.html +74 -0
  568. package/src/web/lib/blame-hover-commands.ts +82 -0
  569. package/src/web/lib/blame-hover.ts +199 -0
  570. package/src/web/lib/chunk-recovery.ts +113 -0
  571. package/src/web/lib/editor-font.ts +70 -0
  572. package/src/web/lib/ext-command-dispatch.ts +24 -0
  573. package/src/web/lib/file-icons.generated.ts +408 -0
  574. package/src/web/lib/file-icons.tsx +192 -0
  575. package/src/web/lib/fluent-icon.tsx +62 -0
  576. package/src/web/lib/git-file-tree.ts +83 -0
  577. package/src/web/lib/git-repo-scope.ts +157 -0
  578. package/src/web/lib/icons.generated.tsx +428 -0
  579. package/src/web/lib/icons.ts +17 -0
  580. package/src/web/lib/lsp/lsp-client.ts +321 -0
  581. package/src/web/lib/lsp/lsp-documents.ts +39 -0
  582. package/src/web/lib/lsp/lsp-monaco.ts +214 -0
  583. package/src/web/lib/lsp/lsp-navigation.ts +129 -0
  584. package/src/web/lib/lsp/lsp-responses.ts +244 -0
  585. package/src/web/lib/lsp/lsp-semantic-tokens.ts +180 -0
  586. package/src/web/lib/lsp/lsp-shadow-models.ts +254 -0
  587. package/src/web/lib/lsp/monaco-builtin-typescript.ts +149 -0
  588. package/src/web/lib/lsp/register-providers.ts +458 -0
  589. package/src/web/lib/monaco-diff-language.ts +62 -0
  590. package/src/web/lib/monaco-dotenv-language.ts +134 -0
  591. package/src/web/lib/sidebar-tabs/tab-registry.ts +11 -2
  592. package/src/web/lib/tab-type-icons.ts +32 -4
  593. package/src/web/main.tsx +30 -1
  594. package/src/web/stores/git-repo-store.ts +117 -0
  595. package/src/web/stores/git-status-store.ts +10 -7
  596. package/src/web/stores/keybindings-store.ts +1 -0
  597. package/src/web/stores/panel-utils.ts +5 -2
  598. package/src/web/stores/problems-store.ts +116 -0
  599. package/src/web/stores/settings-store.ts +40 -0
  600. package/src/web/stores/tab-store.ts +2 -1
  601. package/src/web/stores/window-panel-persistence.ts +1 -0
  602. package/src/web/styles/file-icons.generated.css +1007 -0
  603. package/src/web/styles/fonts/nerd-symbols-codicons.woff2 +0 -0
  604. package/src/web/styles/fonts/nerd-symbols-devicons.woff2 +0 -0
  605. package/src/web/styles/fonts/nerd-symbols-font-awesome-ext.woff2 +0 -0
  606. package/src/web/styles/fonts/nerd-symbols-font-awesome-legacy.woff2 +0 -0
  607. package/src/web/styles/fonts/nerd-symbols-font-awesome.woff2 +0 -0
  608. package/src/web/styles/fonts/nerd-symbols-font-logos.woff2 +0 -0
  609. package/src/web/styles/fonts/nerd-symbols-iec-power.woff2 +0 -0
  610. package/src/web/styles/fonts/nerd-symbols-material.woff2 +0 -0
  611. package/src/web/styles/fonts/nerd-symbols-misc.woff2 +0 -0
  612. package/src/web/styles/fonts/nerd-symbols-octicons.woff2 +0 -0
  613. package/src/web/styles/fonts/nerd-symbols-pomicons.woff2 +0 -0
  614. package/src/web/styles/fonts/nerd-symbols-powerline.woff2 +0 -0
  615. package/src/web/styles/fonts/nerd-symbols-seti.woff2 +0 -0
  616. package/src/web/styles/fonts/nerd-symbols-weather.woff2 +0 -0
  617. package/src/web/styles/globals.css +30 -3
  618. package/src/web/styles/nerd-font.generated.css +153 -0
  619. package/src/web/sw.ts +69 -2
  620. package/src/web/theme/adapters/monaco-adapter.ts +20 -1
  621. package/src/web/theme/diff-token-rules.ts +34 -0
  622. package/src/web/theme/semantic-token-rules.ts +103 -0
  623. package/src/web/theme/theme-mode-options.ts +1 -1
  624. package/vite.config.ts +24 -7
  625. package/dist/web/assets/accounts-settings-section-DC2A6FhQ.js +0 -1
  626. package/dist/web/assets/ai-resource-editor-DDhuy_AR.js +0 -1
  627. package/dist/web/assets/ai-settings-section-J9Rbs26g.js +0 -1
  628. package/dist/web/assets/ai-settings-section-OrhLykA2.js +0 -1
  629. package/dist/web/assets/api-client-PMwZQ4iC.js +0 -1
  630. package/dist/web/assets/appearance-settings-section-BQ1dH29t.js +0 -1
  631. package/dist/web/assets/architecture-PBZL5I3N-D55g5j-p.js +0 -1
  632. package/dist/web/assets/arrow-left-y44wEZrw.js +0 -1
  633. package/dist/web/assets/arrow-right-SQ8KJIvE.js +0 -1
  634. package/dist/web/assets/audio-preview-CAVqEwDi.js +0 -1
  635. package/dist/web/assets/bot-BNu2OM_S.js +0 -1
  636. package/dist/web/assets/brain-BsjvCk4k.js +0 -1
  637. package/dist/web/assets/calendar-clock-Zydwzvp7.js +0 -1
  638. package/dist/web/assets/chat-tab-D2le8LxY.js +0 -15
  639. package/dist/web/assets/check-DczxQ5UD.js +0 -1
  640. package/dist/web/assets/chevron-down-BCt_kn-R.js +0 -1
  641. package/dist/web/assets/chevron-right-Lt-y9H_e.js +0 -1
  642. package/dist/web/assets/chevron-up-CRl1AF4q.js +0 -1
  643. package/dist/web/assets/circle-D4vp8Yky.js +0 -1
  644. package/dist/web/assets/circle-question-mark-BGbDcz7E.js +0 -1
  645. package/dist/web/assets/clock-BBIE-uf3.js +0 -1
  646. package/dist/web/assets/code-CvgQViOi.js +0 -1
  647. package/dist/web/assets/code-editor-D-8oqMBM.js +0 -7
  648. package/dist/web/assets/codex-daily-guard-h4ZpEemV.js +0 -1
  649. package/dist/web/assets/conflict-editor-B0Mj8pYR.js +0 -19
  650. package/dist/web/assets/context-menu-I07Ld1Yr.js +0 -1
  651. package/dist/web/assets/copy-Bqr2VxN5.js +0 -1
  652. package/dist/web/assets/csv-preview-Ds2oCW6U.js +0 -2
  653. package/dist/web/assets/database-BHxcoKlT.js +0 -1
  654. package/dist/web/assets/database-viewer-CiwQ6spt.js +0 -1
  655. package/dist/web/assets/diff-viewer-BomFSnpH.js +0 -4
  656. package/dist/web/assets/docx-preview-PsyMM8SN.js +0 -12
  657. package/dist/web/assets/download-hiDsGuxx.js +0 -1
  658. package/dist/web/assets/explorer-body-CExMoOiW.js +0 -2
  659. package/dist/web/assets/explorer-window-content-Hy9kB6Q7.js +0 -1
  660. package/dist/web/assets/extension-manager-section-DMb56aut.js +0 -1
  661. package/dist/web/assets/extension-webview-CQB0Uvdo.js +0 -3
  662. package/dist/web/assets/eye-DYS5JBeU.js +0 -1
  663. package/dist/web/assets/eye-off-YWCuob9F.js +0 -1
  664. package/dist/web/assets/file-exclamation-point-DpdJqj9-.js +0 -1
  665. package/dist/web/assets/files-settings-section-CVHPO3N9.js +0 -1
  666. package/dist/web/assets/flask-conical-BUxpYe-g.js +0 -1
  667. package/dist/web/assets/folder-symlink-DKTEop0L.js +0 -1
  668. package/dist/web/assets/general-settings-section-CWYR9F5y.js +0 -1
  669. package/dist/web/assets/git-log-panel-DYLF-XSq.js +0 -1
  670. package/dist/web/assets/gitGraph-HDMCJU4V-At-P8hlA.js +0 -1
  671. package/dist/web/assets/glide-data-grid-BxFN-Z6F.js +0 -141
  672. package/dist/web/assets/group-chat-tab-Ch6OGMKj.js +0 -1
  673. package/dist/web/assets/hand-BomFk_WG.js +0 -1
  674. package/dist/web/assets/image-preview-DjT5Xb2L.js +0 -1
  675. package/dist/web/assets/index-BfDJvjH9.js +0 -52
  676. package/dist/web/assets/index-Di9nVG3y.css +0 -2
  677. package/dist/web/assets/info-3K5VOQVL-btSsuixb.js +0 -1
  678. package/dist/web/assets/key-round-BhkPzOjZ.js +0 -1
  679. package/dist/web/assets/keybindings-store-CNqxSJxv.js +0 -1
  680. package/dist/web/assets/keyboard-IQMXPNIE.js +0 -1
  681. package/dist/web/assets/keyboard-shortcuts-section-DAFNxA49.js +0 -1
  682. package/dist/web/assets/loader-circle-Bm-Dq_wA.js +0 -1
  683. package/dist/web/assets/markdown-renderer-BSiaxWjE.js +0 -1
  684. package/dist/web/assets/markdown-renderer-CMNnYOPG.js +0 -3
  685. package/dist/web/assets/mobile-explorer-sheet-BMg4Q9Bm.js +0 -1
  686. package/dist/web/assets/monitor-DEoVYSPl.js +0 -1
  687. package/dist/web/assets/notification-store-CRlOB9I9.js +0 -1
  688. package/dist/web/assets/notifications-settings-section-Cci_OOHx.js +0 -1
  689. package/dist/web/assets/packet-RMMSAZCW-B20_sIFd.js +0 -1
  690. package/dist/web/assets/panel-store-BcgZsiXU.js +0 -1
  691. package/dist/web/assets/pdf-preview-C28MEOND.js +0 -1
  692. package/dist/web/assets/pie-UPGHQEXC-nzfJdXCC.js +0 -1
  693. package/dist/web/assets/portal-container-context-DO44JpXO.js +0 -1
  694. package/dist/web/assets/power-BMdSjXYW.js +0 -1
  695. package/dist/web/assets/ppmbot-settings-section-Cef8FSS6.js +0 -1
  696. package/dist/web/assets/process-table-BfixzY3r.js +0 -1
  697. package/dist/web/assets/proxy-settings-section-BlLWfinY.js +0 -1
  698. package/dist/web/assets/query-audit-section-qnSL15x8.js +0 -1
  699. package/dist/web/assets/radar-KQ55EAFF-CS4sHKD5.js +0 -1
  700. package/dist/web/assets/remote-desktop-mobile-sheet-CG6h4OL2.js +0 -2
  701. package/dist/web/assets/remote-desktop-mobile-view-D__2WLV5.js +0 -1
  702. package/dist/web/assets/remote-desktop-readiness-gate-rL48PCUH.js +0 -1
  703. package/dist/web/assets/remote-desktop-window-content-DlGUCbxq.js +0 -1
  704. package/dist/web/assets/save-CIuK3QI4.js +0 -1
  705. package/dist/web/assets/schedules-settings-section-BUqf3KTd.js +0 -1
  706. package/dist/web/assets/send-DQz3yIWM.js +0 -1
  707. package/dist/web/assets/separator-CE0YEyaB.js +0 -1
  708. package/dist/web/assets/settings-body-Baw2komX.js +0 -2
  709. package/dist/web/assets/settings-store-CuQlVCIe.js +0 -2
  710. package/dist/web/assets/settings-tab-DCW-3C38.js +0 -1
  711. package/dist/web/assets/settings-window-content-CVxOGqPV.js +0 -1
  712. package/dist/web/assets/shield-check-46EViZ6-.js +0 -1
  713. package/dist/web/assets/shield-off-Dx5mw3le.js +0 -1
  714. package/dist/web/assets/sparkles-Bay_CedB.js +0 -1
  715. package/dist/web/assets/sqlite-viewer-BWLSC3VJ.js +0 -1
  716. package/dist/web/assets/system-monitor-body-BqPyB0CY.js +0 -2
  717. package/dist/web/assets/system-monitor-tab-BXRvCThe.js +0 -1
  718. package/dist/web/assets/system-monitor-window-content-CvvwXkmW.js +0 -1
  719. package/dist/web/assets/tab-host-window-content-23IR3qzu.js +0 -1
  720. package/dist/web/assets/table-BbD_HNPU.js +0 -1
  721. package/dist/web/assets/team-member-sheet-BXJtrQAB.js +0 -2
  722. package/dist/web/assets/team-member-window-content-CBWnzwZ1.js +0 -1
  723. package/dist/web/assets/terminal-tab-uNw7Yvwg.js +0 -3
  724. package/dist/web/assets/text-wrap-97GXZlav.js +0 -1
  725. package/dist/web/assets/tool-cards-CjirOQfx.js +0 -9
  726. package/dist/web/assets/treemap-KZPCXAKY-BBrhTPZk.js +0 -1
  727. package/dist/web/assets/use-coarse-long-press-CynaAB7m.js +0 -1
  728. package/dist/web/assets/use-inline-blame-BLPCADZ8.js +0 -8
  729. package/dist/web/assets/use-monaco-theme-D2ETCHji.js +0 -1
  730. package/dist/web/assets/use-open-team-member-BlUqTp-l.js +0 -1
  731. package/dist/web/assets/use-remote-desktop-display-choice-B4O11KIj.js +0 -1
  732. package/dist/web/assets/vendor-markdown-3-bej77C.js +0 -291
  733. package/dist/web/assets/video-preview-BlD1DNP8.js +0 -1
  734. package/dist/web/assets/ws-auth-ZB8jvzhM.js +0 -1
  735. package/dist/web/assets/x-TEI-uJYo.js +0 -1
  736. package/dist/web/monacoeditorwork/css.worker.bundle.js +0 -54268
  737. package/dist/web/monacoeditorwork/editor.worker.bundle.js +0 -14316
  738. package/dist/web/monacoeditorwork/html.worker.bundle.js +0 -30452
  739. package/dist/web/monacoeditorwork/json.worker.bundle.js +0 -22095
  740. package/dist/web/monacoeditorwork/ts.worker.bundle.js +0 -225957
  741. package/src/web/components/explorer/file-icon-map.ts +0 -69
  742. /package/dist/web/assets/{abap-Dbc91hEB.js → abap-tkptwpsK.js} +0 -0
  743. /package/dist/web/assets/{actionscript-3-C14d4O5M.js → actionscript-3-Di9TMGwg.js} +0 -0
  744. /package/dist/web/assets/{ada-n8mPGtZF.js → ada-CB9F079D.js} +0 -0
  745. /package/dist/web/assets/{andromeeda-DAKL0TFq.js → andromeeda-Dcl8jpb7.js} +0 -0
  746. /package/dist/web/assets/{apache-BDCV8YqE.js → apache-D0Nk0qsH.js} +0 -0
  747. /package/dist/web/assets/{apex-BphlFNA_.js → apex-mQIoWncD.js} +0 -0
  748. /package/dist/web/assets/{applescript-F2pJar76.js → applescript-C6ljbcsI.js} +0 -0
  749. /package/dist/web/assets/{apply-theme-Abd1TNqE.js → apply-theme-BwIMNXyX.js} +0 -0
  750. /package/dist/web/assets/{ara-B32t5JRb.js → ara-WFqRPGPe.js} +0 -0
  751. /package/dist/web/assets/{asciidoc-DenFyKu-.js → asciidoc-bNd8w4nf.js} +0 -0
  752. /package/dist/web/assets/{asm-D5mJz41u.js → asm-BQ1_F580.js} +0 -0
  753. /package/dist/web/assets/{aurora-x-CUyAXiXM.js → aurora-x-Ciqs_Dbu.js} +0 -0
  754. /package/dist/web/assets/{awk-CUwaf-l-.js → awk-GCR-6KZV.js} +0 -0
  755. /package/dist/web/assets/{ayu-dark-Cgg8W7cK.js → ayu-dark-DxJXuj99.js} +0 -0
  756. /package/dist/web/assets/{ayu-light-B1c04Bhg.js → ayu-light-jvSyJWDV.js} +0 -0
  757. /package/dist/web/assets/{ayu-mirage-CdWbuzp5.js → ayu-mirage-Cg3BPO6H.js} +0 -0
  758. /package/dist/web/assets/{ballerina-B2-GPRG0.js → ballerina-BPz4CrX6.js} +0 -0
  759. /package/dist/web/assets/{bat-Nss7Yr-0.js → bat-CSTs2hIG.js} +0 -0
  760. /package/dist/web/assets/{beancount-CgaWuvpQ.js → beancount-DMateAZX.js} +0 -0
  761. /package/dist/web/assets/{berry-DCFF4Zj1.js → berry-9lXg0GRM.js} +0 -0
  762. /package/dist/web/assets/{bibtex-BPNI-Gig.js → bibtex-DIbqmvFg.js} +0 -0
  763. /package/dist/web/assets/{bicep-qCj6DX1x.js → bicep-02WGsoJ8.js} +0 -0
  764. /package/dist/web/assets/{bird2-DYDjG-B_.js → bird2-BY0tbu3k.js} +0 -0
  765. /package/dist/web/assets/{c-CZV8SiOL.js → c-jMBX_9Je.js} +0 -0
  766. /package/dist/web/assets/{c3-BG7R2A4x.js → c3-B8JVbNjW.js} +0 -0
  767. /package/dist/web/assets/{cadence-BuiQVST4.js → cadence-DUIf1tvL.js} +0 -0
  768. /package/dist/web/assets/{can-open-in-ppm-DU5MH6XF.js → can-open-in-ppm-DGEc0s4P.js} +0 -0
  769. /package/dist/web/assets/{catppuccin-frappe-C-nwrEbb.js → catppuccin-frappe-FhUCVxex.js} +0 -0
  770. /package/dist/web/assets/{catppuccin-latte-nRLBO6vg.js → catppuccin-latte-CzfrtmgL.js} +0 -0
  771. /package/dist/web/assets/{catppuccin-macchiato-42eAAqCw.js → catppuccin-macchiato-6xL0lOtj.js} +0 -0
  772. /package/dist/web/assets/{catppuccin-mocha-4lH0_4tX.js → catppuccin-mocha-D39-xS3P.js} +0 -0
  773. /package/dist/web/assets/{clarity-BCPLN5zJ.js → clarity-D8TeGvoT.js} +0 -0
  774. /package/dist/web/assets/{clojure-Btb509Z6.js → clojure-Dx_acSX7.js} +0 -0
  775. /package/dist/web/assets/{cmake-CGLZgJL3.js → cmake-CyeYPq8o.js} +0 -0
  776. /package/dist/web/assets/{codeowners-Dgqmdm5J.js → codeowners-DrTI0lmI.js} +0 -0
  777. /package/dist/web/assets/{codeql-DDUO6ZHS.js → codeql-CPkFxVW-.js} +0 -0
  778. /package/dist/web/assets/{common-lisp-DlhZ-mM8.js → common-lisp-B0k-3LTj.js} +0 -0
  779. /package/dist/web/assets/{coq-CVz-5qYC.js → coq-uygpo7to.js} +0 -0
  780. /package/dist/web/assets/{csharp-CXL6GcvM.js → csharp-DKUYGfSp.js} +0 -0
  781. /package/dist/web/assets/{css-CthwUm0E.js → css-DoOUp7v4.js} +0 -0
  782. /package/dist/web/assets/{csv-Bsal3rDr.js → csv-B3YE13gi.js} +0 -0
  783. /package/dist/web/assets/{csv-parser-iow1WWML.js → csv-parser-DXePqmXe.js} +0 -0
  784. /package/dist/web/assets/{cue-D2bSqa4C.js → cue-DViO2wvn.js} +0 -0
  785. /package/dist/web/assets/{cypher-u-EM8HmU.js → cypher-4BMCIW5N.js} +0 -0
  786. /package/dist/web/assets/{d-BFVkgfjO.js → d-BT_sTHas.js} +0 -0
  787. /package/dist/web/assets/{dark-plus-BXlM9uFB.js → dark-plus-DVVXu-1N.js} +0 -0
  788. /package/dist/web/assets/{dart-Hxx4mUdp.js → dart-DHz6f6_6.js} +0 -0
  789. /package/dist/web/assets/{dax-DQwsaFe_.js → dax-ChYCjweK.js} +0 -0
  790. /package/dist/web/assets/{desktop-CAHGHZLk.js → desktop-D6Lt4p04.js} +0 -0
  791. /package/dist/web/assets/{diff-CAbIXu6l.js → diff-D8TDe4hP.js} +0 -0
  792. /package/dist/web/assets/{dist-C_bG2Tku.js → dist-DOTlFQJA.js} +0 -0
  793. /package/dist/web/assets/{docker-51FhFKmM.js → docker-Bsp0YbPx.js} +0 -0
  794. /package/dist/web/assets/{dotenv-C4fc3fLK.js → dotenv-B_7giSY_.js} +0 -0
  795. /package/dist/web/assets/{dracula-CTtuacPO.js → dracula-TrQL2iB5.js} +0 -0
  796. /package/dist/web/assets/{dracula-soft-B-95hu1J.js → dracula-soft-n2XOlgh-.js} +0 -0
  797. /package/dist/web/assets/{dream-maker-Di3hAOzX.js → dream-maker-CdIEdhpT.js} +0 -0
  798. /package/dist/web/assets/{emacs-lisp-C6btr6QV.js → emacs-lisp-CSbixs6u.js} +0 -0
  799. /package/dist/web/assets/{everforest-dark-CDQGzEiq.js → everforest-dark-BuZahZYp.js} +0 -0
  800. /package/dist/web/assets/{everforest-light-DRZC8v3w.js → everforest-light-DPH53z5H.js} +0 -0
  801. /package/dist/web/assets/{fennel-BZz92X8f.js → fennel-B1-K_hlJ.js} +0 -0
  802. /package/dist/web/assets/{fish-qpLXUfGf.js → fish-Cy12Dbua.js} +0 -0
  803. /package/dist/web/assets/{fluent-B3F6P-xc.js → fluent-B_82ys8E.js} +0 -0
  804. /package/dist/web/assets/{format-bytes-B9Dbme9a.js → format-bytes-D5sBgIqU.js} +0 -0
  805. /package/dist/web/assets/{fortran-free-form-DjGQrmKa.js → fortran-free-form-BRQdNzZF.js} +0 -0
  806. /package/dist/web/assets/{gdscript-DToF1duE.js → gdscript-XBDmLUm9.js} +0 -0
  807. /package/dist/web/assets/{gdshader-FZCS76-j.js → gdshader-DhVfB3u4.js} +0 -0
  808. /package/dist/web/assets/{genie-CN3-FS9S.js → genie-X3K29Y49.js} +0 -0
  809. /package/dist/web/assets/{gherkin-DT66zHzt.js → gherkin-DKIx-6cX.js} +0 -0
  810. /package/dist/web/assets/{github-dark-5S2AJM2m.js → github-dark-Bf7zdp5s.js} +0 -0
  811. /package/dist/web/assets/{github-dark-default-DNEUWmc8.js → github-dark-default-DqsBBV11.js} +0 -0
  812. /package/dist/web/assets/{github-dark-dimmed-BVgm_raB.js → github-dark-dimmed-X2gqRz6w.js} +0 -0
  813. /package/dist/web/assets/{github-dark-high-contrast-Dai8qNkr.js → github-dark-high-contrast-Z7tvbGX4.js} +0 -0
  814. /package/dist/web/assets/{github-light-C49nlhDa.js → github-light-BKxt-7zZ.js} +0 -0
  815. /package/dist/web/assets/{github-light-default-BLQcyxQl.js → github-light-default-B0liF4d4.js} +0 -0
  816. /package/dist/web/assets/{github-light-high-contrast-BH3u_hMd.js → github-light-high-contrast-F4encJwr.js} +0 -0
  817. /package/dist/web/assets/{gleam-G2907CEQ.js → gleam-Pz2bHgBB.js} +0 -0
  818. /package/dist/web/assets/{gn-fxgN7J9Q.js → gn-CgmdNsPU.js} +0 -0
  819. /package/dist/web/assets/{gnuplot-a1TK_67n.js → gnuplot-qLNF5yZ9.js} +0 -0
  820. /package/dist/web/assets/{go-DLqnNJpz.js → go-CSDUNhE7.js} +0 -0
  821. /package/dist/web/assets/{groovy-D8U-plxc.js → groovy-B3NEnOHF.js} +0 -0
  822. /package/dist/web/assets/{gruvbox-dark-hard-DRYdA7rg.js → gruvbox-dark-hard-DcoftiUX.js} +0 -0
  823. /package/dist/web/assets/{gruvbox-dark-medium-CJgayBQH.js → gruvbox-dark-medium-D1wVSuD8.js} +0 -0
  824. /package/dist/web/assets/{gruvbox-dark-soft-spQNOlQ2.js → gruvbox-dark-soft-DWpunymH.js} +0 -0
  825. /package/dist/web/assets/{gruvbox-light-hard-FoElS0Wo.js → gruvbox-light-hard-rHMvyUdS.js} +0 -0
  826. /package/dist/web/assets/{gruvbox-light-medium-9E1Brisc.js → gruvbox-light-medium-3O2KiXO7.js} +0 -0
  827. /package/dist/web/assets/{gruvbox-light-soft-Coyp7RRB.js → gruvbox-light-soft-lNlXJPwH.js} +0 -0
  828. /package/dist/web/assets/{haskell-D1twJpgj.js → haskell-aaG3aC0h.js} +0 -0
  829. /package/dist/web/assets/{haxe-CppquubK.js → haxe-CPcHhUDd.js} +0 -0
  830. /package/dist/web/assets/{hcl-BWfTkyhR.js → hcl-CMQNlR_4.js} +0 -0
  831. /package/dist/web/assets/{hjson-fgd7F6t5.js → hjson-DeuklPFj.js} +0 -0
  832. /package/dist/web/assets/{hlsl-Ua1j-4aZ.js → hlsl-BI3hlsaM.js} +0 -0
  833. /package/dist/web/assets/{horizon-CTFgrxGb.js → horizon-C7-gOcjs.js} +0 -0
  834. /package/dist/web/assets/{horizon-bright-C4eTVZPB.js → horizon-bright-Cxt9bRW7.js} +0 -0
  835. /package/dist/web/assets/{houston-BeYbWPdk.js → houston-DbF2G7iD.js} +0 -0
  836. /package/dist/web/assets/{hy-BposFX9Q.js → hy-DRG6Hs2I.js} +0 -0
  837. /package/dist/web/assets/{image-gallery-COea0nSk.js → image-gallery-CObzTisL.js} +0 -0
  838. /package/dist/web/assets/{imba-D11-b73t.js → imba-CxKv_2TW.js} +0 -0
  839. /package/dist/web/assets/{ini-BCYCXf0w.js → ini-BiHsyCdO.js} +0 -0
  840. /package/dist/web/assets/{java-BqKIPPzY.js → java-D3RZzgDB.js} +0 -0
  841. /package/dist/web/assets/{javascript-CxvTx_wu.js → javascript-4FmSqG-T.js} +0 -0
  842. /package/dist/web/assets/{json-DiknJGdj.js → json-CjB236_E.js} +0 -0
  843. /package/dist/web/assets/{json5--8nFeehk.js → json5-bkfO-Rco.js} +0 -0
  844. /package/dist/web/assets/{jsonc-BFcq-Nx-.js → jsonc-BwaTeLyv.js} +0 -0
  845. /package/dist/web/assets/{jsonl-DKItgfTA.js → jsonl-CfxNSwGd.js} +0 -0
  846. /package/dist/web/assets/{jsonnet-sNz5wf7H.js → jsonnet-CQETCYrp.js} +0 -0
  847. /package/dist/web/assets/{jssm-BALAIF_E.js → jssm-D5o3Zzdz.js} +0 -0
  848. /package/dist/web/assets/{jsx-fXHHDCVl.js → jsx-BAMILPLo.js} +0 -0
  849. /package/dist/web/assets/{kanagawa-dragon-nywk9qzg.js → kanagawa-dragon-BhGVxu3R.js} +0 -0
  850. /package/dist/web/assets/{kanagawa-lotus-BmYPLC4f.js → kanagawa-lotus-FH4Y59ro.js} +0 -0
  851. /package/dist/web/assets/{kanagawa-wave-624mOWgc.js → kanagawa-wave-eilvP9MB.js} +0 -0
  852. /package/dist/web/assets/{kdl-DT8Argim.js → kdl-BQ-yvXUK.js} +0 -0
  853. /package/dist/web/assets/{kotlin-BvUjvPz2.js → kotlin-BuCx0-VT.js} +0 -0
  854. /package/dist/web/assets/{kusto-B0PONVdx.js → kusto-DAN_n_Cy.js} +0 -0
  855. /package/dist/web/assets/{laserwave-ByV7LuzT.js → laserwave-Cq2BlxrT.js} +0 -0
  856. /package/dist/web/assets/{lean-DQtq2qQC.js → lean-Dhq7uXKw.js} +0 -0
  857. /package/dist/web/assets/{less-DZeD4ccP.js → less-CxaMQb8j.js} +0 -0
  858. /package/dist/web/assets/{libesm-CcPYXCKp.js → libesm-DdtEjhIi.js} +0 -0
  859. /package/dist/web/assets/{light-plus-BCaKDxvd.js → light-plus-B4sMAend.js} +0 -0
  860. /package/dist/web/assets/{llvm-Dzok661y.js → llvm-DQ6-B_6Y.js} +0 -0
  861. /package/dist/web/assets/{log-C32HpwgI.js → log-Bb_vqvu7.js} +0 -0
  862. /package/dist/web/assets/{logo-Dtjk3XHO.js → logo-BzfYv3A_.js} +0 -0
  863. /package/dist/web/assets/{luau-BMbN7IqN.js → luau-BnAeNR77.js} +0 -0
  864. /package/dist/web/assets/{make-DIVSnx7D.js → make-B6IFuxpC.js} +0 -0
  865. /package/dist/web/assets/{markdown-B1JzcsJb.js → markdown-Z0xi77Fn.js} +0 -0
  866. /package/dist/web/assets/{material-theme-XMfEph9O.js → material-theme-1scy1SYn.js} +0 -0
  867. /package/dist/web/assets/{material-theme-darker-CRGzh4Ox.js → material-theme-darker-G-JykXQP.js} +0 -0
  868. /package/dist/web/assets/{material-theme-lighter-D6esgP3h.js → material-theme-lighter-BtKkCMVq.js} +0 -0
  869. /package/dist/web/assets/{material-theme-ocean-CGbfRrFG.js → material-theme-ocean-irrDC89L.js} +0 -0
  870. /package/dist/web/assets/{material-theme-palenight-DFW4xdPI.js → material-theme-palenight-Eq5_K4LM.js} +0 -0
  871. /package/dist/web/assets/{matlab-Zpc8hvmI.js → matlab-BE3oCXZC.js} +0 -0
  872. /package/dist/web/assets/{mdx-DLlDpnjI.js → mdx-DYiuFTGw.js} +0 -0
  873. /package/dist/web/assets/{mermaid-q_sEDHYr.js → mermaid-DVlaEvtw.js} +0 -0
  874. /package/dist/web/assets/{min-dark-DUklXai3.js → min-dark-DSkeTpQa.js} +0 -0
  875. /package/dist/web/assets/{min-light-Ps7CV3R0.js → min-light-CFv2Q0uF.js} +0 -0
  876. /package/dist/web/assets/{mipsasm-anKs0TGD.js → mipsasm-CiAFuZQ2.js} +0 -0
  877. /package/dist/web/assets/{mojo-CWTvit9D.js → mojo-ARshcaSQ.js} +0 -0
  878. /package/dist/web/assets/{monokai-DOSMe3B9.js → monokai-CPTV-SOg.js} +0 -0
  879. /package/dist/web/assets/{moonbit-zOAryA05.js → moonbit-D57B0dZr.js} +0 -0
  880. /package/dist/web/assets/{move-CA6YZdSC.js → move-qgy3G_o9.js} +0 -0
  881. /package/dist/web/assets/{narrat-CyMxkfZJ.js → narrat-CZ3rC-oc.js} +0 -0
  882. /package/dist/web/assets/{nextflow-groovy-D5beSS3L.js → nextflow-groovy-BxxIOcI4.js} +0 -0
  883. /package/dist/web/assets/{night-owl-3ALu1K6e.js → night-owl-B1ryGCda.js} +0 -0
  884. /package/dist/web/assets/{night-owl-light-_NLbQQrl.js → night-owl-light-BZvNnvMF.js} +0 -0
  885. /package/dist/web/assets/{nix-C_KqthNc.js → nix-BVBQi8yv.js} +0 -0
  886. /package/dist/web/assets/{nord-VG8J_Wfy.js → nord-3NXw613h.js} +0 -0
  887. /package/dist/web/assets/{nushell-Dx7K7YNI.js → nushell-BMOLRalb.js} +0 -0
  888. /package/dist/web/assets/{objective-c-DrEbGERB.js → objective-c-AxruEUgh.js} +0 -0
  889. /package/dist/web/assets/{objective-cpp-DpiXqKhj.js → objective-cpp-cFT0qRsD.js} +0 -0
  890. /package/dist/web/assets/{ocaml-G6x51MAm.js → ocaml-_8JH6O8J.js} +0 -0
  891. /package/dist/web/assets/{odin-tK6CU-OU.js → odin-nwYvR0O6.js} +0 -0
  892. /package/dist/web/assets/{one-dark-pro-581te-yF.js → one-dark-pro-C1LaYJaH.js} +0 -0
  893. /package/dist/web/assets/{one-light-DpYva-U1.js → one-light-B7rMc__c.js} +0 -0
  894. /package/dist/web/assets/{openscad-C7LYrrI4.js → openscad-Cwes8bKO.js} +0 -0
  895. /package/dist/web/assets/{pascal-ChqM3eJD.js → pascal-DMt-6tdZ.js} +0 -0
  896. /package/dist/web/assets/{pkl-BlIRJsyQ.js → pkl-QBTyYQmB.js} +0 -0
  897. /package/dist/web/assets/{plastic-DxceXlOD.js → plastic-BTSUp8Fk.js} +0 -0
  898. /package/dist/web/assets/{plsql-CVikvjWK.js → plsql-DQv3IFXP.js} +0 -0
  899. /package/dist/web/assets/{po-BN9bpeJD.js → po-CNwZx4tW.js} +0 -0
  900. /package/dist/web/assets/{poimandres-NeQA7ZSh.js → poimandres-8Os7Qequ.js} +0 -0
  901. /package/dist/web/assets/{polar-DtRx-uzO.js → polar-b4yK8oD8.js} +0 -0
  902. /package/dist/web/assets/{postcss-EDnOs84S.js → postcss-sFctwpxx.js} +0 -0
  903. /package/dist/web/assets/{powerquery-mc-bbl3v.js → powerquery-Cg_WrtuN.js} +0 -0
  904. /package/dist/web/assets/{powershell-ZqZF93a-.js → powershell-C7Ifz95h.js} +0 -0
  905. /package/dist/web/assets/{prisma-vhORN1Sx.js → prisma-Z52HUJzQ.js} +0 -0
  906. /package/dist/web/assets/{prolog-DfIbN_m8.js → prolog-DLqW-zR1.js} +0 -0
  907. /package/dist/web/assets/{proto-BHcnh-Db.js → proto-BOIzxCCJ.js} +0 -0
  908. /package/dist/web/assets/{puppet-oLpQOx2h.js → puppet-De7TjZIf.js} +0 -0
  909. /package/dist/web/assets/{purescript-HbM4Dt8M.js → purescript-R76ou1WT.js} +0 -0
  910. /package/dist/web/assets/{python-Dlxo2z6Q.js → python-Dprm0tNP.js} +0 -0
  911. /package/dist/web/assets/{qmldir-B5ox9idu.js → qmldir-Clp_jpNw.js} +0 -0
  912. /package/dist/web/assets/{qss-CyegwBrl.js → qss-eQPYYzSo.js} +0 -0
  913. /package/dist/web/assets/{r-CxE2X3lg.js → r-CCcRHIf5.js} +0 -0
  914. /package/dist/web/assets/{racket-CpguQMOj.js → racket-CzE472yp.js} +0 -0
  915. /package/dist/web/assets/{raku-DDf8ASYE.js → raku-DQwXrTSi.js} +0 -0
  916. /package/dist/web/assets/{red-C634f6x3.js → red-KCS6wyop.js} +0 -0
  917. /package/dist/web/assets/{reg-4gnm7BOP.js → reg-CcrAddUh.js} +0 -0
  918. /package/dist/web/assets/{regexp-Cs-hPAru.js → regexp-DDbud-Ri.js} +0 -0
  919. /package/dist/web/assets/{rel-CrGcWbwM.js → rel-99GDgaHp.js} +0 -0
  920. /package/dist/web/assets/{resolve-theme-Dm8ehbOv.js → resolve-theme-CW2niGV2.js} +0 -0
  921. /package/dist/web/assets/{riscv-B2P26ROS.js → riscv-Dm2eNv0R.js} +0 -0
  922. /package/dist/web/assets/{ron-DDHGmvxW.js → ron-CzFt0ygH.js} +0 -0
  923. /package/dist/web/assets/{rose-pine-CUYRoYal.js → rose-pine-Ck6lCrCP.js} +0 -0
  924. /package/dist/web/assets/{rose-pine-dawn-C9JfuUh8.js → rose-pine-dawn-vtALRJNj.js} +0 -0
  925. /package/dist/web/assets/{rose-pine-moon-CrYHzRJm.js → rose-pine-moon-DPto8qXw.js} +0 -0
  926. /package/dist/web/assets/{rosmsg-iqzz1U38.js → rosmsg-NtS6429H.js} +0 -0
  927. /package/dist/web/assets/{rust-DVeWF3Is.js → rust-BjIXvF9h.js} +0 -0
  928. /package/dist/web/assets/{sass-CbVwBbUd.js → sass-CQ23wf5E.js} +0 -0
  929. /package/dist/web/assets/{scala-gZhcvPGv.js → scala-LfKLM143.js} +0 -0
  930. /package/dist/web/assets/{scheme-Z-DWgvmB.js → scheme-D3SLBXlF.js} +0 -0
  931. /package/dist/web/assets/{sdbl-wn_BtpSz.js → sdbl-ODRd2rGN.js} +0 -0
  932. /package/dist/web/assets/{shellscript-C09f889h.js → shellscript-3KB1G_oA.js} +0 -0
  933. /package/dist/web/assets/{slack-dark-D63Fbr3l.js → slack-dark-DTtyWmIy.js} +0 -0
  934. /package/dist/web/assets/{slack-ochin--Yu-v0r6.js → slack-ochin-Bu0PApk3.js} +0 -0
  935. /package/dist/web/assets/{smalltalk-LQDcL_tW.js → smalltalk-haMT-Sbe.js} +0 -0
  936. /package/dist/web/assets/{snazzy-light-bo9fX83t.js → snazzy-light-DXJzefE9.js} +0 -0
  937. /package/dist/web/assets/{solarized-dark-zSs85XH6.js → solarized-dark-B6LyYa18.js} +0 -0
  938. /package/dist/web/assets/{solarized-light-B6Q4CXBt.js → solarized-light-QLADebkv.js} +0 -0
  939. /package/dist/web/assets/{solidity-uUJPOjGx.js → solidity-mzfq1aDc.js} +0 -0
  940. /package/dist/web/assets/{splunk-C6oWgmrC.js → splunk-CyH4RWBp.js} +0 -0
  941. /package/dist/web/assets/{sql-DyUvXbLi.js → sql-CWVlT5D3.js} +0 -0
  942. /package/dist/web/assets/{ssh-config-62Vrd_7v.js → ssh-config-DNvQJ1Qx.js} +0 -0
  943. /package/dist/web/assets/{stylus-CmLQe7Fq.js → stylus-ByQQdtmf.js} +0 -0
  944. /package/dist/web/assets/{swift-DJwuT1eZ.js → swift-D1cpY4ow.js} +0 -0
  945. /package/dist/web/assets/{synthwave-84-CEeyTLD7.js → synthwave-84-BDF_-QiW.js} +0 -0
  946. /package/dist/web/assets/{system-verilog-DMqtAclw.js → system-verilog-BYrkMydC.js} +0 -0
  947. /package/dist/web/assets/{systemd-XnScP_8M.js → systemd-CQm3zyK0.js} +0 -0
  948. /package/dist/web/assets/{talonscript-CDoODzml.js → talonscript-DMW5CzE1.js} +0 -0
  949. /package/dist/web/assets/{tasl-DycI0-Tf.js → tasl-BhFzMCr2.js} +0 -0
  950. /package/dist/web/assets/{tcl-Dt8iP0sw.js → tcl-D7VEAF-9.js} +0 -0
  951. /package/dist/web/assets/{terraform-DXzABgqQ.js → terraform-DdT5A0Vy.js} +0 -0
  952. /package/dist/web/assets/{tokyo-night-DHB1Yc-3.js → tokyo-night-WGLMM6Q9.js} +0 -0
  953. /package/dist/web/assets/{toml-BkejsZF3.js → toml-CZ7ipXHZ.js} +0 -0
  954. /package/dist/web/assets/{tsv-ClmhsiiR.js → tsv-B1zVvoTr.js} +0 -0
  955. /package/dist/web/assets/{tsx-Cp-c_JHF.js → tsx-D4HwRUBq.js} +0 -0
  956. /package/dist/web/assets/{turtle-BbwC417u.js → turtle-B4r8KEJH.js} +0 -0
  957. /package/dist/web/assets/{typescript-DbwnrRKJ.js → typescript-BnHhxMtp.js} +0 -0
  958. /package/dist/web/assets/{typespec-DLL0LoZj.js → typespec-DP2q46GT.js} +0 -0
  959. /package/dist/web/assets/{typst-BmEouVT1.js → typst-DFsD_yaD.js} +0 -0
  960. /package/dist/web/assets/{utils-CwNUra6_.js → utils-Bmf_8h7Y.js} +0 -0
  961. /package/dist/web/assets/{v-C5rFgF81.js → v-Bji8hSVT.js} +0 -0
  962. /package/dist/web/assets/{vala-rBXMujLw.js → vala-D3TIgGmU.js} +0 -0
  963. /package/dist/web/assets/{vb-mxG_YZv2.js → vb-DvcxFS2q.js} +0 -0
  964. /package/dist/web/assets/{vendor-xterm-BtjgHRUe.js → vendor-xterm-BqPDsE9b.js} +0 -0
  965. /package/dist/web/assets/{verilog-uQ-oJRKp.js → verilog-Dy7cF35d.js} +0 -0
  966. /package/dist/web/assets/{vesper-SO5Hw_2X.js → vesper-BzjwUv9J.js} +0 -0
  967. /package/dist/web/assets/{vhdl-8IeO85hx.js → vhdl-DuFnFNmW.js} +0 -0
  968. /package/dist/web/assets/{viml-De-Hm57y.js → viml-yAPgKlbz.js} +0 -0
  969. /package/dist/web/assets/{vitesse-black-BVm23GJE.js → vitesse-black-oSSQdyIZ.js} +0 -0
  970. /package/dist/web/assets/{vitesse-dark-CR0XeT-h.js → vitesse-dark-BZxwPihB.js} +0 -0
  971. /package/dist/web/assets/{vitesse-light-CXIFICUA.js → vitesse-light-uIigycvt.js} +0 -0
  972. /package/dist/web/assets/{vyper-dUuvAUFJ.js → vyper-CX3NAxm5.js} +0 -0
  973. /package/dist/web/assets/{wasm-DbLMmiW0.js → wasm-6mEOOvVa.js} +0 -0
  974. /package/dist/web/assets/{wasm-D5Vd7qV1.js → wasm-D9td37qO.js} +0 -0
  975. /package/dist/web/assets/{wenyan-BafBYCBu.js → wenyan-lwNIHgk6.js} +0 -0
  976. /package/dist/web/assets/{wgsl-DY5sHamz.js → wgsl-DQAzCfog.js} +0 -0
  977. /package/dist/web/assets/{wikitext-QkQQVra5.js → wikitext-DTXmt5NE.js} +0 -0
  978. /package/dist/web/assets/{wit-BZjaDTy9.js → wit-Bdw_7WDH.js} +0 -0
  979. /package/dist/web/assets/{wolfram-vrjPFD7R.js → wolfram-DqyHDZ07.js} +0 -0
  980. /package/dist/web/assets/{yaml-D1as76NB.js → yaml-CPXhdByd.js} +0 -0
  981. /package/dist/web/assets/{zenscript-D31myxQh.js → zenscript-6s_i5zek.js} +0 -0
  982. /package/dist/web/assets/{zig-BbLb6ieN.js → zig-B2htezJ_.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import * as React from "react"
2
- import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
2
+ import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@/lib/icons"
3
3
  import { Select as SelectPrimitive } from "radix-ui"
4
4
 
5
5
  import { cn } from "@/lib/utils"
@@ -1,4 +1,4 @@
1
- import type { LucideIcon } from "lucide-react";
1
+ import type { LucideIcon } from "@/lib/icons";
2
2
  import type { ReactNode } from "react";
3
3
 
4
4
  interface SidebarHeaderProps {
@@ -6,7 +6,7 @@ import {
6
6
  Loader2Icon,
7
7
  OctagonXIcon,
8
8
  TriangleAlertIcon,
9
- } from "lucide-react"
9
+ } from "@/lib/icons"
10
10
  import { Toaster as Sonner, type ToasterProps } from "sonner"
11
11
  import { useSettingsStore } from "@/stores/settings-store"
12
12
 
@@ -0,0 +1,124 @@
1
+ /**
2
+ * The repository a git surface should talk to, and the two ways to address it.
3
+ *
4
+ * `gitUrl` builds a project-scoped git URL carrying the `repo=` scope, and
5
+ * `repoPath` rebases a project-relative file path onto that repository. Between
6
+ * them they cover both shapes of git route: the repo-scoped ones (status, log,
7
+ * graph, worktrees) and the file-scoped ones (blame, hunks, file diff).
8
+ *
9
+ * For a project that *is* a repository — nearly all of them — every URL this
10
+ * returns is byte-identical to what the call site built before, and
11
+ * `repoPath` is the identity. That is deliberate: the container-folder case
12
+ * must not be able to regress the ordinary one.
13
+ */
14
+ import { useCallback, useEffect, useMemo } from "react";
15
+ import { projectUrl } from "@/lib/api-client";
16
+ import { useGitRepoStore } from "@/stores/git-repo-store";
17
+ import {
18
+ hasNoRepo,
19
+ needsPick,
20
+ projectRelativePath,
21
+ rebaseStatusPaths,
22
+ repoRelativePath,
23
+ resolveRepo,
24
+ withRepoParam,
25
+ type GitRepoCandidate,
26
+ type StatusPaths,
27
+ } from "@/lib/git-repo-scope";
28
+
29
+ export interface UseGitRepo {
30
+ /** The resolved repository, or null while loading / awaiting a choice. */
31
+ repo: GitRepoCandidate | null;
32
+ /** Every repository under the project, for a picker. */
33
+ repos: GitRepoCandidate[];
34
+ /** True when the project root is not a repository but something under it is. */
35
+ isNested: boolean;
36
+ /** True when there is a choice to make and it has not been made. */
37
+ needsPick: boolean;
38
+ /** True when nothing under the project is a repository. */
39
+ noRepo: boolean;
40
+ /** `gitUrl("/status")`, `gitUrl("/graph?max=50")` — scope included. */
41
+ gitUrl: (suffix: string) => string;
42
+ /** Project-relative → repository-relative; null when outside the repository. */
43
+ repoPath: (projectRelative: string) => string | null;
44
+ /** Repository-relative → project-relative, for paths git reported. */
45
+ projectFile: (repoRelative: string) => string;
46
+ /** A status answer with its paths in the project's terms, for the file tree. */
47
+ rebaseStatus: <T extends StatusPaths>(status: T) => T;
48
+ choose: (repoPath: string) => void;
49
+ reload: () => void;
50
+ }
51
+
52
+ export function useGitRepo(projectName: string | undefined): UseGitRepo {
53
+ const discovery = useGitRepoStore((s) => (projectName ? s.discovery[projectName] : undefined));
54
+ const chosen = useGitRepoStore((s) => (projectName ? s.chosen[projectName] : undefined));
55
+ const load = useGitRepoStore((s) => s.load);
56
+ const chooseInStore = useGitRepoStore((s) => s.choose);
57
+
58
+ useEffect(() => {
59
+ if (projectName) void load(projectName);
60
+ }, [projectName, load]);
61
+
62
+ const repo = resolveRepo(discovery, chosen);
63
+
64
+ const gitUrl = useCallback(
65
+ (suffix: string) => withRepoParam(`${projectUrl(projectName ?? "")}/git${suffix}`, repo),
66
+ [projectName, repo],
67
+ );
68
+
69
+ const repoPath = useCallback(
70
+ (projectRelative: string) => repoRelativePath(projectRelative, repo),
71
+ [repo],
72
+ );
73
+
74
+ const projectFile = useCallback(
75
+ (repoRelative: string) => projectRelativePath(repoRelative, repo),
76
+ [repo],
77
+ );
78
+
79
+ const rebaseStatus = useCallback(
80
+ <T extends StatusPaths>(status: T) => rebaseStatusPaths(status, repo),
81
+ [repo],
82
+ );
83
+
84
+ const choose = useCallback(
85
+ (path: string) => {
86
+ if (projectName) chooseInStore(projectName, path);
87
+ },
88
+ [projectName, chooseInStore],
89
+ );
90
+
91
+ const reload = useCallback(() => {
92
+ if (projectName) void load(projectName, true);
93
+ }, [projectName, load]);
94
+
95
+ // Memoised because call sites name `gitRepo` itself in a dependency array —
96
+ // a fresh object literal every render would re-create their `useCallback`s
97
+ // every render, and an effect depending on one of those would re-fetch in a
98
+ // loop. Every field is already stable: the store's own values, or a
99
+ // `useCallback` keyed on the resolved repo.
100
+ //
101
+ // The store's in-flight flag used to be one of them. It went false → true →
102
+ // false on every mount and nothing ever read it, so all it did was hand every
103
+ // consumer three identities where one would do — and fire the first
104
+ // `git blame`, `git status` and file diff three times. It is gone from the
105
+ // store entirely now rather than merely left out here. The two identities
106
+ // that remain are the ones that mean something: before discovery answers,
107
+ // and after.
108
+ return useMemo(
109
+ () => ({
110
+ repo,
111
+ repos: discovery?.repos ?? [],
112
+ isNested: !!discovery && !discovery.rootIsRepo && discovery.repos.length > 0,
113
+ needsPick: needsPick(discovery, chosen),
114
+ noRepo: hasNoRepo(discovery),
115
+ gitUrl,
116
+ repoPath,
117
+ projectFile,
118
+ rebaseStatus,
119
+ choose,
120
+ reload,
121
+ }),
122
+ [repo, discovery, chosen, gitUrl, repoPath, projectFile, rebaseStatus, choose, reload],
123
+ );
124
+ }
@@ -8,6 +8,7 @@ import { useExtensionStore } from "@/stores/extension-store";
8
8
  import { useCompareStore } from "@/stores/compare-store";
9
9
  import { openSettings } from "@/components/settings/open-settings";
10
10
  import { basename } from "@/lib/utils";
11
+ import { dispatchExtCommand } from "@/lib/ext-command-dispatch";
11
12
 
12
13
  /** Dispatch this event to open the command palette from anywhere, optionally with initial query */
13
14
  export function openCommandPalette(initialQuery?: string) {
@@ -225,6 +226,15 @@ export function useGlobalKeybindings() {
225
226
  return;
226
227
  }
227
228
 
229
+ // Problems, in the dock — VS Code's Ctrl+Shift+M, and its placement.
230
+ if (match(e, "open-problems")) {
231
+ e.preventDefault();
232
+ usePanelStore.getState().openInDock({
233
+ type: "problems", title: "Problems", projectId: null, closable: true,
234
+ });
235
+ return;
236
+ }
237
+
228
238
  // Switch project 1-9
229
239
  for (let i = 1; i <= 9; i++) {
230
240
  if (match(e, `switch-project-${i}`)) {
@@ -253,12 +263,7 @@ export function useGlobalKeybindings() {
253
263
  if (!parsed) { parsed = parseCombo(raw); extParsedCache.set(raw, parsed); }
254
264
  if (eventMatchesCombo(e, parsed)) {
255
265
  e.preventDefault();
256
- const project = useProjectStore.getState().activeProject;
257
- const args: unknown[] = [];
258
- if (project?.path) args.push(project.path);
259
- window.dispatchEvent(new CustomEvent("ext:command:execute", {
260
- detail: { command: kb.command, args },
261
- }));
266
+ void dispatchExtCommand(kb.command);
262
267
  return;
263
268
  }
264
269
  }
@@ -16,8 +16,19 @@
16
16
  */
17
17
  import { useCallback, useEffect, useRef, useState } from "react";
18
18
  import type * as MonacoType from "monaco-editor";
19
- import { api, projectUrl } from "@/lib/api-client";
20
- import { formatBlameAnnotation, type BlameResult } from "../../shared/blame";
19
+ import { api } from "@/lib/api-client";
20
+ import {
21
+ formatBlameAnnotation,
22
+ isUncommittedHash,
23
+ type BlameCommitInfo,
24
+ type BlameLineDetail,
25
+ type BlameResult,
26
+ } from "../../shared/blame";
27
+ import { buildBlameHoverMarkdown } from "@/lib/blame-hover";
28
+ import { registerBlameHoverCommands } from "@/lib/blame-hover-commands";
29
+ import { registerDiffLanguage } from "@/lib/monaco-diff-language";
30
+ import { useGitRepo } from "@/hooks/use-git-repo";
31
+ import { useProjectStore } from "@/stores/project-store";
21
32
 
22
33
  const STYLE_ID = "inline-blame-styles";
23
34
  // Monaco renders injected text as a real span carrying `inlineClassName`, so
@@ -29,6 +40,11 @@ const CSS = `
29
40
  font-style: italic;
30
41
  white-space: pre;
31
42
  }
43
+ /* The hover's avatar is a markdown image, so it sits on the text baseline and
44
+ hangs below the author name without this. */
45
+ .monaco-hover img {
46
+ vertical-align: text-bottom;
47
+ }
32
48
  `;
33
49
 
34
50
  function injectStyles(editor: MonacoType.editor.ICodeEditor): void {
@@ -78,22 +94,53 @@ export function useInlineBlame({
78
94
  const [stale, setStale] = useState(false);
79
95
  const [line, setLine] = useState(0);
80
96
  const [reloadToken, setReloadToken] = useState(0);
97
+ // Keyed, not bare: two adjacent lines can share a commit, and a detail
98
+ // matched on the hash alone would show the previous line's diff on the next
99
+ // one while the new request is still in flight.
100
+ const [detail, setDetail] = useState<{ key: string; value: BlameLineDetail | null } | null>(null);
101
+ const detailCache = useRef(new Map<string, BlameLineDetail | null>());
81
102
  const decorationsRef = useRef<MonacoType.editor.IEditorDecorationsCollection | null>(null);
103
+ // The line the annotation is actually drawn on, for the touch handler to
104
+ // compare a tap against. A ref rather than the `line` state so the handler
105
+ // does not have to be torn down and rebuilt on every cursor move.
106
+ const annotatedLineRef = useRef(0);
107
+ // The hover's action links address the Git Graph views by absolute path,
108
+ // which is what those commands take. Looked up here rather than passed in, so
109
+ // the three call sites do not each have to find it.
110
+ const projectPath = useProjectStore((s) => s.projects.find((p) => p.name === projectName)?.path);
111
+ // Which repository the project's git actually lives in: itself, or a subfolder
112
+ // the user picked. Every path below is expressed relative to *that*, because
113
+ // that is where git runs.
114
+ const gitRepo = useGitRepo(projectName);
115
+ const gitRoot = gitRepo.repo?.path ?? projectPath;
116
+ // `null` means the open file is outside the chosen repository — there is
117
+ // nothing to blame, which is a quiet no-annotation rather than an error.
118
+ const repoFile = filePath ? gitRepo.repoPath(filePath) : null;
82
119
 
83
120
  const refresh = useCallback(() => setReloadToken((n) => n + 1), []);
84
121
 
122
+ // Both are global to the page and idempotent. Registered here rather than at
123
+ // module load because both need a Monaco instance: the `diff` language is
124
+ // what colours the hover's diff block, and the commands are what its buttons
125
+ // reach.
126
+ useEffect(() => {
127
+ if (!monaco || !enabled) return;
128
+ registerDiffLanguage(monaco);
129
+ registerBlameHoverCommands(monaco);
130
+ }, [monaco, enabled]);
131
+
85
132
  // Load the blame. A file with no git history answers with an empty table
86
133
  // rather than an error, so there is nothing to special-case here.
87
134
  useEffect(() => {
88
- if (!enabled || !projectName || !filePath) {
135
+ if (!enabled || !projectName || !filePath || repoFile == null) {
89
136
  setBlame(null);
90
137
  return;
91
138
  }
92
139
  let cancelled = false;
93
- const query = new URLSearchParams({ path: filePath });
140
+ const query = new URLSearchParams({ path: repoFile });
94
141
  if (rev) query.set("rev", rev);
95
142
  api
96
- .get<BlameResult>(`${projectUrl(projectName)}/git/blame?${query}`)
143
+ .get<BlameResult>(gitRepo.gitUrl(`/blame?${query}`))
97
144
  .then((result) => {
98
145
  if (cancelled) return;
99
146
  setBlame(result);
@@ -106,7 +153,7 @@ export function useInlineBlame({
106
153
  return () => {
107
154
  cancelled = true;
108
155
  };
109
- }, [enabled, projectName, filePath, rev, reloadToken]);
156
+ }, [enabled, projectName, filePath, repoFile, rev, reloadToken, gitRepo]);
110
157
 
111
158
  // Follow the cursor, and notice edits.
112
159
  useEffect(() => {
@@ -122,19 +169,108 @@ export function useInlineBlame({
122
169
  };
123
170
  }, [editor, enabled, readOnly]);
124
171
 
125
- const commit = (() => {
172
+ // A tap where a touch device has no hover.
173
+ //
174
+ // The project's mobile rules forbid a hover-only interaction, and a phone has
175
+ // no hover at all — so on a device that reports `hover: none`, a tap on the
176
+ // annotation opens the same hover that a mouse would. `editor.action.showHover`
177
+ // opens it at the cursor, which the tap has already moved onto the line.
178
+ //
179
+ // The tap is identified by position rather than by the mouse target's
180
+ // `injectedText`, which says so exactly but is not in Monaco's public
181
+ // typings: the annotation sits after the line's last column, so a tap at or
182
+ // past that column on the annotated line is a tap on it. Being a little
183
+ // generous about the column is the right way round here — it makes the target
184
+ // the whole end of the line rather than a 19px strip of italic text.
185
+ useEffect(() => {
186
+ if (!editor || !enabled) return;
187
+ // `hover: none` rather than a width breakpoint: the question is whether this
188
+ // pointer can hover at all, not how wide the screen is.
189
+ if (!window.matchMedia?.("(hover: none)").matches) return;
190
+
191
+ const sub = editor.onMouseDown((e) => {
192
+ const position = e.target.position;
193
+ const model = editor.getModel();
194
+ if (!position || !model) return;
195
+ if (position.lineNumber !== annotatedLineRef.current) return;
196
+ if (position.column < model.getLineMaxColumn(position.lineNumber)) return;
197
+ editor.getAction("editor.action.showHover")?.run();
198
+ });
199
+ return () => sub.dispose();
200
+ }, [editor, enabled]);
201
+
202
+ const lineBlame: { commit: BlameCommitInfo; origLine: number } | null = (() => {
126
203
  if (!blame || stale || line <= 0) return null;
127
- const entry = blame.lines[line - 1];
204
+ const dense = blame.lines[line - 1];
128
205
  // The table is dense and in order, but a defensive lookup costs nothing and
129
206
  // keeps a short blame from mis-attributing a line past its end.
130
- const hash = entry?.finalLine === line ? entry.hash : blame.lines.find((l) => l.finalLine === line)?.hash;
131
- return hash ? (blame.commits[hash] ?? null) : null;
207
+ const entry = dense?.finalLine === line ? dense : blame.lines.find((l) => l.finalLine === line);
208
+ if (!entry) return null;
209
+ const commit = blame.commits[entry.hash];
210
+ return commit ? { commit, origLine: entry.origLine } : null;
132
211
  })();
212
+ const commit = lineBlame?.commit ?? null;
213
+
214
+ // What the hover needs beyond the annotation: the whole commit message and
215
+ // the change this commit made to this line. One `git show` per commit *and
216
+ // line*, so the key covers both — moving down a line inside the same commit
217
+ // is a different diff.
218
+ //
219
+ // Deliberately not fetched lazily when the hover opens: Monaco reads
220
+ // `hoverMessage` off the decoration synchronously, so a hover has whatever is
221
+ // ready at that moment. Fetching as the cursor moves is what makes it appear
222
+ // filled in instead of behind a spinner — which is the failure this editor
223
+ // already had once, with the bundled TypeScript worker.
224
+ const detailHash = commit && !isUncommittedHash(commit.hash) ? commit.hash : null;
225
+ // The path *at that commit*: after a rename the current path did not exist
226
+ // there, and git would report no diff rather than an error. `filename` comes
227
+ // from the blame git already ran, so it is repository-relative like
228
+ // `repoFile` — not project-relative like the tab's `filePath`.
229
+ const detailPath = commit?.filename || repoFile || undefined;
230
+ const detailLine = lineBlame?.origLine ?? 0;
231
+ const detailKey = `${detailHash} ${detailLine} ${detailPath}`;
232
+
233
+ useEffect(() => {
234
+ if (!enabled || !projectName || !detailHash || !detailPath || detailLine < 1) {
235
+ setDetail(null);
236
+ return;
237
+ }
238
+ const key = detailKey;
239
+ const cache = detailCache.current;
240
+ // `has`, not a truthy check: a commit with nothing to show caches as null
241
+ // and must not be refetched on every return to the line.
242
+ if (cache.has(key)) {
243
+ setDetail({ key, value: cache.get(key) ?? null });
244
+ return;
245
+ }
246
+
247
+ let cancelled = false;
248
+ const query = new URLSearchParams({ hash: detailHash, path: detailPath, line: String(detailLine) });
249
+ api
250
+ .get<BlameLineDetail | null>(gitRepo.gitUrl(`/commit-line?${query}`))
251
+ .then((result) => {
252
+ if (cancelled) return;
253
+ // Bounded: `tab-pool` keeps editors mounted for the life of the session,
254
+ // so an unbounded cache here is a leak that grows with every line the
255
+ // cursor has ever rested on.
256
+ if (cache.size >= 200) cache.delete(cache.keys().next().value as string);
257
+ cache.set(key, result ?? null);
258
+ setDetail({ key, value: result ?? null });
259
+ })
260
+ .catch(() => {
261
+ // No detail is a smaller hover, not an error worth showing.
262
+ if (!cancelled) setDetail(null);
263
+ });
264
+ return () => {
265
+ cancelled = true;
266
+ };
267
+ }, [enabled, projectName, detailHash, detailPath, detailLine, detailKey, gitRepo]);
133
268
 
134
269
  // Draw it.
135
270
  useEffect(() => {
136
271
  if (!editor || !monaco) return;
137
272
  if (!enabled || !commit || line <= 0) {
273
+ annotatedLineRef.current = 0;
138
274
  decorationsRef.current?.clear();
139
275
  return;
140
276
  }
@@ -142,9 +278,11 @@ export function useInlineBlame({
142
278
 
143
279
  const model = editor.getModel();
144
280
  if (!model || line > model.getLineCount()) {
281
+ annotatedLineRef.current = 0;
145
282
  decorationsRef.current?.clear();
146
283
  return;
147
284
  }
285
+ annotatedLineRef.current = line;
148
286
  const column = model.getLineMaxColumn(line);
149
287
  const text = formatBlameAnnotation(commit);
150
288
 
@@ -154,13 +292,25 @@ export function useInlineBlame({
154
292
  // `after` injects text that is not part of the model, so it never
155
293
  // reaches the file and never shifts a column the user can select.
156
294
  after: { content: ` ${text}`, inlineClassName: "inline-blame-annotation" },
295
+ // Hovering injected text does reach a collapsed decoration: Monaco
296
+ // relaxes its column check by one character for `showIfCollapsed`, and
297
+ // the injected span resolves to the line's last column. Verified
298
+ // against Monaco 0.55.1 rather than assumed, because the whole hover
299
+ // hangs off it.
157
300
  showIfCollapsed: true,
301
+ // Null for an uncommitted line, which the annotation already explains.
302
+ hoverMessage: buildBlameHoverMarkdown({
303
+ commit,
304
+ detail: detail?.key === detailKey ? detail.value : null,
305
+ filePath: repoFile ?? "",
306
+ projectPath: gitRoot,
307
+ }),
158
308
  },
159
309
  };
160
310
 
161
311
  if (decorationsRef.current) decorationsRef.current.set([decoration]);
162
312
  else decorationsRef.current = editor.createDecorationsCollection([decoration]);
163
- }, [editor, monaco, enabled, commit, line]);
313
+ }, [editor, monaco, enabled, commit, line, detail, detailKey, repoFile, gitRoot]);
164
314
 
165
315
  // Take the annotation down when the hook stops being used.
166
316
  useEffect(
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A device whose primary pointer is a finger.
3
+ *
4
+ * `useIsMobile` asks how wide the viewport is, which is the right question for a layout and
5
+ * the wrong one for a device: a desktop browser narrowed to half the screen is still a
6
+ * desktop, and a tablet in landscape is still a tablet. Anything deciding what a *machine*
7
+ * should be asked to do — starting a language server that was 854 MB resident — belongs here,
8
+ * because the answer must not change when a window is dragged narrower. It did: the editor
9
+ * tore its language server down at 767px and cold-started a new one on the way back.
10
+ *
11
+ * `hover: none` is the same test `use-inline-blame.ts` uses for the tap-to-open path, and
12
+ * `pointer: coarse` alongside it is what keeps a desktop with a touchscreen on the desktop
13
+ * answer — browsers report the *primary* pointer there, which is still the mouse.
14
+ */
15
+ import { useSyncExternalStore } from "react";
16
+
17
+ const QUERY = "(pointer: coarse) and (hover: none)";
18
+
19
+ function query(): MediaQueryList | null {
20
+ return typeof window !== "undefined" && window.matchMedia ? window.matchMedia(QUERY) : null;
21
+ }
22
+
23
+ function subscribe(cb: () => void): () => void {
24
+ const list = query();
25
+ // A device does not usually change category mid-session, but a tablet gaining a trackpad
26
+ // does — and Safari only gained `addEventListener` on MediaQueryList in 14.
27
+ list?.addEventListener?.("change", cb);
28
+ return () => list?.removeEventListener?.("change", cb);
29
+ }
30
+
31
+ function getSnapshot(): boolean {
32
+ return query()?.matches ?? false;
33
+ }
34
+
35
+ function getServerSnapshot(): boolean {
36
+ return false;
37
+ }
38
+
39
+ export function useIsTouchOnly(): boolean {
40
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
41
+ }
42
+
43
+ /** Non-hook check, for code that runs outside a component. */
44
+ export function isTouchOnlyDevice(): boolean {
45
+ return getSnapshot();
46
+ }
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Connects one Monaco editor to the language server for its file.
3
+ *
4
+ * Registers the model as a document, keeps the server's copy in step with the
5
+ * buffer, turns published diagnostics into markers, and reports the server's
6
+ * state so the UI can say what is happening.
7
+ *
8
+ * Edits are sent incrementally, which is what VS Code does and what keeps a
9
+ * large file affordable. Monaco hands out changes already ordered bottom-up
10
+ * within an event, which is the order LSP needs for sequential application, so
11
+ * they pass straight through. The version number is the safety net: if it ever
12
+ * skips, the bridge asks for the whole document back rather than applying a
13
+ * delta to a copy that is already wrong.
14
+ */
15
+ import { useEffect, useRef, useState } from "react";
16
+ import type * as MonacoType from "monaco-editor";
17
+ import {
18
+ acquireLspConnection,
19
+ releaseLspConnection,
20
+ type LspConnection,
21
+ type LspDocumentStatus,
22
+ } from "@/lib/lsp/lsp-client";
23
+ import { registerLspDocument, unregisterLspDocument } from "@/lib/lsp/lsp-documents";
24
+ import { disposeShadowModels } from "@/lib/lsp/lsp-shadow-models";
25
+ import { registerLspProviders } from "@/lib/lsp/register-providers";
26
+ import { fromLspRange, markerSeverity } from "@/lib/lsp/lsp-monaco";
27
+ import { registerSemanticTokens, semanticTokensLegendOf } from "@/lib/lsp/lsp-semantic-tokens";
28
+ import { useProblemsStore } from "@/stores/problems-store";
29
+
30
+ export interface UseLspOptions {
31
+ editor: MonacoType.editor.IStandaloneCodeEditor | null;
32
+ monaco: typeof MonacoType | null;
33
+ projectName?: string;
34
+ /** Project-relative path. An absolute or untitled path is not served. */
35
+ filePath?: string;
36
+ enabled: boolean;
37
+ }
38
+
39
+ export interface LspState {
40
+ status: LspDocumentStatus | null;
41
+ /** Diagnostics for this file, for a Problems view to list. */
42
+ diagnostics: LspDiagnostic[];
43
+ }
44
+
45
+ export interface LspDiagnostic {
46
+ message: string;
47
+ severity?: number;
48
+ source?: string;
49
+ code?: string | number;
50
+ range: { start: { line: number; character: number }; end: { line: number; character: number } };
51
+ }
52
+
53
+ /**
54
+ * Markers are owned per language server so clearing one server's diagnostics
55
+ * cannot wipe another's — PPM's own SQL and JSON markers live on the same
56
+ * models.
57
+ */
58
+ const MARKER_OWNER = "ppm-lsp";
59
+
60
+ export function useLsp({ editor, monaco, projectName, filePath, enabled }: UseLspOptions): LspState {
61
+ const [status, setStatus] = useState<LspDocumentStatus | null>(null);
62
+ const [diagnostics, setDiagnostics] = useState<LspDiagnostic[]>([]);
63
+ const connectionRef = useRef<LspConnection | null>(null);
64
+
65
+ const active = enabled && Boolean(projectName && filePath && editor && monaco);
66
+
67
+ // Register the providers once Monaco exists. Doing it here rather than at
68
+ // module load keeps it out of the bundle's startup path, and the function
69
+ // itself is idempotent per language.
70
+ useEffect(() => {
71
+ if (!monaco || !active) return;
72
+ registerLspProviders(monaco);
73
+ }, [monaco, active]);
74
+
75
+ // Open the document, keep it in step, and close it on the way out.
76
+ useEffect(() => {
77
+ if (!active || !editor || !monaco || !projectName || !filePath) {
78
+ setStatus(null);
79
+ setDiagnostics([]);
80
+ return;
81
+ }
82
+
83
+ const model = editor.getModel();
84
+ if (!model) return;
85
+
86
+ const connection = acquireLspConnection(projectName);
87
+ connectionRef.current = connection;
88
+ registerLspDocument(model, { connection, path: filePath });
89
+
90
+ const offStatus = connection.onStatus((path, next) => {
91
+ if (path !== filePath) return;
92
+ setStatus(next);
93
+ // Semantic tokens are indices into a legend only the server knows, so the
94
+ // provider cannot be registered until one has answered. Idempotent per
95
+ // language, so every editor mount arriving here costs nothing.
96
+ if (next.state === "ready") {
97
+ const legend = semanticTokensLegendOf(next.capabilities);
98
+ if (legend) registerSemanticTokens(monaco, model.getLanguageId(), legend);
99
+ }
100
+ });
101
+
102
+ const offNotification = connection.onNotification((method, params) => {
103
+ if (method !== "textDocument/publishDiagnostics") return;
104
+ const payload = params as { uri?: string; diagnostics?: LspDiagnostic[] };
105
+ // The bridge rewrote the URI to this model's, so a mismatch means the
106
+ // diagnostics belong to a different file this socket also has open.
107
+ if (payload.uri !== model.uri.toString()) return;
108
+
109
+ const list = payload.diagnostics ?? [];
110
+ setDiagnostics(list);
111
+ // Also to the shared store, which is what the Problems panel reads. The
112
+ // markers below only draw on this model, so they can say what is wrong
113
+ // with *this* file and nothing more.
114
+ useProblemsStore.getState().publish(projectName, filePath, list);
115
+ monaco.editor.setModelMarkers(
116
+ model,
117
+ MARKER_OWNER,
118
+ list.map((diagnostic) => ({
119
+ ...fromLspRange(diagnostic.range),
120
+ message: diagnostic.message,
121
+ severity: markerSeverity(monaco, diagnostic.severity),
122
+ source: diagnostic.source,
123
+ code: diagnostic.code === undefined ? undefined : String(diagnostic.code),
124
+ })),
125
+ );
126
+ });
127
+
128
+ connection.open(filePath, {
129
+ getText: () => model.getValue(),
130
+ getVersion: () => model.getVersionId(),
131
+ clientUri: model.uri.toString(),
132
+ });
133
+
134
+ const onChange = model.onDidChangeContent((event) => {
135
+ connection.change(
136
+ filePath,
137
+ event.versionId,
138
+ // Monaco's ranges are 1-based and its changes within one event are
139
+ // already ordered bottom-up, which is the order LSP applies them in.
140
+ event.changes.map((change) => ({
141
+ range: {
142
+ start: { line: change.range.startLineNumber - 1, character: change.range.startColumn - 1 },
143
+ end: { line: change.range.endLineNumber - 1, character: change.range.endColumn - 1 },
144
+ },
145
+ text: change.text,
146
+ })),
147
+ );
148
+ });
149
+
150
+ return () => {
151
+ onChange.dispose();
152
+ offStatus();
153
+ offNotification();
154
+ // Clear our markers so a closed file's errors do not outlive it.
155
+ monaco.editor.setModelMarkers(model, MARKER_OWNER, []);
156
+ useProblemsStore.getState().clear(projectName, filePath);
157
+ unregisterLspDocument(model);
158
+ connection.close(filePath);
159
+ // The shadow models exist only so Monaco can resolve a peek or an F12 into a file that
160
+ // is not open. Once the last editor for the project has gone there is nothing left to
161
+ // resolve them for, and forty files' contents are pure memory until the page reloads.
162
+ if (releaseLspConnection(projectName)) disposeShadowModels();
163
+ connectionRef.current = null;
164
+ setStatus(null);
165
+ setDiagnostics([]);
166
+ };
167
+ }, [active, editor, monaco, projectName, filePath]);
168
+
169
+ return { status, diagnostics };
170
+ }
171
+
172
+ /** Tell the server a save happened, so servers that only analyse on save catch up. */
173
+ export function notifyLspSave(projectName: string, filePath: string, text: string): void {
174
+ // Uses the shared connection rather than a hook, because a save comes from
175
+ // the toolbar and the keybinding as well as from the editor.
176
+ const connection = acquireLspConnection(projectName);
177
+ try {
178
+ connection.save(filePath, text);
179
+ } finally {
180
+ releaseLspConnection(projectName);
181
+ }
182
+ }