@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.
- package/CHANGELOG.md +108 -0
- package/CLAUDE.md +42 -1
- package/LICENSE +5 -0
- package/THIRD-PARTY-NOTICES.md +83 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/cli-reference.md +4 -4
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/bun.lock +38 -7
- package/dist/web/assets/KaTeX_Size3-Regular-gV2CO0n9.woff2 +0 -0
- package/dist/web/assets/accounts-settings-section-BuxD9zH3.js +1 -0
- package/dist/web/assets/ai-resource-editor-F09pf8Hd.js +1 -0
- package/dist/web/assets/ai-settings-section-Dd9tOUp0.js +1 -0
- package/dist/web/assets/ai-settings-section-FrU2X8Fu.js +1 -0
- package/dist/web/assets/{angular-html-D4qjt-75.js → angular-html-DkR4iCth.js} +1 -1
- package/dist/web/assets/{angular-ts-DvLn04T8.js → angular-ts-DcyL4Chx.js} +1 -1
- package/dist/web/assets/api-client-BUCo1lms.js +1 -0
- package/dist/web/assets/{api-client-DCzgxFNY.js → api-client-bfB7cXRM.js} +1 -1
- package/dist/web/assets/{api-settings-t5xLrBkQ.js → api-settings-BcNjZIvG.js} +1 -1
- package/dist/web/assets/{api-themes-CJmyQeMk.js → api-themes-DBfyVUtX.js} +1 -1
- package/dist/web/assets/{apl-DQOoPzqd.js → apl-BVlrVtjt.js} +1 -1
- package/dist/web/assets/appearance-settings-section-whgnq3ss.js +1 -0
- package/dist/web/assets/architecture-PBZL5I3N-5K0wEkAn.js +1 -0
- package/dist/web/assets/{astro-C2zFJ1Er.js → astro-MjJlozLj.js} +1 -1
- package/dist/web/assets/audio-preview-Bc54GCAV.js +1 -0
- package/dist/web/assets/{blade-CBD8sEa1.js → blade-DnJWi1fz.js} +1 -1
- package/dist/web/assets/{bsl-bs2JpeTQ.js → bsl-DCmJxSIz.js} +1 -1
- package/dist/web/assets/{button-DHI8IY_N.js → button-VW4QGKCn.js} +1 -1
- package/dist/web/assets/{cairo-DT2g4i_6.js → cairo-C8dDenub.js} +1 -1
- package/dist/web/assets/chat-tab-Cr6_KSGO.js +15 -0
- package/dist/web/assets/{cobol-B2rp6LA1.js → cobol-DPx_nifl.js} +1 -1
- package/dist/web/assets/code-editor-DfmlGamv.js +7 -0
- package/dist/web/assets/codex-daily-guard-CfybHv_c.js +1 -0
- package/dist/web/assets/{coffee-D5ShQC08.js → coffee-DvFzqhgN.js} +1 -1
- package/dist/web/assets/conflict-editor-DenQUOT2.js +19 -0
- package/dist/web/assets/context-menu-DOODKZdF.js +1 -0
- package/dist/web/assets/{cpp-BmKOH-E0.js → cpp-BLJN0umi.js} +1 -1
- package/dist/web/assets/{createLucideIcon-CLMdC3Kl.js → createLucideIcon-DoiEKeJ_.js} +1 -1
- package/dist/web/assets/{crystal-B7u_ZTpu.js → crystal-BXR-9fGw.js} +1 -1
- package/dist/web/assets/csv-preview-CClrJOuR.js +2 -0
- package/dist/web/assets/{data-grid-overlay-editor-DJWgclot.js → data-grid-overlay-editor-D4fhcMfT.js} +1 -1
- package/dist/web/assets/{data-grid-types-Uu77aFvI.js → data-grid-types-OgUxMLdQ.js} +1 -1
- package/dist/web/assets/database-viewer-DItjm8wB.js +1 -0
- package/dist/web/assets/dialog-DQTn55Mt.js +1 -0
- package/dist/web/assets/diff-viewer-BpNj7pN9.js +4 -0
- package/dist/web/assets/{dist-BTdRgQig.js → dist-CrBOCtCW.js} +1 -1
- package/dist/web/assets/docx-preview-DYBkiUaE.js +12 -0
- package/dist/web/assets/{edge--MpXROh5.js → edge-rWOlCmXT.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-ESj6hMoD.js → edit-diff-preview-COtmo54G.js} +3 -3
- package/dist/web/assets/editor-font-BDrdiGf1.js +1 -0
- package/dist/web/assets/editor-language-service-DxkZ51E5.js +1 -0
- package/dist/web/assets/{elixir-DL8mOfzH.js → elixir-E7Y82okW.js} +1 -1
- package/dist/web/assets/{elm-eVlzIFEZ.js → elm-DTPGbc-w.js} +1 -1
- package/dist/web/assets/{erb-BgvaH9l0.js → erb-DHqLHrE6.js} +1 -1
- package/dist/web/assets/{erlang-CEf8Sfhs.js → erlang-Byg0nNiV.js} +1 -1
- package/dist/web/assets/{esm-C5xqy163.js → esm-D_DmOM7n.js} +2 -2
- package/dist/web/assets/explorer-body-D-5z464e.js +2 -0
- package/dist/web/assets/explorer-window-content-7-1wuRul.js +1 -0
- package/dist/web/assets/extension-manager-section-BhwB6nqr.js +1 -0
- package/dist/web/assets/extension-webview-DI4VL2tJ.js +12 -0
- package/dist/web/assets/file-icons-EzPL0q-k.js +1 -0
- package/dist/web/assets/file-icons.generated-CfaJuvZu.css +1 -0
- package/dist/web/assets/file-store-DMABxOkV.js +1 -0
- package/dist/web/assets/files-settings-section-CZzABuKz.js +1 -0
- package/dist/web/assets/format-file-meta-DOpzJJhS.js +1 -0
- package/dist/web/assets/{fortran-fixed-form-yAUsSjab.js → fortran-fixed-form-CY1n0Xf6.js} +1 -1
- package/dist/web/assets/{fsharp-BEWvY_ZR.js → fsharp-_vEDSCJz.js} +1 -1
- package/dist/web/assets/{gdresource-CYZFZ057.js → gdresource-B6XT0wAC.js} +1 -1
- package/dist/web/assets/geist-cyrillic-ext-wght-italic-BYAq_K0C.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-wght-italic-Da0gXVk3.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/web/assets/geist-latin-ext-wght-italic-XgKbg5n7.woff2 +0 -0
- package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/web/assets/geist-latin-wght-italic-dTnRTFFJ.woff2 +0 -0
- package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/web/assets/geist-vietnamese-wght-italic-0fly6zkB.woff2 +0 -0
- package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/web/assets/general-settings-section-BcxwiZ0X.js +1 -0
- package/dist/web/assets/{git-commit-DedchUJ6.js → git-commit-Wk9ovq59.js} +1 -1
- package/dist/web/assets/git-log-panel-CRN4JVOx.js +1 -0
- package/dist/web/assets/{git-rebase-DPvHNzQr.js → git-rebase-DSarGPvK.js} +1 -1
- package/dist/web/assets/git-repo-store-Dy69YCHN.js +1 -0
- package/dist/web/assets/gitGraph-HDMCJU4V-DkVT2MAM.js +1 -0
- package/dist/web/assets/glide-data-grid-BvgAqSUr.js +141 -0
- package/dist/web/assets/{glimmer-js-B4hPYBMX.js → glimmer-js-CkYI35_P.js} +1 -1
- package/dist/web/assets/{glimmer-ts-C0WfcQnO.js → glimmer-ts-BqmIZcds.js} +1 -1
- package/dist/web/assets/{glsl-DHW88hTv.js → glsl-Be-yBCF5.js} +1 -1
- package/dist/web/assets/{graphql-CEvXbo6e.js → graphql-a5DrENHY.js} +1 -1
- package/dist/web/assets/group-chat-tab-DFa5mAx5.js +1 -0
- package/dist/web/assets/{hack-lKfhn1vw.js → hack-BLAg20aD.js} +1 -1
- package/dist/web/assets/{haml-AjKlANaB.js → haml-Dj6bGOQH.js} +1 -1
- package/dist/web/assets/{handlebars-B8fZzj2G.js → handlebars-dmEa36Oh.js} +1 -1
- package/dist/web/assets/{html-derivative-VZmoMdQD.js → html-derivative-lLi3-RNT.js} +1 -1
- package/dist/web/assets/{html-H_S3FJMj.js → html-yacZYzSE.js} +1 -1
- package/dist/web/assets/{http-DBxROFKc.js → http-1KaxcE4e.js} +1 -1
- package/dist/web/assets/{hurl-Hf7XWQHN.js → hurl-ST-dEEZR.js} +1 -1
- package/dist/web/assets/{hxml-BRhRKwSo.js → hxml-CpDtuq__.js} +1 -1
- package/dist/web/assets/icons-DQjqk0lJ.js +1 -0
- package/dist/web/assets/image-preview-CJVxL0uH.js +1 -0
- package/dist/web/assets/index-D7DbXD3G.css +1 -0
- package/dist/web/assets/index-ZtfxZOyb.js +52 -0
- package/dist/web/assets/info-3K5VOQVL-BBsmKGzA.js +1 -0
- package/dist/web/assets/input-D-dR8RI6.js +1 -0
- package/dist/web/assets/{jinja-D3jMH0jG.js → jinja-Cjw-evAn.js} +1 -1
- package/dist/web/assets/{jira-watcher-section-DZvWeUAW.js → jira-watcher-section-DIC1yIV3.js} +1 -1
- package/dist/web/assets/{jison-CZtpkLiY.js → jison-DfATMYoY.js} +1 -1
- package/dist/web/assets/{julia-DwFjOpos.js → julia-DDCaxiqT.js} +1 -1
- package/dist/web/assets/{just-BEfj8dHN.js → just-CJL529u6.js} +1 -1
- package/dist/web/assets/keybindings-store-tVfhPANS.js +1 -0
- package/dist/web/assets/keyboard-shortcuts-section-BW03P3AF.js +1 -0
- package/dist/web/assets/{latex-C6Rb_zGG.js → latex-Zc4EpLpW.js} +1 -1
- package/dist/web/assets/{lib-CFTK00ux.js → lib-BVwmtv2i.js} +1 -1
- package/dist/web/assets/{liquid-DTVs9cD3.js → liquid-B_6KMNYS.js} +1 -1
- package/dist/web/assets/{lua-C1zfiqhG.js → lua-BtS2idK7.js} +1 -1
- package/dist/web/assets/markdown-renderer-CvL1pWeK.js +3 -0
- package/dist/web/assets/markdown-renderer-sJNNVhlS.js +1 -0
- package/dist/web/assets/{marko-_hrXozl2.js → marko-Wk6LBnck.js} +1 -1
- package/dist/web/assets/{mdc-AX9XWu8K.js → mdc-cRaXBrzL.js} +1 -1
- package/dist/web/assets/{media-url-D43IHXnP.js → media-url-DL8OCGGg.js} +1 -1
- package/dist/web/assets/{mobile-bottom-sheet-GSto0_0m.js → mobile-bottom-sheet-CoUauvLF.js} +1 -1
- package/dist/web/assets/mobile-explorer-sheet-CZ0HZ2E_.js +1 -0
- package/dist/web/assets/monaco-dotenv-language-BDYnKcnr.js +1 -0
- package/dist/web/assets/monaspace-argon-latin-400-italic-DHf095HZ.woff2 +0 -0
- package/dist/web/assets/monaspace-argon-latin-400-italic-DZMiIHEH.woff +0 -0
- package/dist/web/assets/monaspace-argon-latin-400-normal-DZUN4ACH.woff +0 -0
- package/dist/web/assets/monaspace-argon-latin-400-normal-RS-2TGNg.woff2 +0 -0
- package/dist/web/assets/monaspace-argon-latin-700-normal-4y--rLW1.woff +0 -0
- package/dist/web/assets/monaspace-argon-latin-700-normal-D9kWRRK5.woff2 +0 -0
- package/dist/web/assets/monaspace-krypton-latin-400-italic-BoBCEexI.woff2 +0 -0
- package/dist/web/assets/monaspace-krypton-latin-400-italic-LWEicbvC.woff +0 -0
- package/dist/web/assets/monaspace-krypton-latin-400-normal-D9XlxC9R.woff +0 -0
- package/dist/web/assets/monaspace-krypton-latin-400-normal-DsuVXUab.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-codicons-DSvMY_FK.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-devicons-BBab8P54.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-font-awesome-BzNW1pRA.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-font-awesome-ext-D30e--UY.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-font-awesome-legacy-D_qekXx9.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-font-logos-gdu3INfy.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-iec-power-Cw6TNeDf.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-material-l-CXi9Ay.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-misc-BaVfdyeB.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-octicons-CJLTTzKm.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-pomicons-D7T3Ya3H.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-powerline-Cgg0sdGS.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-seti-DYiUFq6z.woff2 +0 -0
- package/dist/web/assets/nerd-symbols-weather-D4Jrp5XD.woff2 +0 -0
- package/dist/web/assets/{nextflow-xJ5dkaQ2.js → nextflow-Bos2wvDV.js} +1 -1
- package/dist/web/assets/{nginx-BfbjvmIV.js → nginx-DMlOwzdr.js} +1 -1
- package/dist/web/assets/{nim-KrUnNSwZ.js → nim-D2dZQA88.js} +1 -1
- package/dist/web/assets/notification-store-BZbsPnW0.js +1 -0
- package/dist/web/assets/notifications-settings-section-DPUROMw-.js +1 -0
- package/dist/web/assets/{number-overlay-editor-CGZ1ObrN.js → number-overlay-editor-DZ2i_Bnb.js} +1 -1
- package/dist/web/assets/{overview-panel-Ni1Wqr3E.js → overview-panel-R146OIom.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-DwmYPOlx.js +1 -0
- package/dist/web/assets/panel-store-BVLBRn6M.js +1 -0
- package/dist/web/assets/pdf-preview-BWUPGLp6.js +1 -0
- package/dist/web/assets/{perl-DAexWIeo.js → perl-C5-Z6fPn.js} +1 -1
- package/dist/web/assets/{php-DXc7GdU9.js → php-BXNNhkMH.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-D0oogIFi.js +1 -0
- package/dist/web/assets/portal-container-context-BarKmT4S.js +1 -0
- package/dist/web/assets/{postgres-viewer-DmbVhmJ8.js → postgres-viewer-CjOvaruz.js} +3 -3
- package/dist/web/assets/ppmbot-settings-section-DrvWh8l8.js +1 -0
- package/dist/web/assets/problems-panel-B7BWVhdy.js +1 -0
- package/dist/web/assets/process-table-BRMS1MrX.js +1 -0
- package/dist/web/assets/{project-store-DCDLF-x3.js → project-store-BhMbVln3.js} +1 -1
- package/dist/web/assets/proxy-settings-section-Bv0Ny-Yy.js +1 -0
- package/dist/web/assets/{pug-CHds8FDl.js → pug-C1zf1yWy.js} +1 -1
- package/dist/web/assets/{qml-DBt6oNnU.js → qml-OW58jGpD.js} +1 -1
- package/dist/web/assets/query-audit-section-BcHJZcVC.js +1 -0
- package/dist/web/assets/radar-KQ55EAFF-CQIJOQGa.js +1 -0
- package/dist/web/assets/{razor-DVDe2z8Z.js → razor-DzjSaobM.js} +1 -1
- package/dist/web/assets/{react-Bf5xrFLG.js → react-Bghu0NUO.js} +1 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-ByjaeZKX.js +2 -0
- package/dist/web/assets/remote-desktop-mobile-view-D13mtr9F.js +1 -0
- package/dist/web/assets/remote-desktop-readiness-gate-BTzss2wX.js +1 -0
- package/dist/web/assets/remote-desktop-window-content-CbqTCaC6.js +1 -0
- package/dist/web/assets/{rst-s3rP0H8p.js → rst-RfuihOUW.js} +1 -1
- package/dist/web/assets/{ruby-sRcfbjlr.js → ruby-CNO3pli1.js} +1 -1
- package/dist/web/assets/{run-in-terminal-Yt_lq4T9.js → run-in-terminal-Cb_hVU8x.js} +1 -1
- package/dist/web/assets/{sas-CuyZeQJw.js → sas-DZY5BtXx.js} +1 -1
- package/dist/web/assets/schedules-settings-section-DO8xAOVj.js +1 -0
- package/dist/web/assets/scroll-area-LtNV8g5o.js +1 -0
- package/dist/web/assets/{scss-B9m4FneT.js → scss--4g-REcN.js} +1 -1
- package/dist/web/assets/{send-to-chat-01eMNs3j.js → send-to-chat-Cnpru1M0.js} +1 -1
- package/dist/web/assets/separator-Cds1yxy8.js +1 -0
- package/dist/web/assets/settings-body-Rnu-FcX-.js +2 -0
- package/dist/web/assets/settings-store-DZPgPtEA.js +2 -0
- package/dist/web/assets/settings-tab-C6PHxs0Z.js +1 -0
- package/dist/web/assets/settings-window-content-CQ4gT2qj.js +1 -0
- package/dist/web/assets/{shaderlab-BuCltaXx.js → shaderlab-Cu4sBiVn.js} +1 -1
- package/dist/web/assets/{shellsession-DG_WIFRW.js → shellsession-DWzJfEv7.js} +1 -1
- package/dist/web/assets/{soy-CKNCwmqR.js → soy-BnqE-5Ff.js} +1 -1
- package/dist/web/assets/{sparql-BEH92-9e.js → sparql-Ctg__NhZ.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BTMEy88p.js → sql-query-editor-D9k19T_M.js} +1 -1
- package/dist/web/assets/sqlite-viewer-DoV9hnWJ.js +1 -0
- package/dist/web/assets/{stata-Bt5IUWCl.js → stata-Qk2h66XW.js} +1 -1
- package/dist/web/assets/{streaming-store-Dw3ZR1E4.js → streaming-store-uDu3PoN1.js} +1 -1
- package/dist/web/assets/{surrealql-B5M94PT2.js → surrealql-8QEX7EfH.js} +1 -1
- package/dist/web/assets/{svelte-BqLoF5fB.js → svelte-D_mubC5-.js} +1 -1
- package/dist/web/assets/system-monitor-body-2vQ1kMxE.js +2 -0
- package/dist/web/assets/system-monitor-tab-krAcvwF7.js +1 -0
- package/dist/web/assets/system-monitor-window-content-qXLcicFM.js +1 -0
- package/dist/web/assets/tab-host-window-content-7fPZNEni.js +1 -0
- package/dist/web/assets/{tab-store-Dsk4jnlN.js → tab-store-DGJGnbwv.js} +1 -1
- package/dist/web/assets/team-member-sheet-2FnRmk1a.js +2 -0
- package/dist/web/assets/team-member-window-content-BgvJFypM.js +1 -0
- package/dist/web/assets/{templ-BxGWIwYz.js → templ-C1jV0fsO.js} +1 -1
- package/dist/web/assets/terminal-tab-Cs0sGljx.js +3 -0
- package/dist/web/assets/{tex-B9CPrNBA.js → tex-D_StFXy_.js} +1 -1
- package/dist/web/assets/tool-cards-DU_S2o51.js +9 -0
- package/dist/web/assets/treemap-KZPCXAKY-BhEtjljr.js +1 -0
- package/dist/web/assets/{ts-tags-CObhnP_s.js → ts-tags-B5m47rEm.js} +1 -1
- package/dist/web/assets/{twig-ZcDaz0E8.js → twig-C_br6GIl.js} +1 -1
- package/dist/web/assets/{use-blob-url-D-NnFGAr.js → use-blob-url-C-SGi_Hb.js} +1 -1
- package/dist/web/assets/use-inline-blame-B4trxGcR.js +16 -0
- package/dist/web/assets/{use-is-mobile-BsqeOLv4.js → use-is-mobile-BQ9Bv5Ga.js} +1 -1
- package/dist/web/assets/use-lsp-CV0vzILO.js +6 -0
- package/dist/web/assets/use-monaco-theme-DBqbWjWX.js +1 -0
- package/dist/web/assets/use-open-team-member-DENsjp0s.js +1 -0
- package/dist/web/assets/use-remote-desktop-display-choice-BK_f787P.js +1 -0
- package/dist/web/assets/{use-visual-viewport-hdC_hRtB.js → use-visual-viewport-CbwnktSG.js} +1 -1
- package/dist/web/assets/{use-websocket-CUKjQFAl.js → use-websocket-LgXiX1qN.js} +1 -1
- package/dist/web/assets/vendor-markdown-CuWCHIVb.js +291 -0
- package/dist/web/assets/{vendor-mermaid-BoRFiriK.js → vendor-mermaid-Cbig5zA6.js} +1 -1
- package/dist/web/assets/{vendor-ui-D1NQnrtd.js → vendor-ui-BBdkypKW.js} +1 -1
- package/dist/web/assets/video-preview-BDNwumbW.js +1 -0
- package/dist/web/assets/{vue-TgfQfAF8.js → vue-DQwCnLdr.js} +1 -1
- package/dist/web/assets/{vue-html-DbAh9aHW.js → vue-html-T_EoGpPJ.js} +1 -1
- package/dist/web/assets/{vue-vine-DQ8US6vO.js → vue-vine-DmxLqX50.js} +1 -1
- package/dist/web/assets/{window-pip-registry-DfPfSFQg.js → window-pip-registry-3l4hoxuD.js} +1 -1
- package/dist/web/assets/{window-store-BSXqIkwB.js → window-store-UC1jJeLM.js} +1 -1
- package/dist/web/assets/ws-auth-DEAJiGCR.js +1 -0
- package/dist/web/assets/{xml-CXzUNYMl.js → xml-Bs6Bw8is.js} +1 -1
- package/dist/web/assets/{xsl-CdnFww1s.js → xsl-f5ZNhRCc.js} +1 -1
- package/dist/web/index.html +107 -73
- package/dist/web/sw.js +1 -1
- package/docs/project-roadmap.md +2 -0
- package/licenses/Apache-2.0.txt +73 -0
- package/licenses/CC-BY-4.0.txt +156 -0
- package/licenses/MIT.txt +18 -0
- package/licenses/OFL-1.1.txt +43 -0
- package/licenses/Unlicense.txt +10 -0
- package/package.json +14 -7
- package/packages/ext-git-graph/src/blame-view.ts +4 -5
- package/packages/ext-git-graph/src/commit-detail-escaping.test.ts +205 -0
- package/packages/ext-git-graph/src/commit-detail-file-cap.test.ts +65 -0
- package/packages/ext-git-graph/src/commit-message-html.test.ts +214 -0
- package/packages/ext-git-graph/src/commit-message-html.ts +190 -0
- package/packages/ext-git-graph/src/commit-request-generation.test.ts +57 -0
- package/packages/ext-git-graph/src/compare-view.ts +4 -5
- package/packages/ext-git-graph/src/extension.ts +148 -36
- package/packages/ext-git-graph/src/file-history-view.ts +4 -5
- package/packages/ext-git-graph/src/log-args.test.ts +57 -0
- package/packages/ext-git-graph/src/ppm-api.ts +39 -6
- package/packages/ext-git-graph/src/project-scope.test.ts +77 -0
- package/packages/ext-git-graph/src/project-scope.ts +69 -0
- package/packages/ext-git-graph/src/shortstat-parser.test.ts +53 -0
- package/packages/ext-git-graph/src/shortstat-parser.ts +45 -0
- package/packages/ext-git-graph/src/types.ts +2 -0
- package/packages/ext-git-graph/src/webview-html.test.ts +407 -0
- package/packages/ext-git-graph/src/webview-html.ts +631 -108
- package/packages/ext-git-graph/src/webview-shell.test.ts +63 -0
- package/packages/ext-git-graph/src/webview-shell.ts +48 -7
- package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
- package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
- package/scripts/check-ppm-dir-usage.sh +0 -0
- package/scripts/copy-monaco.ts +63 -0
- package/scripts/gen-file-icons.ts +485 -0
- package/scripts/gen-nerd-font.ts +311 -0
- package/scripts/gen-product-icons.ts +442 -0
- package/scripts/install.sh +0 -0
- package/scripts/monaco-staging.ts +32 -0
- package/scripts/precompress-web.ts +77 -0
- package/scripts/release.sh +0 -0
- package/scripts/third-party-notices.ts +160 -0
- package/scripts/vite-monaco-dev-assets.ts +63 -0
- package/src/providers/claude-agent-sdk.ts +32 -2
- package/src/server/index.ts +17 -0
- package/src/server/routes/chat.ts +16 -6
- package/src/server/routes/git.ts +113 -1
- package/src/server/routes/lsp.ts +58 -0
- package/src/server/routes/project-scoped.ts +2 -0
- package/src/server/routes/static-encoding.ts +73 -0
- package/src/server/routes/static-fallback.ts +51 -0
- package/src/server/routes/static.ts +41 -5
- package/src/server/ws/lsp.ts +433 -0
- package/src/services/chat-search.service.ts +211 -26
- package/src/services/edge-forwarder.ts +191 -191
- package/src/services/fs-ops/fs-real-path.ts +23 -0
- package/src/services/git-blame/commit-line-diff.ts +124 -0
- package/src/services/git-blame/git-blame.service.ts +96 -1
- package/src/services/git-repos/git-repo-discovery.ts +152 -0
- package/src/services/lsp/lsp-capabilities.ts +160 -0
- package/src/services/lsp/lsp-manager.ts +442 -0
- package/src/services/lsp/lsp-protocol.ts +170 -0
- package/src/services/lsp/lsp-session.ts +466 -0
- package/src/services/lsp/server-registry.ts +401 -0
- package/src/services/search-index-db.service.ts +10 -2
- package/src/services/windows-process-tree.ts +351 -351
- package/src/shared/blame.ts +51 -0
- package/src/shared/lsp-uri.ts +108 -0
- package/src/web/app.tsx +6 -0
- package/src/web/components/ai-resources/ai-resource-editor.tsx +1 -1
- package/src/web/components/ai-resources/ai-resources-panel.tsx +1 -1
- package/src/web/components/ai-resources/mcp-group.tsx +1 -1
- package/src/web/components/ai-resources/new-resource-menu.tsx +1 -1
- package/src/web/components/ai-resources/resource-visuals.tsx +1 -1
- package/src/web/components/auth/login-screen.tsx +1 -1
- package/src/web/components/auth/support-dialog.tsx +1 -1
- package/src/web/components/chat/attachment-chips.tsx +113 -5
- package/src/web/components/chat/background-command-bar.tsx +1 -1
- package/src/web/components/chat/background-output-panel.tsx +1 -1
- package/src/web/components/chat/change-edit-list.tsx +1 -1
- package/src/web/components/chat/change-file-row.tsx +1 -1
- package/src/web/components/chat/chat-history-bar.tsx +2 -2
- package/src/web/components/chat/chat-history-panel.tsx +1 -1
- package/src/web/components/chat/chat-placeholder.tsx +1 -1
- package/src/web/components/chat/chat-scroll-nav.tsx +1 -1
- package/src/web/components/chat/chat-tab.tsx +1 -1
- package/src/web/components/chat/chat-toolbar-overflow-menu.tsx +1 -1
- package/src/web/components/chat/chat-welcome.tsx +1 -1
- package/src/web/components/chat/codex-usage-panel.tsx +1 -1
- package/src/web/components/chat/file-picker.tsx +1 -1
- package/src/web/components/chat/image-preview-states.tsx +1 -1
- package/src/web/components/chat/message-action-bar.tsx +1 -1
- package/src/web/components/chat/message-input.tsx +1 -1
- package/src/web/components/chat/message-list.tsx +1 -1
- package/src/web/components/chat/mode-selector.tsx +1 -1
- package/src/web/components/chat/model-selector.tsx +1 -1
- package/src/web/components/chat/model-thinking-selector.tsx +1 -1
- package/src/web/components/chat/pre-compact-button.tsx +1 -1
- package/src/web/components/chat/provider-selector.tsx +1 -1
- package/src/web/components/chat/send-message-card.tsx +1 -1
- package/src/web/components/chat/session-context-menu.tsx +1 -1
- package/src/web/components/chat/session-debug-dialog.tsx +1 -1
- package/src/web/components/chat/session-history-list.tsx +1 -1
- package/src/web/components/chat/session-list-panel.tsx +1 -1
- package/src/web/components/chat/session-picker.tsx +1 -1
- package/src/web/components/chat/slash-command-picker.tsx +1 -1
- package/src/web/components/chat/task-tracker.tsx +1 -1
- package/src/web/components/chat/team-activity-panel.tsx +1 -1
- package/src/web/components/chat/team-member-activity-row.tsx +1 -1
- package/src/web/components/chat/team-member-list.tsx +1 -1
- package/src/web/components/chat/team-member-sheet.tsx +1 -1
- package/src/web/components/chat/team-member-window-content.tsx +1 -1
- package/src/web/components/chat/team-working-bar.tsx +1 -1
- package/src/web/components/chat/tool-cards.tsx +2 -2
- package/src/web/components/chat/turn-change-sheet.tsx +1 -1
- package/src/web/components/chat/turn-change-tray.tsx +1 -1
- package/src/web/components/chat/turn-cost-warning.tsx +1 -1
- package/src/web/components/chat/usage-badge.tsx +1 -1
- package/src/web/components/chat/usage-panel-shell.tsx +1 -1
- package/src/web/components/chat/version-switcher.tsx +1 -1
- package/src/web/components/database/connection-import-export.tsx +1 -1
- package/src/web/components/database/connection-list.tsx +1 -1
- package/src/web/components/database/connection-row.tsx +1 -1
- package/src/web/components/database/database-sidebar.tsx +1 -1
- package/src/web/components/database/database-viewer.tsx +1 -1
- package/src/web/components/database/export-button.tsx +1 -1
- package/src/web/components/database/glide-context-menu.tsx +1 -1
- package/src/web/components/database/glide-data-grid.tsx +1 -1
- package/src/web/components/database/glide-data-preview-panel.tsx +2 -2
- package/src/web/components/database/glide-grid-pagination.tsx +1 -1
- package/src/web/components/database/glide-grid-toolbar.tsx +1 -1
- package/src/web/components/database/glide-header-menu.tsx +1 -1
- package/src/web/components/database/glide-save-bar.tsx +1 -1
- package/src/web/components/database/schema-table-tree.tsx +1 -1
- package/src/web/components/editor/audio-preview.tsx +1 -1
- package/src/web/components/editor/code-editor.tsx +167 -21
- package/src/web/components/editor/compare-picker.tsx +1 -1
- package/src/web/components/editor/conflict-editor.tsx +15 -6
- package/src/web/components/editor/csv-preview.tsx +1 -1
- package/src/web/components/editor/diff-viewer.tsx +59 -37
- package/src/web/components/editor/docx-preview.tsx +1 -1
- package/src/web/components/editor/editor-breadcrumb-external.tsx +1 -1
- package/src/web/components/editor/editor-breadcrumb.tsx +1 -1
- package/src/web/components/editor/editor-language-picker.tsx +3 -1
- package/src/web/components/editor/editor-language-service.tsx +77 -0
- package/src/web/components/editor/editor-mobile-toolbar.tsx +13 -2
- package/src/web/components/editor/editor-placeholder.tsx +1 -1
- package/src/web/components/editor/editor-toolbar.tsx +1 -1
- package/src/web/components/editor/image-preview.tsx +1 -1
- package/src/web/components/editor/lsp-status.tsx +241 -0
- package/src/web/components/editor/pdf-preview.tsx +1 -1
- package/src/web/components/editor/video-player/video-player-controls.tsx +1 -1
- package/src/web/components/editor/video-player/video-player.tsx +1 -1
- package/src/web/components/editor/video-player/video-settings-menu.tsx +1 -1
- package/src/web/components/editor/video-preview.tsx +1 -1
- package/src/web/components/explorer/file-tree.tsx +1 -1
- package/src/web/components/explorer/inline-tree-input.tsx +1 -1
- package/src/web/components/explorer/search-panel.tsx +3 -2
- package/src/web/components/explorer/tree-node-context-menu.tsx +1 -1
- package/src/web/components/explorer/tree-node.tsx +5 -12
- package/src/web/components/extensions/extension-quickpick.tsx +1 -1
- package/src/web/components/extensions/extension-tree-view.tsx +1 -1
- package/src/web/components/extensions/extension-webview.tsx +53 -20
- package/src/web/components/extensions/webview-theme.ts +121 -0
- package/src/web/components/floating-window/pip/pip-caption-button.tsx +1 -1
- package/src/web/components/git/create-worktree-dialog.tsx +5 -3
- package/src/web/components/git/git-log-panel.tsx +4 -2
- package/src/web/components/git/git-placeholder.tsx +1 -1
- package/src/web/components/git/git-ref-badge.tsx +1 -1
- package/src/web/components/git/git-repo-picker.tsx +145 -0
- package/src/web/components/git/git-status-panel.tsx +231 -250
- package/src/web/components/git/git-worktree-panel.tsx +6 -4
- package/src/web/components/git/hunk-stage-dialog.tsx +5 -3
- package/src/web/components/group-chat/group-chat-tab.tsx +1 -1
- package/src/web/components/group-chat/group-create-dialog.tsx +1 -1
- package/src/web/components/group-chat/group-full-transcript-view.tsx +1 -1
- package/src/web/components/group-chat/group-list.tsx +1 -1
- package/src/web/components/group-chat/group-member-edit-dialog.tsx +1 -1
- package/src/web/components/group-chat/group-member-roster.tsx +1 -1
- package/src/web/components/group-chat/group-message-item.tsx +1 -1
- package/src/web/components/group-chat/group-transcript-messages.tsx +1 -1
- package/src/web/components/jira/jira-config-form.tsx +1 -1
- package/src/web/components/jira/jira-filter-builder.tsx +1 -1
- package/src/web/components/jira/jira-panel.tsx +1 -1
- package/src/web/components/jira/jira-results-panel.tsx +1 -1
- package/src/web/components/jira/jira-ticket-card.tsx +1 -1
- package/src/web/components/jira/jira-ticket-detail.tsx +1 -1
- package/src/web/components/jira/jira-watcher-form.tsx +1 -1
- package/src/web/components/jira/jira-watcher-list.tsx +1 -1
- package/src/web/components/layout/add-project-form.tsx +1 -1
- package/src/web/components/layout/cloud-alias-row.tsx +1 -1
- package/src/web/components/layout/cloud-share-named-tunnel-row.tsx +1 -1
- package/src/web/components/layout/cloud-share-popover.tsx +1 -1
- package/src/web/components/layout/command-palette-filter-chips.tsx +1 -1
- package/src/web/components/layout/command-palette.tsx +46 -8
- package/src/web/components/layout/dock-header.tsx +4 -4
- package/src/web/components/layout/dock-panel.tsx +3 -3
- package/src/web/components/layout/draggable-tab.tsx +20 -3
- package/src/web/components/layout/editor-panel.tsx +1 -1
- package/src/web/components/layout/mobile-drawer-tab-bar.tsx +10 -1
- package/src/web/components/layout/mobile-drawer.tsx +1 -1
- package/src/web/components/layout/mobile-nav.tsx +3 -3
- package/src/web/components/layout/mobile-tab-switcher-sheet.tsx +13 -4
- package/src/web/components/layout/nav-section-rail.tsx +1 -1
- package/src/web/components/layout/notification-bell-popover.tsx +1 -1
- package/src/web/components/layout/panel-layout.tsx +1 -1
- package/src/web/components/layout/project-bottom-sheet.tsx +4 -1
- package/src/web/components/layout/project-sort.ts +1 -1
- package/src/web/components/layout/project-switcher.tsx +1 -1
- package/src/web/components/layout/reparenting-tab.tsx +1 -1
- package/src/web/components/layout/sidebar.tsx +1 -1
- package/src/web/components/layout/status-bar.tsx +4 -1
- package/src/web/components/layout/tab-bar.tsx +9 -23
- package/src/web/components/layout/tab-content.tsx +6 -1
- package/src/web/components/layout/tab-pool.tsx +1 -0
- package/src/web/components/layout/tab-pop-out-menu-item.tsx +1 -1
- package/src/web/components/layout/upgrade-button.tsx +1 -1
- package/src/web/components/layout/wake-lock-indicator.tsx +1 -1
- package/src/web/components/os-explorer/explorer-body.tsx +1 -1
- package/src/web/components/os-explorer/explorer-breadcrumb.tsx +1 -1
- package/src/web/components/os-explorer/explorer-sidebar.tsx +1 -1
- package/src/web/components/os-explorer/explorer-sort-menu.tsx +1 -1
- package/src/web/components/os-explorer/explorer-toolbar.tsx +1 -1
- package/src/web/components/os-explorer/icons/file-type-icon-map.ts +10 -94
- package/src/web/components/os-explorer/icons/file-type-icon.tsx +17 -13
- package/src/web/components/os-explorer/mobile/mobile-bottom-toolbar.tsx +1 -1
- package/src/web/components/os-explorer/mobile/mobile-explorer-top-bar.tsx +1 -1
- package/src/web/components/os-explorer/mobile/mobile-more-sheet.tsx +1 -1
- package/src/web/components/os-explorer/mobile/mobile-places-sheet.tsx +1 -1
- package/src/web/components/os-explorer/mobile/mobile-places-strip.tsx +1 -1
- package/src/web/components/os-explorer/properties-dialog.tsx +1 -1
- package/src/web/components/os-explorer/skins/macos-window-chrome.tsx +1 -1
- package/src/web/components/os-explorer/skins/windows-window-chrome.tsx +1 -1
- package/src/web/components/os-explorer/upload/upload-batch-card.tsx +1 -1
- package/src/web/components/os-explorer/upload/upload-batch-row.tsx +1 -1
- package/src/web/components/os-explorer/use-coarse-long-press.ts +8 -0
- package/src/web/components/os-explorer/views/column-view-mobile.tsx +1 -1
- package/src/web/components/os-explorer/views/icons-view-tile.tsx +1 -1
- package/src/web/components/os-explorer/views/list-row.tsx +1 -1
- package/src/web/components/os-explorer/views/list-view.tsx +1 -1
- package/src/web/components/postgres/postgres-viewer.tsx +1 -1
- package/src/web/components/problems/problems-panel.tsx +230 -0
- package/src/web/components/problems/problems-status.tsx +53 -0
- package/src/web/components/projects/dir-suggest.tsx +1 -1
- package/src/web/components/projects/project-list.tsx +1 -1
- package/src/web/components/remote-desktop/remote-desktop-mobile-toolbar.tsx +1 -1
- package/src/web/components/remote-desktop/remote-desktop-mobile-view.tsx +1 -1
- package/src/web/components/remote-desktop/remote-desktop-readiness-gate.tsx +1 -1
- package/src/web/components/remote-desktop/remote-desktop-warning-gate.tsx +1 -1
- package/src/web/components/remote-desktop/remote-desktop-window-content.tsx +1 -1
- package/src/web/components/root-error-boundary.tsx +116 -0
- package/src/web/components/settings/accounts/account-add-dialog.tsx +1 -1
- package/src/web/components/settings/accounts/account-card.tsx +1 -1
- package/src/web/components/settings/accounts/account-export-dialog.tsx +1 -1
- package/src/web/components/settings/accounts/account-export-simulation.tsx +1 -1
- package/src/web/components/settings/accounts/account-import-dialog.tsx +1 -1
- package/src/web/components/settings/accounts/account-profile-panel.tsx +1 -1
- package/src/web/components/settings/accounts/account-rotation-settings.tsx +1 -1
- package/src/web/components/settings/accounts/account-token-test-dialog.tsx +1 -1
- package/src/web/components/settings/accounts/account-usage-pattern-chart.tsx +1 -1
- package/src/web/components/settings/accounts/accounts-pane-header.tsx +1 -1
- package/src/web/components/settings/accounts/accounts-settings-section.tsx +1 -1
- package/src/web/components/settings/accounts/claude-accounts-section.tsx +9 -1
- package/src/web/components/settings/accounts/codex-accounts-section.tsx +10 -1
- package/src/web/components/settings/accounts/codex-add-account-dialog.tsx +1 -1
- package/src/web/components/settings/accounts/codex-backup-dialog.tsx +1 -1
- package/src/web/components/settings/ai-settings-section.tsx +1 -1
- package/src/web/components/settings/appearance-settings-section.tsx +56 -1
- package/src/web/components/settings/change-password-section.tsx +1 -1
- package/src/web/components/settings/extension-manager-section.tsx +1 -1
- package/src/web/components/settings/general-settings-section.tsx +1 -1
- package/src/web/components/settings/glob-list-editor.tsx +1 -1
- package/src/web/components/settings/keyboard-shortcuts-section.tsx +1 -1
- package/src/web/components/settings/mcp-server-dialog.tsx +1 -1
- package/src/web/components/settings/notifications-settings-section.tsx +1 -1
- package/src/web/components/settings/ppmbot-settings-section.tsx +1 -1
- package/src/web/components/settings/proxy-settings-section.tsx +1 -1
- package/src/web/components/settings/proxy-test-section.tsx +1 -1
- package/src/web/components/settings/query-audit-section.tsx +1 -1
- package/src/web/components/settings/schedules/schedule-row.tsx +1 -1
- package/src/web/components/settings/schedules/schedules-settings-section.tsx +1 -1
- package/src/web/components/settings/settings-body.tsx +1 -1
- package/src/web/components/settings/settings-categories.ts +14 -3
- package/src/web/components/settings/settings-category-list.tsx +1 -1
- package/src/web/components/settings/settings-section-content.tsx +1 -1
- package/src/web/components/settings/tag-settings-section.tsx +1 -1
- package/src/web/components/settings/theme-grid.tsx +1 -1
- package/src/web/components/settings/theme-manager-section.tsx +1 -1
- package/src/web/components/settings/theme-picker.tsx +1 -1
- package/src/web/components/shared/bug-report-popup.tsx +1 -1
- package/src/web/components/shared/connection-lost-overlay.tsx +1 -1
- package/src/web/components/shared/diagram-overlay.tsx +1 -1
- package/src/web/components/shared/image-overlay.tsx +1 -1
- package/src/web/components/shared/theme-mode-menu.tsx +1 -1
- package/src/web/components/sqlite/sqlite-data-grid.tsx +1 -1
- package/src/web/components/sqlite/sqlite-table-list.tsx +1 -1
- package/src/web/components/sqlite/sqlite-viewer.tsx +1 -1
- package/src/web/components/system/process-group-row.tsx +1 -1
- package/src/web/components/system/process-row.tsx +1 -1
- package/src/web/components/system/process-table-toolbar.tsx +1 -1
- package/src/web/components/system/resource-status-bar.tsx +1 -1
- package/src/web/components/system/sortable-header.tsx +1 -1
- package/src/web/components/system/system-monitor-body.tsx +1 -1
- package/src/web/components/terminal/terminal-finish-login.tsx +1 -1
- package/src/web/components/terminal/terminal-links-sheet.tsx +1 -1
- package/src/web/components/terminal/terminal-mobile-toolbar.tsx +1 -1
- package/src/web/components/terminal/terminal-placeholder.tsx +1 -1
- package/src/web/components/terminal/terminal-tab.tsx +1 -1
- package/src/web/components/tunnels/named-tunnel/named-tunnel-login-step.tsx +1 -1
- package/src/web/components/tunnels/named-tunnel/named-tunnel-section.tsx +1 -1
- package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +1 -1
- package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-popup.tsx +1 -1
- package/src/web/components/tunnels/tunnel-manager-tab.tsx +1 -1
- package/src/web/components/ui/accordion.tsx +1 -1
- package/src/web/components/ui/adaptive-context-menu.tsx +9 -2
- package/src/web/components/ui/browse-button.tsx +1 -1
- package/src/web/components/ui/context-menu.tsx +1 -1
- package/src/web/components/ui/dialog.tsx +1 -1
- package/src/web/components/ui/dropdown-menu.tsx +1 -1
- package/src/web/components/ui/file-browser-picker.tsx +4 -6
- package/src/web/components/ui/select.tsx +1 -1
- package/src/web/components/ui/sidebar-header.tsx +1 -1
- package/src/web/components/ui/sonner.tsx +1 -1
- package/src/web/hooks/use-git-repo.ts +124 -0
- package/src/web/hooks/use-global-keybindings.ts +11 -6
- package/src/web/hooks/use-inline-blame.ts +161 -11
- package/src/web/hooks/use-is-touch-only.ts +46 -0
- package/src/web/hooks/use-lsp.ts +182 -0
- package/src/web/hooks/use-terminal.ts +60 -2
- package/src/web/hooks/use-touch-tab-drag.ts +18 -2
- package/src/web/hooks/use-url-sync.ts +15 -1
- package/src/web/index.html +74 -0
- package/src/web/lib/blame-hover-commands.ts +82 -0
- package/src/web/lib/blame-hover.ts +199 -0
- package/src/web/lib/chunk-recovery.ts +113 -0
- package/src/web/lib/editor-font.ts +70 -0
- package/src/web/lib/ext-command-dispatch.ts +24 -0
- package/src/web/lib/file-icons.generated.ts +408 -0
- package/src/web/lib/file-icons.tsx +192 -0
- package/src/web/lib/fluent-icon.tsx +62 -0
- package/src/web/lib/git-file-tree.ts +83 -0
- package/src/web/lib/git-repo-scope.ts +157 -0
- package/src/web/lib/icons.generated.tsx +428 -0
- package/src/web/lib/icons.ts +17 -0
- package/src/web/lib/lsp/lsp-client.ts +321 -0
- package/src/web/lib/lsp/lsp-documents.ts +39 -0
- package/src/web/lib/lsp/lsp-monaco.ts +214 -0
- package/src/web/lib/lsp/lsp-navigation.ts +129 -0
- package/src/web/lib/lsp/lsp-responses.ts +244 -0
- package/src/web/lib/lsp/lsp-semantic-tokens.ts +180 -0
- package/src/web/lib/lsp/lsp-shadow-models.ts +254 -0
- package/src/web/lib/lsp/monaco-builtin-typescript.ts +149 -0
- package/src/web/lib/lsp/register-providers.ts +458 -0
- package/src/web/lib/monaco-diff-language.ts +62 -0
- package/src/web/lib/monaco-dotenv-language.ts +134 -0
- package/src/web/lib/sidebar-tabs/tab-registry.ts +11 -2
- package/src/web/lib/tab-type-icons.ts +32 -4
- package/src/web/main.tsx +30 -1
- package/src/web/stores/git-repo-store.ts +117 -0
- package/src/web/stores/git-status-store.ts +10 -7
- package/src/web/stores/keybindings-store.ts +1 -0
- package/src/web/stores/panel-utils.ts +5 -2
- package/src/web/stores/problems-store.ts +116 -0
- package/src/web/stores/settings-store.ts +40 -0
- package/src/web/stores/tab-store.ts +2 -1
- package/src/web/stores/window-panel-persistence.ts +1 -0
- package/src/web/styles/file-icons.generated.css +1007 -0
- package/src/web/styles/fonts/nerd-symbols-codicons.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-devicons.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-font-awesome-ext.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-font-awesome-legacy.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-font-awesome.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-font-logos.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-iec-power.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-material.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-misc.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-octicons.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-pomicons.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-powerline.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-seti.woff2 +0 -0
- package/src/web/styles/fonts/nerd-symbols-weather.woff2 +0 -0
- package/src/web/styles/globals.css +30 -3
- package/src/web/styles/nerd-font.generated.css +153 -0
- package/src/web/sw.ts +69 -2
- package/src/web/theme/adapters/monaco-adapter.ts +20 -1
- package/src/web/theme/diff-token-rules.ts +34 -0
- package/src/web/theme/semantic-token-rules.ts +103 -0
- package/src/web/theme/theme-mode-options.ts +1 -1
- package/vite.config.ts +24 -7
- package/dist/web/assets/accounts-settings-section-DC2A6FhQ.js +0 -1
- package/dist/web/assets/ai-resource-editor-DDhuy_AR.js +0 -1
- package/dist/web/assets/ai-settings-section-J9Rbs26g.js +0 -1
- package/dist/web/assets/ai-settings-section-OrhLykA2.js +0 -1
- package/dist/web/assets/api-client-PMwZQ4iC.js +0 -1
- package/dist/web/assets/appearance-settings-section-BQ1dH29t.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-D55g5j-p.js +0 -1
- package/dist/web/assets/arrow-left-y44wEZrw.js +0 -1
- package/dist/web/assets/arrow-right-SQ8KJIvE.js +0 -1
- package/dist/web/assets/audio-preview-CAVqEwDi.js +0 -1
- package/dist/web/assets/bot-BNu2OM_S.js +0 -1
- package/dist/web/assets/brain-BsjvCk4k.js +0 -1
- package/dist/web/assets/calendar-clock-Zydwzvp7.js +0 -1
- package/dist/web/assets/chat-tab-D2le8LxY.js +0 -15
- package/dist/web/assets/check-DczxQ5UD.js +0 -1
- package/dist/web/assets/chevron-down-BCt_kn-R.js +0 -1
- package/dist/web/assets/chevron-right-Lt-y9H_e.js +0 -1
- package/dist/web/assets/chevron-up-CRl1AF4q.js +0 -1
- package/dist/web/assets/circle-D4vp8Yky.js +0 -1
- package/dist/web/assets/circle-question-mark-BGbDcz7E.js +0 -1
- package/dist/web/assets/clock-BBIE-uf3.js +0 -1
- package/dist/web/assets/code-CvgQViOi.js +0 -1
- package/dist/web/assets/code-editor-D-8oqMBM.js +0 -7
- package/dist/web/assets/codex-daily-guard-h4ZpEemV.js +0 -1
- package/dist/web/assets/conflict-editor-B0Mj8pYR.js +0 -19
- package/dist/web/assets/context-menu-I07Ld1Yr.js +0 -1
- package/dist/web/assets/copy-Bqr2VxN5.js +0 -1
- package/dist/web/assets/csv-preview-Ds2oCW6U.js +0 -2
- package/dist/web/assets/database-BHxcoKlT.js +0 -1
- package/dist/web/assets/database-viewer-CiwQ6spt.js +0 -1
- package/dist/web/assets/diff-viewer-BomFSnpH.js +0 -4
- package/dist/web/assets/docx-preview-PsyMM8SN.js +0 -12
- package/dist/web/assets/download-hiDsGuxx.js +0 -1
- package/dist/web/assets/explorer-body-CExMoOiW.js +0 -2
- package/dist/web/assets/explorer-window-content-Hy9kB6Q7.js +0 -1
- package/dist/web/assets/extension-manager-section-DMb56aut.js +0 -1
- package/dist/web/assets/extension-webview-CQB0Uvdo.js +0 -3
- package/dist/web/assets/eye-DYS5JBeU.js +0 -1
- package/dist/web/assets/eye-off-YWCuob9F.js +0 -1
- package/dist/web/assets/file-exclamation-point-DpdJqj9-.js +0 -1
- package/dist/web/assets/files-settings-section-CVHPO3N9.js +0 -1
- package/dist/web/assets/flask-conical-BUxpYe-g.js +0 -1
- package/dist/web/assets/folder-symlink-DKTEop0L.js +0 -1
- package/dist/web/assets/general-settings-section-CWYR9F5y.js +0 -1
- package/dist/web/assets/git-log-panel-DYLF-XSq.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-At-P8hlA.js +0 -1
- package/dist/web/assets/glide-data-grid-BxFN-Z6F.js +0 -141
- package/dist/web/assets/group-chat-tab-Ch6OGMKj.js +0 -1
- package/dist/web/assets/hand-BomFk_WG.js +0 -1
- package/dist/web/assets/image-preview-DjT5Xb2L.js +0 -1
- package/dist/web/assets/index-BfDJvjH9.js +0 -52
- package/dist/web/assets/index-Di9nVG3y.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-btSsuixb.js +0 -1
- package/dist/web/assets/key-round-BhkPzOjZ.js +0 -1
- package/dist/web/assets/keybindings-store-CNqxSJxv.js +0 -1
- package/dist/web/assets/keyboard-IQMXPNIE.js +0 -1
- package/dist/web/assets/keyboard-shortcuts-section-DAFNxA49.js +0 -1
- package/dist/web/assets/loader-circle-Bm-Dq_wA.js +0 -1
- package/dist/web/assets/markdown-renderer-BSiaxWjE.js +0 -1
- package/dist/web/assets/markdown-renderer-CMNnYOPG.js +0 -3
- package/dist/web/assets/mobile-explorer-sheet-BMg4Q9Bm.js +0 -1
- package/dist/web/assets/monitor-DEoVYSPl.js +0 -1
- package/dist/web/assets/notification-store-CRlOB9I9.js +0 -1
- package/dist/web/assets/notifications-settings-section-Cci_OOHx.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-B20_sIFd.js +0 -1
- package/dist/web/assets/panel-store-BcgZsiXU.js +0 -1
- package/dist/web/assets/pdf-preview-C28MEOND.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-nzfJdXCC.js +0 -1
- package/dist/web/assets/portal-container-context-DO44JpXO.js +0 -1
- package/dist/web/assets/power-BMdSjXYW.js +0 -1
- package/dist/web/assets/ppmbot-settings-section-Cef8FSS6.js +0 -1
- package/dist/web/assets/process-table-BfixzY3r.js +0 -1
- package/dist/web/assets/proxy-settings-section-BlLWfinY.js +0 -1
- package/dist/web/assets/query-audit-section-qnSL15x8.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-CS4sHKD5.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-CG6h4OL2.js +0 -2
- package/dist/web/assets/remote-desktop-mobile-view-D__2WLV5.js +0 -1
- package/dist/web/assets/remote-desktop-readiness-gate-rL48PCUH.js +0 -1
- package/dist/web/assets/remote-desktop-window-content-DlGUCbxq.js +0 -1
- package/dist/web/assets/save-CIuK3QI4.js +0 -1
- package/dist/web/assets/schedules-settings-section-BUqf3KTd.js +0 -1
- package/dist/web/assets/send-DQz3yIWM.js +0 -1
- package/dist/web/assets/separator-CE0YEyaB.js +0 -1
- package/dist/web/assets/settings-body-Baw2komX.js +0 -2
- package/dist/web/assets/settings-store-CuQlVCIe.js +0 -2
- package/dist/web/assets/settings-tab-DCW-3C38.js +0 -1
- package/dist/web/assets/settings-window-content-CVxOGqPV.js +0 -1
- package/dist/web/assets/shield-check-46EViZ6-.js +0 -1
- package/dist/web/assets/shield-off-Dx5mw3le.js +0 -1
- package/dist/web/assets/sparkles-Bay_CedB.js +0 -1
- package/dist/web/assets/sqlite-viewer-BWLSC3VJ.js +0 -1
- package/dist/web/assets/system-monitor-body-BqPyB0CY.js +0 -2
- package/dist/web/assets/system-monitor-tab-BXRvCThe.js +0 -1
- package/dist/web/assets/system-monitor-window-content-CvvwXkmW.js +0 -1
- package/dist/web/assets/tab-host-window-content-23IR3qzu.js +0 -1
- package/dist/web/assets/table-BbD_HNPU.js +0 -1
- package/dist/web/assets/team-member-sheet-BXJtrQAB.js +0 -2
- package/dist/web/assets/team-member-window-content-CBWnzwZ1.js +0 -1
- package/dist/web/assets/terminal-tab-uNw7Yvwg.js +0 -3
- package/dist/web/assets/text-wrap-97GXZlav.js +0 -1
- package/dist/web/assets/tool-cards-CjirOQfx.js +0 -9
- package/dist/web/assets/treemap-KZPCXAKY-BBrhTPZk.js +0 -1
- package/dist/web/assets/use-coarse-long-press-CynaAB7m.js +0 -1
- package/dist/web/assets/use-inline-blame-BLPCADZ8.js +0 -8
- package/dist/web/assets/use-monaco-theme-D2ETCHji.js +0 -1
- package/dist/web/assets/use-open-team-member-BlUqTp-l.js +0 -1
- package/dist/web/assets/use-remote-desktop-display-choice-B4O11KIj.js +0 -1
- package/dist/web/assets/vendor-markdown-3-bej77C.js +0 -291
- package/dist/web/assets/video-preview-BlD1DNP8.js +0 -1
- package/dist/web/assets/ws-auth-ZB8jvzhM.js +0 -1
- package/dist/web/assets/x-TEI-uJYo.js +0 -1
- package/dist/web/monacoeditorwork/css.worker.bundle.js +0 -54268
- package/dist/web/monacoeditorwork/editor.worker.bundle.js +0 -14316
- package/dist/web/monacoeditorwork/html.worker.bundle.js +0 -30452
- package/dist/web/monacoeditorwork/json.worker.bundle.js +0 -22095
- package/dist/web/monacoeditorwork/ts.worker.bundle.js +0 -225957
- package/src/web/components/explorer/file-icon-map.ts +0 -69
- /package/dist/web/assets/{abap-Dbc91hEB.js → abap-tkptwpsK.js} +0 -0
- /package/dist/web/assets/{actionscript-3-C14d4O5M.js → actionscript-3-Di9TMGwg.js} +0 -0
- /package/dist/web/assets/{ada-n8mPGtZF.js → ada-CB9F079D.js} +0 -0
- /package/dist/web/assets/{andromeeda-DAKL0TFq.js → andromeeda-Dcl8jpb7.js} +0 -0
- /package/dist/web/assets/{apache-BDCV8YqE.js → apache-D0Nk0qsH.js} +0 -0
- /package/dist/web/assets/{apex-BphlFNA_.js → apex-mQIoWncD.js} +0 -0
- /package/dist/web/assets/{applescript-F2pJar76.js → applescript-C6ljbcsI.js} +0 -0
- /package/dist/web/assets/{apply-theme-Abd1TNqE.js → apply-theme-BwIMNXyX.js} +0 -0
- /package/dist/web/assets/{ara-B32t5JRb.js → ara-WFqRPGPe.js} +0 -0
- /package/dist/web/assets/{asciidoc-DenFyKu-.js → asciidoc-bNd8w4nf.js} +0 -0
- /package/dist/web/assets/{asm-D5mJz41u.js → asm-BQ1_F580.js} +0 -0
- /package/dist/web/assets/{aurora-x-CUyAXiXM.js → aurora-x-Ciqs_Dbu.js} +0 -0
- /package/dist/web/assets/{awk-CUwaf-l-.js → awk-GCR-6KZV.js} +0 -0
- /package/dist/web/assets/{ayu-dark-Cgg8W7cK.js → ayu-dark-DxJXuj99.js} +0 -0
- /package/dist/web/assets/{ayu-light-B1c04Bhg.js → ayu-light-jvSyJWDV.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-CdWbuzp5.js → ayu-mirage-Cg3BPO6H.js} +0 -0
- /package/dist/web/assets/{ballerina-B2-GPRG0.js → ballerina-BPz4CrX6.js} +0 -0
- /package/dist/web/assets/{bat-Nss7Yr-0.js → bat-CSTs2hIG.js} +0 -0
- /package/dist/web/assets/{beancount-CgaWuvpQ.js → beancount-DMateAZX.js} +0 -0
- /package/dist/web/assets/{berry-DCFF4Zj1.js → berry-9lXg0GRM.js} +0 -0
- /package/dist/web/assets/{bibtex-BPNI-Gig.js → bibtex-DIbqmvFg.js} +0 -0
- /package/dist/web/assets/{bicep-qCj6DX1x.js → bicep-02WGsoJ8.js} +0 -0
- /package/dist/web/assets/{bird2-DYDjG-B_.js → bird2-BY0tbu3k.js} +0 -0
- /package/dist/web/assets/{c-CZV8SiOL.js → c-jMBX_9Je.js} +0 -0
- /package/dist/web/assets/{c3-BG7R2A4x.js → c3-B8JVbNjW.js} +0 -0
- /package/dist/web/assets/{cadence-BuiQVST4.js → cadence-DUIf1tvL.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-DU5MH6XF.js → can-open-in-ppm-DGEc0s4P.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-C-nwrEbb.js → catppuccin-frappe-FhUCVxex.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-nRLBO6vg.js → catppuccin-latte-CzfrtmgL.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-42eAAqCw.js → catppuccin-macchiato-6xL0lOtj.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-4lH0_4tX.js → catppuccin-mocha-D39-xS3P.js} +0 -0
- /package/dist/web/assets/{clarity-BCPLN5zJ.js → clarity-D8TeGvoT.js} +0 -0
- /package/dist/web/assets/{clojure-Btb509Z6.js → clojure-Dx_acSX7.js} +0 -0
- /package/dist/web/assets/{cmake-CGLZgJL3.js → cmake-CyeYPq8o.js} +0 -0
- /package/dist/web/assets/{codeowners-Dgqmdm5J.js → codeowners-DrTI0lmI.js} +0 -0
- /package/dist/web/assets/{codeql-DDUO6ZHS.js → codeql-CPkFxVW-.js} +0 -0
- /package/dist/web/assets/{common-lisp-DlhZ-mM8.js → common-lisp-B0k-3LTj.js} +0 -0
- /package/dist/web/assets/{coq-CVz-5qYC.js → coq-uygpo7to.js} +0 -0
- /package/dist/web/assets/{csharp-CXL6GcvM.js → csharp-DKUYGfSp.js} +0 -0
- /package/dist/web/assets/{css-CthwUm0E.js → css-DoOUp7v4.js} +0 -0
- /package/dist/web/assets/{csv-Bsal3rDr.js → csv-B3YE13gi.js} +0 -0
- /package/dist/web/assets/{csv-parser-iow1WWML.js → csv-parser-DXePqmXe.js} +0 -0
- /package/dist/web/assets/{cue-D2bSqa4C.js → cue-DViO2wvn.js} +0 -0
- /package/dist/web/assets/{cypher-u-EM8HmU.js → cypher-4BMCIW5N.js} +0 -0
- /package/dist/web/assets/{d-BFVkgfjO.js → d-BT_sTHas.js} +0 -0
- /package/dist/web/assets/{dark-plus-BXlM9uFB.js → dark-plus-DVVXu-1N.js} +0 -0
- /package/dist/web/assets/{dart-Hxx4mUdp.js → dart-DHz6f6_6.js} +0 -0
- /package/dist/web/assets/{dax-DQwsaFe_.js → dax-ChYCjweK.js} +0 -0
- /package/dist/web/assets/{desktop-CAHGHZLk.js → desktop-D6Lt4p04.js} +0 -0
- /package/dist/web/assets/{diff-CAbIXu6l.js → diff-D8TDe4hP.js} +0 -0
- /package/dist/web/assets/{dist-C_bG2Tku.js → dist-DOTlFQJA.js} +0 -0
- /package/dist/web/assets/{docker-51FhFKmM.js → docker-Bsp0YbPx.js} +0 -0
- /package/dist/web/assets/{dotenv-C4fc3fLK.js → dotenv-B_7giSY_.js} +0 -0
- /package/dist/web/assets/{dracula-CTtuacPO.js → dracula-TrQL2iB5.js} +0 -0
- /package/dist/web/assets/{dracula-soft-B-95hu1J.js → dracula-soft-n2XOlgh-.js} +0 -0
- /package/dist/web/assets/{dream-maker-Di3hAOzX.js → dream-maker-CdIEdhpT.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-C6btr6QV.js → emacs-lisp-CSbixs6u.js} +0 -0
- /package/dist/web/assets/{everforest-dark-CDQGzEiq.js → everforest-dark-BuZahZYp.js} +0 -0
- /package/dist/web/assets/{everforest-light-DRZC8v3w.js → everforest-light-DPH53z5H.js} +0 -0
- /package/dist/web/assets/{fennel-BZz92X8f.js → fennel-B1-K_hlJ.js} +0 -0
- /package/dist/web/assets/{fish-qpLXUfGf.js → fish-Cy12Dbua.js} +0 -0
- /package/dist/web/assets/{fluent-B3F6P-xc.js → fluent-B_82ys8E.js} +0 -0
- /package/dist/web/assets/{format-bytes-B9Dbme9a.js → format-bytes-D5sBgIqU.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-DjGQrmKa.js → fortran-free-form-BRQdNzZF.js} +0 -0
- /package/dist/web/assets/{gdscript-DToF1duE.js → gdscript-XBDmLUm9.js} +0 -0
- /package/dist/web/assets/{gdshader-FZCS76-j.js → gdshader-DhVfB3u4.js} +0 -0
- /package/dist/web/assets/{genie-CN3-FS9S.js → genie-X3K29Y49.js} +0 -0
- /package/dist/web/assets/{gherkin-DT66zHzt.js → gherkin-DKIx-6cX.js} +0 -0
- /package/dist/web/assets/{github-dark-5S2AJM2m.js → github-dark-Bf7zdp5s.js} +0 -0
- /package/dist/web/assets/{github-dark-default-DNEUWmc8.js → github-dark-default-DqsBBV11.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-BVgm_raB.js → github-dark-dimmed-X2gqRz6w.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-Dai8qNkr.js → github-dark-high-contrast-Z7tvbGX4.js} +0 -0
- /package/dist/web/assets/{github-light-C49nlhDa.js → github-light-BKxt-7zZ.js} +0 -0
- /package/dist/web/assets/{github-light-default-BLQcyxQl.js → github-light-default-B0liF4d4.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-BH3u_hMd.js → github-light-high-contrast-F4encJwr.js} +0 -0
- /package/dist/web/assets/{gleam-G2907CEQ.js → gleam-Pz2bHgBB.js} +0 -0
- /package/dist/web/assets/{gn-fxgN7J9Q.js → gn-CgmdNsPU.js} +0 -0
- /package/dist/web/assets/{gnuplot-a1TK_67n.js → gnuplot-qLNF5yZ9.js} +0 -0
- /package/dist/web/assets/{go-DLqnNJpz.js → go-CSDUNhE7.js} +0 -0
- /package/dist/web/assets/{groovy-D8U-plxc.js → groovy-B3NEnOHF.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DRYdA7rg.js → gruvbox-dark-hard-DcoftiUX.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-CJgayBQH.js → gruvbox-dark-medium-D1wVSuD8.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-spQNOlQ2.js → gruvbox-dark-soft-DWpunymH.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-FoElS0Wo.js → gruvbox-light-hard-rHMvyUdS.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-9E1Brisc.js → gruvbox-light-medium-3O2KiXO7.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-Coyp7RRB.js → gruvbox-light-soft-lNlXJPwH.js} +0 -0
- /package/dist/web/assets/{haskell-D1twJpgj.js → haskell-aaG3aC0h.js} +0 -0
- /package/dist/web/assets/{haxe-CppquubK.js → haxe-CPcHhUDd.js} +0 -0
- /package/dist/web/assets/{hcl-BWfTkyhR.js → hcl-CMQNlR_4.js} +0 -0
- /package/dist/web/assets/{hjson-fgd7F6t5.js → hjson-DeuklPFj.js} +0 -0
- /package/dist/web/assets/{hlsl-Ua1j-4aZ.js → hlsl-BI3hlsaM.js} +0 -0
- /package/dist/web/assets/{horizon-CTFgrxGb.js → horizon-C7-gOcjs.js} +0 -0
- /package/dist/web/assets/{horizon-bright-C4eTVZPB.js → horizon-bright-Cxt9bRW7.js} +0 -0
- /package/dist/web/assets/{houston-BeYbWPdk.js → houston-DbF2G7iD.js} +0 -0
- /package/dist/web/assets/{hy-BposFX9Q.js → hy-DRG6Hs2I.js} +0 -0
- /package/dist/web/assets/{image-gallery-COea0nSk.js → image-gallery-CObzTisL.js} +0 -0
- /package/dist/web/assets/{imba-D11-b73t.js → imba-CxKv_2TW.js} +0 -0
- /package/dist/web/assets/{ini-BCYCXf0w.js → ini-BiHsyCdO.js} +0 -0
- /package/dist/web/assets/{java-BqKIPPzY.js → java-D3RZzgDB.js} +0 -0
- /package/dist/web/assets/{javascript-CxvTx_wu.js → javascript-4FmSqG-T.js} +0 -0
- /package/dist/web/assets/{json-DiknJGdj.js → json-CjB236_E.js} +0 -0
- /package/dist/web/assets/{json5--8nFeehk.js → json5-bkfO-Rco.js} +0 -0
- /package/dist/web/assets/{jsonc-BFcq-Nx-.js → jsonc-BwaTeLyv.js} +0 -0
- /package/dist/web/assets/{jsonl-DKItgfTA.js → jsonl-CfxNSwGd.js} +0 -0
- /package/dist/web/assets/{jsonnet-sNz5wf7H.js → jsonnet-CQETCYrp.js} +0 -0
- /package/dist/web/assets/{jssm-BALAIF_E.js → jssm-D5o3Zzdz.js} +0 -0
- /package/dist/web/assets/{jsx-fXHHDCVl.js → jsx-BAMILPLo.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-nywk9qzg.js → kanagawa-dragon-BhGVxu3R.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-BmYPLC4f.js → kanagawa-lotus-FH4Y59ro.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-624mOWgc.js → kanagawa-wave-eilvP9MB.js} +0 -0
- /package/dist/web/assets/{kdl-DT8Argim.js → kdl-BQ-yvXUK.js} +0 -0
- /package/dist/web/assets/{kotlin-BvUjvPz2.js → kotlin-BuCx0-VT.js} +0 -0
- /package/dist/web/assets/{kusto-B0PONVdx.js → kusto-DAN_n_Cy.js} +0 -0
- /package/dist/web/assets/{laserwave-ByV7LuzT.js → laserwave-Cq2BlxrT.js} +0 -0
- /package/dist/web/assets/{lean-DQtq2qQC.js → lean-Dhq7uXKw.js} +0 -0
- /package/dist/web/assets/{less-DZeD4ccP.js → less-CxaMQb8j.js} +0 -0
- /package/dist/web/assets/{libesm-CcPYXCKp.js → libesm-DdtEjhIi.js} +0 -0
- /package/dist/web/assets/{light-plus-BCaKDxvd.js → light-plus-B4sMAend.js} +0 -0
- /package/dist/web/assets/{llvm-Dzok661y.js → llvm-DQ6-B_6Y.js} +0 -0
- /package/dist/web/assets/{log-C32HpwgI.js → log-Bb_vqvu7.js} +0 -0
- /package/dist/web/assets/{logo-Dtjk3XHO.js → logo-BzfYv3A_.js} +0 -0
- /package/dist/web/assets/{luau-BMbN7IqN.js → luau-BnAeNR77.js} +0 -0
- /package/dist/web/assets/{make-DIVSnx7D.js → make-B6IFuxpC.js} +0 -0
- /package/dist/web/assets/{markdown-B1JzcsJb.js → markdown-Z0xi77Fn.js} +0 -0
- /package/dist/web/assets/{material-theme-XMfEph9O.js → material-theme-1scy1SYn.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-CRGzh4Ox.js → material-theme-darker-G-JykXQP.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-D6esgP3h.js → material-theme-lighter-BtKkCMVq.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-CGbfRrFG.js → material-theme-ocean-irrDC89L.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-DFW4xdPI.js → material-theme-palenight-Eq5_K4LM.js} +0 -0
- /package/dist/web/assets/{matlab-Zpc8hvmI.js → matlab-BE3oCXZC.js} +0 -0
- /package/dist/web/assets/{mdx-DLlDpnjI.js → mdx-DYiuFTGw.js} +0 -0
- /package/dist/web/assets/{mermaid-q_sEDHYr.js → mermaid-DVlaEvtw.js} +0 -0
- /package/dist/web/assets/{min-dark-DUklXai3.js → min-dark-DSkeTpQa.js} +0 -0
- /package/dist/web/assets/{min-light-Ps7CV3R0.js → min-light-CFv2Q0uF.js} +0 -0
- /package/dist/web/assets/{mipsasm-anKs0TGD.js → mipsasm-CiAFuZQ2.js} +0 -0
- /package/dist/web/assets/{mojo-CWTvit9D.js → mojo-ARshcaSQ.js} +0 -0
- /package/dist/web/assets/{monokai-DOSMe3B9.js → monokai-CPTV-SOg.js} +0 -0
- /package/dist/web/assets/{moonbit-zOAryA05.js → moonbit-D57B0dZr.js} +0 -0
- /package/dist/web/assets/{move-CA6YZdSC.js → move-qgy3G_o9.js} +0 -0
- /package/dist/web/assets/{narrat-CyMxkfZJ.js → narrat-CZ3rC-oc.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-D5beSS3L.js → nextflow-groovy-BxxIOcI4.js} +0 -0
- /package/dist/web/assets/{night-owl-3ALu1K6e.js → night-owl-B1ryGCda.js} +0 -0
- /package/dist/web/assets/{night-owl-light-_NLbQQrl.js → night-owl-light-BZvNnvMF.js} +0 -0
- /package/dist/web/assets/{nix-C_KqthNc.js → nix-BVBQi8yv.js} +0 -0
- /package/dist/web/assets/{nord-VG8J_Wfy.js → nord-3NXw613h.js} +0 -0
- /package/dist/web/assets/{nushell-Dx7K7YNI.js → nushell-BMOLRalb.js} +0 -0
- /package/dist/web/assets/{objective-c-DrEbGERB.js → objective-c-AxruEUgh.js} +0 -0
- /package/dist/web/assets/{objective-cpp-DpiXqKhj.js → objective-cpp-cFT0qRsD.js} +0 -0
- /package/dist/web/assets/{ocaml-G6x51MAm.js → ocaml-_8JH6O8J.js} +0 -0
- /package/dist/web/assets/{odin-tK6CU-OU.js → odin-nwYvR0O6.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-581te-yF.js → one-dark-pro-C1LaYJaH.js} +0 -0
- /package/dist/web/assets/{one-light-DpYva-U1.js → one-light-B7rMc__c.js} +0 -0
- /package/dist/web/assets/{openscad-C7LYrrI4.js → openscad-Cwes8bKO.js} +0 -0
- /package/dist/web/assets/{pascal-ChqM3eJD.js → pascal-DMt-6tdZ.js} +0 -0
- /package/dist/web/assets/{pkl-BlIRJsyQ.js → pkl-QBTyYQmB.js} +0 -0
- /package/dist/web/assets/{plastic-DxceXlOD.js → plastic-BTSUp8Fk.js} +0 -0
- /package/dist/web/assets/{plsql-CVikvjWK.js → plsql-DQv3IFXP.js} +0 -0
- /package/dist/web/assets/{po-BN9bpeJD.js → po-CNwZx4tW.js} +0 -0
- /package/dist/web/assets/{poimandres-NeQA7ZSh.js → poimandres-8Os7Qequ.js} +0 -0
- /package/dist/web/assets/{polar-DtRx-uzO.js → polar-b4yK8oD8.js} +0 -0
- /package/dist/web/assets/{postcss-EDnOs84S.js → postcss-sFctwpxx.js} +0 -0
- /package/dist/web/assets/{powerquery-mc-bbl3v.js → powerquery-Cg_WrtuN.js} +0 -0
- /package/dist/web/assets/{powershell-ZqZF93a-.js → powershell-C7Ifz95h.js} +0 -0
- /package/dist/web/assets/{prisma-vhORN1Sx.js → prisma-Z52HUJzQ.js} +0 -0
- /package/dist/web/assets/{prolog-DfIbN_m8.js → prolog-DLqW-zR1.js} +0 -0
- /package/dist/web/assets/{proto-BHcnh-Db.js → proto-BOIzxCCJ.js} +0 -0
- /package/dist/web/assets/{puppet-oLpQOx2h.js → puppet-De7TjZIf.js} +0 -0
- /package/dist/web/assets/{purescript-HbM4Dt8M.js → purescript-R76ou1WT.js} +0 -0
- /package/dist/web/assets/{python-Dlxo2z6Q.js → python-Dprm0tNP.js} +0 -0
- /package/dist/web/assets/{qmldir-B5ox9idu.js → qmldir-Clp_jpNw.js} +0 -0
- /package/dist/web/assets/{qss-CyegwBrl.js → qss-eQPYYzSo.js} +0 -0
- /package/dist/web/assets/{r-CxE2X3lg.js → r-CCcRHIf5.js} +0 -0
- /package/dist/web/assets/{racket-CpguQMOj.js → racket-CzE472yp.js} +0 -0
- /package/dist/web/assets/{raku-DDf8ASYE.js → raku-DQwXrTSi.js} +0 -0
- /package/dist/web/assets/{red-C634f6x3.js → red-KCS6wyop.js} +0 -0
- /package/dist/web/assets/{reg-4gnm7BOP.js → reg-CcrAddUh.js} +0 -0
- /package/dist/web/assets/{regexp-Cs-hPAru.js → regexp-DDbud-Ri.js} +0 -0
- /package/dist/web/assets/{rel-CrGcWbwM.js → rel-99GDgaHp.js} +0 -0
- /package/dist/web/assets/{resolve-theme-Dm8ehbOv.js → resolve-theme-CW2niGV2.js} +0 -0
- /package/dist/web/assets/{riscv-B2P26ROS.js → riscv-Dm2eNv0R.js} +0 -0
- /package/dist/web/assets/{ron-DDHGmvxW.js → ron-CzFt0ygH.js} +0 -0
- /package/dist/web/assets/{rose-pine-CUYRoYal.js → rose-pine-Ck6lCrCP.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-C9JfuUh8.js → rose-pine-dawn-vtALRJNj.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-CrYHzRJm.js → rose-pine-moon-DPto8qXw.js} +0 -0
- /package/dist/web/assets/{rosmsg-iqzz1U38.js → rosmsg-NtS6429H.js} +0 -0
- /package/dist/web/assets/{rust-DVeWF3Is.js → rust-BjIXvF9h.js} +0 -0
- /package/dist/web/assets/{sass-CbVwBbUd.js → sass-CQ23wf5E.js} +0 -0
- /package/dist/web/assets/{scala-gZhcvPGv.js → scala-LfKLM143.js} +0 -0
- /package/dist/web/assets/{scheme-Z-DWgvmB.js → scheme-D3SLBXlF.js} +0 -0
- /package/dist/web/assets/{sdbl-wn_BtpSz.js → sdbl-ODRd2rGN.js} +0 -0
- /package/dist/web/assets/{shellscript-C09f889h.js → shellscript-3KB1G_oA.js} +0 -0
- /package/dist/web/assets/{slack-dark-D63Fbr3l.js → slack-dark-DTtyWmIy.js} +0 -0
- /package/dist/web/assets/{slack-ochin--Yu-v0r6.js → slack-ochin-Bu0PApk3.js} +0 -0
- /package/dist/web/assets/{smalltalk-LQDcL_tW.js → smalltalk-haMT-Sbe.js} +0 -0
- /package/dist/web/assets/{snazzy-light-bo9fX83t.js → snazzy-light-DXJzefE9.js} +0 -0
- /package/dist/web/assets/{solarized-dark-zSs85XH6.js → solarized-dark-B6LyYa18.js} +0 -0
- /package/dist/web/assets/{solarized-light-B6Q4CXBt.js → solarized-light-QLADebkv.js} +0 -0
- /package/dist/web/assets/{solidity-uUJPOjGx.js → solidity-mzfq1aDc.js} +0 -0
- /package/dist/web/assets/{splunk-C6oWgmrC.js → splunk-CyH4RWBp.js} +0 -0
- /package/dist/web/assets/{sql-DyUvXbLi.js → sql-CWVlT5D3.js} +0 -0
- /package/dist/web/assets/{ssh-config-62Vrd_7v.js → ssh-config-DNvQJ1Qx.js} +0 -0
- /package/dist/web/assets/{stylus-CmLQe7Fq.js → stylus-ByQQdtmf.js} +0 -0
- /package/dist/web/assets/{swift-DJwuT1eZ.js → swift-D1cpY4ow.js} +0 -0
- /package/dist/web/assets/{synthwave-84-CEeyTLD7.js → synthwave-84-BDF_-QiW.js} +0 -0
- /package/dist/web/assets/{system-verilog-DMqtAclw.js → system-verilog-BYrkMydC.js} +0 -0
- /package/dist/web/assets/{systemd-XnScP_8M.js → systemd-CQm3zyK0.js} +0 -0
- /package/dist/web/assets/{talonscript-CDoODzml.js → talonscript-DMW5CzE1.js} +0 -0
- /package/dist/web/assets/{tasl-DycI0-Tf.js → tasl-BhFzMCr2.js} +0 -0
- /package/dist/web/assets/{tcl-Dt8iP0sw.js → tcl-D7VEAF-9.js} +0 -0
- /package/dist/web/assets/{terraform-DXzABgqQ.js → terraform-DdT5A0Vy.js} +0 -0
- /package/dist/web/assets/{tokyo-night-DHB1Yc-3.js → tokyo-night-WGLMM6Q9.js} +0 -0
- /package/dist/web/assets/{toml-BkejsZF3.js → toml-CZ7ipXHZ.js} +0 -0
- /package/dist/web/assets/{tsv-ClmhsiiR.js → tsv-B1zVvoTr.js} +0 -0
- /package/dist/web/assets/{tsx-Cp-c_JHF.js → tsx-D4HwRUBq.js} +0 -0
- /package/dist/web/assets/{turtle-BbwC417u.js → turtle-B4r8KEJH.js} +0 -0
- /package/dist/web/assets/{typescript-DbwnrRKJ.js → typescript-BnHhxMtp.js} +0 -0
- /package/dist/web/assets/{typespec-DLL0LoZj.js → typespec-DP2q46GT.js} +0 -0
- /package/dist/web/assets/{typst-BmEouVT1.js → typst-DFsD_yaD.js} +0 -0
- /package/dist/web/assets/{utils-CwNUra6_.js → utils-Bmf_8h7Y.js} +0 -0
- /package/dist/web/assets/{v-C5rFgF81.js → v-Bji8hSVT.js} +0 -0
- /package/dist/web/assets/{vala-rBXMujLw.js → vala-D3TIgGmU.js} +0 -0
- /package/dist/web/assets/{vb-mxG_YZv2.js → vb-DvcxFS2q.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-BtjgHRUe.js → vendor-xterm-BqPDsE9b.js} +0 -0
- /package/dist/web/assets/{verilog-uQ-oJRKp.js → verilog-Dy7cF35d.js} +0 -0
- /package/dist/web/assets/{vesper-SO5Hw_2X.js → vesper-BzjwUv9J.js} +0 -0
- /package/dist/web/assets/{vhdl-8IeO85hx.js → vhdl-DuFnFNmW.js} +0 -0
- /package/dist/web/assets/{viml-De-Hm57y.js → viml-yAPgKlbz.js} +0 -0
- /package/dist/web/assets/{vitesse-black-BVm23GJE.js → vitesse-black-oSSQdyIZ.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-CR0XeT-h.js → vitesse-dark-BZxwPihB.js} +0 -0
- /package/dist/web/assets/{vitesse-light-CXIFICUA.js → vitesse-light-uIigycvt.js} +0 -0
- /package/dist/web/assets/{vyper-dUuvAUFJ.js → vyper-CX3NAxm5.js} +0 -0
- /package/dist/web/assets/{wasm-DbLMmiW0.js → wasm-6mEOOvVa.js} +0 -0
- /package/dist/web/assets/{wasm-D5Vd7qV1.js → wasm-D9td37qO.js} +0 -0
- /package/dist/web/assets/{wenyan-BafBYCBu.js → wenyan-lwNIHgk6.js} +0 -0
- /package/dist/web/assets/{wgsl-DY5sHamz.js → wgsl-DQAzCfog.js} +0 -0
- /package/dist/web/assets/{wikitext-QkQQVra5.js → wikitext-DTXmt5NE.js} +0 -0
- /package/dist/web/assets/{wit-BZjaDTy9.js → wit-Bdw_7WDH.js} +0 -0
- /package/dist/web/assets/{wolfram-vrjPFD7R.js → wolfram-DqyHDZ07.js} +0 -0
- /package/dist/web/assets/{yaml-D1as76NB.js → yaml-CPXhdByd.js} +0 -0
- /package/dist/web/assets/{zenscript-D31myxQh.js → zenscript-6s_i5zek.js} +0 -0
- /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 "
|
|
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"
|
|
@@ -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
|
-
|
|
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
|
|
20
|
-
import {
|
|
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:
|
|
140
|
+
const query = new URLSearchParams({ path: repoFile });
|
|
94
141
|
if (rev) query.set("rev", rev);
|
|
95
142
|
api
|
|
96
|
-
.get<BlameResult>(
|
|
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
|
-
|
|
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
|
|
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
|
|
131
|
-
|
|
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
|
+
}
|