@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
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place `THIRD-PARTY-NOTICES.md` is written, and the reason it is not
|
|
3
|
+
* written by hand.
|
|
4
|
+
*
|
|
5
|
+
* PPM ships other people's artwork: 14 subset `.woff2` faces cut from Nerd
|
|
6
|
+
* Fonts, the vscode-icons drawings inlined as data URIs in a stylesheet, and
|
|
7
|
+
* the Fluent System Icons path data compiled into a module. All three arrive
|
|
8
|
+
* through a generator, none of them is recognisable as a third-party asset
|
|
9
|
+
* once it has, and `package.json` has no `files` field — so everything in the
|
|
10
|
+
* tree is in the tarball whether or not anybody remembered to say where it
|
|
11
|
+
* came from. A notice written by hand goes stale the first time a generator's
|
|
12
|
+
* source list is edited; one emitted by the generator cannot.
|
|
13
|
+
*
|
|
14
|
+
* Each generator owns its own section and rewrites only that section, because
|
|
15
|
+
* they run independently: `bun scripts/gen-file-icons.ts` on its own must not
|
|
16
|
+
* blank the font's notice. That is what the BEGIN/END markers are for.
|
|
17
|
+
*/
|
|
18
|
+
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
19
|
+
import { resolve } from "node:path";
|
|
20
|
+
|
|
21
|
+
export interface Notice {
|
|
22
|
+
/** The component, named the way its own project names it. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Where it came from, as a URL somebody can check. */
|
|
25
|
+
upstream: string;
|
|
26
|
+
/**
|
|
27
|
+
* An SPDX identifier where one exists, spelled out where it does not.
|
|
28
|
+
*
|
|
29
|
+
* Nerd Fonts' own source table records Font Logos as "unlicensed"; upstream
|
|
30
|
+
* it carries a verbatim copy of The Unlicense, which is a dedication to the
|
|
31
|
+
* public domain rather than an absence of terms. GitHub's licence API
|
|
32
|
+
* reports `Unlicense` for that repository, and the two readings are exact
|
|
33
|
+
* opposites, so this column follows the licence text rather than the table.
|
|
34
|
+
*/
|
|
35
|
+
license: string;
|
|
36
|
+
/** The version vendored, where the source pins one. */
|
|
37
|
+
version?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The upstream copyright line, without the sign.
|
|
40
|
+
*
|
|
41
|
+
* A column rather than prose because MIT, Apache-2.0 and the OFL all require
|
|
42
|
+
* the notice to travel with the work, and a table is the only shape that
|
|
43
|
+
* makes a missing one visible.
|
|
44
|
+
*/
|
|
45
|
+
holder: string;
|
|
46
|
+
/** Anything a reader needs that the three columns cannot carry. */
|
|
47
|
+
note?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const FILE = resolve(import.meta.dir, "../THIRD-PARTY-NOTICES.md");
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The order the file lists sections in, so that the result does not depend on
|
|
54
|
+
* which generator happened to run last.
|
|
55
|
+
*/
|
|
56
|
+
const SECTIONS = ["product-icons", "file-icons", "nerd-font"] as const;
|
|
57
|
+
export type SectionId = (typeof SECTIONS)[number];
|
|
58
|
+
|
|
59
|
+
const HEADER = `# Third-party notices
|
|
60
|
+
|
|
61
|
+
PPM itself is licensed under the Elastic License 2.0 (see \`LICENSE\`). It also
|
|
62
|
+
redistributes the components below, each under its own terms, which continue to
|
|
63
|
+
apply to those components.
|
|
64
|
+
|
|
65
|
+
Every section here is emitted by the generator that vendors the component —
|
|
66
|
+
edit that generator, not this file. Re-run:
|
|
67
|
+
|
|
68
|
+
\`\`\`
|
|
69
|
+
bun scripts/gen-product-icons.ts
|
|
70
|
+
bun scripts/gen-file-icons.ts
|
|
71
|
+
bun scripts/gen-nerd-font.ts
|
|
72
|
+
\`\`\`
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
function begin(id: SectionId): string {
|
|
76
|
+
return `<!-- BEGIN ${id} -->`;
|
|
77
|
+
}
|
|
78
|
+
function end(id: SectionId): string {
|
|
79
|
+
return `<!-- END ${id} -->`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** `github.com/owner/repo` reads better in a table cell than the whole URL. */
|
|
83
|
+
function short(url: string): string {
|
|
84
|
+
const u = new URL(url);
|
|
85
|
+
return `${u.host}${u.pathname.replace(/\/$/, "")}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function renderTable(notices: readonly Notice[]): string {
|
|
89
|
+
const rows = notices.map(
|
|
90
|
+
(n) =>
|
|
91
|
+
`| ${n.name} | [${short(n.upstream)}](${n.upstream}) | ${n.version ?? "—"} | ${licenseCell(n.license)} | \u00a9 ${n.holder} |`,
|
|
92
|
+
);
|
|
93
|
+
const notes = notices.filter((n) => n.note).map((n) => `- **${n.name}** — ${n.note}`);
|
|
94
|
+
return [
|
|
95
|
+
"| Component | Upstream | Version | Licence | Copyright |",
|
|
96
|
+
"| --- | --- | --- | --- | --- |",
|
|
97
|
+
...rows,
|
|
98
|
+
...(notes.length > 0 ? ["", ...notes] : []),
|
|
99
|
+
].join("\n");
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Every SPDX id in the column links to the text committed under `licenses/`.
|
|
104
|
+
*
|
|
105
|
+
* A link to spdx.org would not do: MIT, Apache-2.0 and the OFL each require the
|
|
106
|
+
* licence itself to be distributed with the work, so the copy has to be in the
|
|
107
|
+
* tarball. The cell may name two (Font Awesome licenses its icons and its fonts
|
|
108
|
+
* differently), so this rewrites ids wherever they appear rather than treating
|
|
109
|
+
* the whole cell as one.
|
|
110
|
+
*/
|
|
111
|
+
function licenseCell(license: string): string {
|
|
112
|
+
return license.replace(/[A-Za-z0-9.-]+/g, (word) =>
|
|
113
|
+
VENDORED.has(word) ? `[${word}](licenses/${word}.txt)` : word,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** The texts committed under `licenses/`. */
|
|
118
|
+
const VENDORED = new Set(["MIT", "Apache-2.0", "OFL-1.1", "CC-BY-4.0", "Unlicense"]);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Replace one section of the notices file, leaving the others as they are.
|
|
122
|
+
*
|
|
123
|
+
* `intro` is prose the generator wants above its table — what was vendored and
|
|
124
|
+
* in what form, which is the part a licence column cannot say.
|
|
125
|
+
*/
|
|
126
|
+
export function writeNotices(
|
|
127
|
+
id: SectionId,
|
|
128
|
+
heading: string,
|
|
129
|
+
intro: string,
|
|
130
|
+
notices: readonly Notice[],
|
|
131
|
+
): void {
|
|
132
|
+
const body = [
|
|
133
|
+
begin(id),
|
|
134
|
+
"",
|
|
135
|
+
`## ${heading}`,
|
|
136
|
+
"",
|
|
137
|
+
intro.trim(),
|
|
138
|
+
"",
|
|
139
|
+
renderTable(notices),
|
|
140
|
+
"",
|
|
141
|
+
end(id),
|
|
142
|
+
].join("\n");
|
|
143
|
+
|
|
144
|
+
const existing = existsSync(FILE) ? readFileSync(FILE, "utf-8") : "";
|
|
145
|
+
const sections = new Map<SectionId, string>();
|
|
146
|
+
for (const other of SECTIONS) {
|
|
147
|
+
if (other === id) continue;
|
|
148
|
+
const from = existing.indexOf(begin(other));
|
|
149
|
+
const to = existing.indexOf(end(other));
|
|
150
|
+
if (from !== -1 && to > from) sections.set(other, existing.slice(from, to + end(other).length));
|
|
151
|
+
}
|
|
152
|
+
sections.set(id, body);
|
|
153
|
+
|
|
154
|
+
const out =
|
|
155
|
+
[HEADER.trim(), ...SECTIONS.filter((s) => sections.has(s)).map((s) => sections.get(s)!)].join(
|
|
156
|
+
"\n\n",
|
|
157
|
+
) + "\n";
|
|
158
|
+
writeFileSync(FILE, out);
|
|
159
|
+
console.log(`notices ${id}: ${notices.length} component${notices.length === 1 ? "" : "s"}`);
|
|
160
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monaco under `bun dev:web`.
|
|
3
|
+
*
|
|
4
|
+
* `monaco-adapter.ts` points the AMD loader at `/assets/monaco/vs`, and that path only exists
|
|
5
|
+
* after `bun run build` — `copy-monaco.ts` stages it into `dist/web`. In dev the request fell
|
|
6
|
+
* through to the SPA fallback, which answers `loader.js` with `index.html` as `text/html`; the
|
|
7
|
+
* browser's strict MIME check turns that into a SyntaxError, and every editor and diff tab then
|
|
8
|
+
* spins forever. It reads as a hung component rather than as a missing asset, which is what made
|
|
9
|
+
* it worth a plugin rather than a note in the README — and the jsdelivr default this replaced
|
|
10
|
+
* did work in dev, so it is a regression rather than a gap.
|
|
11
|
+
*
|
|
12
|
+
* The files come straight out of `node_modules` through the same exclusion list the build uses,
|
|
13
|
+
* so dev cannot succeed on a file production does not ship.
|
|
14
|
+
*/
|
|
15
|
+
import { createReadStream, statSync } from "node:fs";
|
|
16
|
+
import { extname, resolve, sep } from "node:path";
|
|
17
|
+
import type { Plugin } from "vite";
|
|
18
|
+
import { MONACO_VS, isUnused } from "./monaco-staging.ts";
|
|
19
|
+
|
|
20
|
+
/** Every file in the AMD build is one of these two; anything an upgrade adds is sent as bytes. */
|
|
21
|
+
const CONTENT_TYPES: Record<string, string> = {
|
|
22
|
+
".js": "text/javascript; charset=utf-8",
|
|
23
|
+
".css": "text/css; charset=utf-8",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The file `pathname` asks for, relative to Monaco's `vs` directory, or null when there is
|
|
28
|
+
* nothing to serve — which leaves the request to Vite and its SPA fallback, exactly as before.
|
|
29
|
+
*
|
|
30
|
+
* Exported for its own test: the traversal guard is the kind of thing that is easy to write and
|
|
31
|
+
* impossible to notice the absence of, and this runs on a dev server that listens on the LAN
|
|
32
|
+
* (`server.host: true`).
|
|
33
|
+
*/
|
|
34
|
+
export function monacoDevAsset(pathname: string, root = MONACO_VS): { file: string; contentType: string } | null {
|
|
35
|
+
let decoded: string;
|
|
36
|
+
try {
|
|
37
|
+
decoded = decodeURIComponent(pathname.split("?")[0] ?? "");
|
|
38
|
+
} catch {
|
|
39
|
+
return null; // a malformed escape is not a path
|
|
40
|
+
}
|
|
41
|
+
if (decoded.includes("\0")) return null;
|
|
42
|
+
const file = resolve(root, `.${decoded.startsWith("/") ? decoded : `/${decoded}`}`);
|
|
43
|
+
if (!file.startsWith(root + sep)) return null;
|
|
44
|
+
if (isUnused(file)) return null;
|
|
45
|
+
if (!statSync(file, { throwIfNoEntry: false })?.isFile()) return null;
|
|
46
|
+
return { file, contentType: CONTENT_TYPES[extname(file)] ?? "application/octet-stream" };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function monacoDevAssets(): Plugin {
|
|
50
|
+
return {
|
|
51
|
+
name: "ppm-monaco-dev-assets",
|
|
52
|
+
apply: "serve",
|
|
53
|
+
configureServer(server) {
|
|
54
|
+
// Connect strips the mounted prefix, so `req.url` here is the path inside `vs/`.
|
|
55
|
+
server.middlewares.use("/assets/monaco/vs", (req, res, next) => {
|
|
56
|
+
const asset = monacoDevAsset(req.url ?? "/");
|
|
57
|
+
if (!asset) return next();
|
|
58
|
+
res.setHeader("Content-Type", asset.contentType);
|
|
59
|
+
createReadStream(asset.file).on("error", next).pipe(res);
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -564,9 +564,18 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
564
564
|
|
|
565
565
|
async listSessionsByDir(dir?: string, opts?: { limit?: number; offset?: number }): Promise<SessionInfo[]> {
|
|
566
566
|
try {
|
|
567
|
-
const limit = opts?.limit ?? 50;
|
|
568
567
|
const offset = opts?.offset ?? 0;
|
|
569
|
-
|
|
568
|
+
// A dir-scoped call with no explicit limit means "every session in this
|
|
569
|
+
// project" — chat search and the search-index backfill both ask that way.
|
|
570
|
+
// It has to be answered by paging the SDK, not by taking its first page:
|
|
571
|
+
// everything past that page fell through to the recovery scan below,
|
|
572
|
+
// which can only reconstruct a title from the transcript's first 512
|
|
573
|
+
// bytes. So 165 of 228 sessions here were listed under their opening
|
|
574
|
+
// prompt ("/recap") instead of the name they had been given, and no
|
|
575
|
+
// search for that name could match them.
|
|
576
|
+
const sdkSessions = dir !== undefined && opts?.limit === undefined
|
|
577
|
+
? await listAllSdkSessions(dir)
|
|
578
|
+
: await sdkListSessions({ dir, limit: opts?.limit ?? 50, offset });
|
|
570
579
|
// Overlay DB titles (user-set) over SDK titles
|
|
571
580
|
const ids = sdkSessions.map((s) => s.sessionId);
|
|
572
581
|
const dbTitles = getSessionTitles(ids);
|
|
@@ -2167,6 +2176,27 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
2167
2176
|
}
|
|
2168
2177
|
}
|
|
2169
2178
|
|
|
2179
|
+
const SDK_SESSION_PAGE = 200;
|
|
2180
|
+
/** Hard stop so a pathological directory cannot spin here. */
|
|
2181
|
+
const SDK_SESSION_MAX_PAGES = 100;
|
|
2182
|
+
|
|
2183
|
+
/** Every session the SDK can parse in `dir`, paged until exhausted. */
|
|
2184
|
+
async function listAllSdkSessions(
|
|
2185
|
+
dir: string,
|
|
2186
|
+
): Promise<Awaited<ReturnType<typeof sdkListSessions>>> {
|
|
2187
|
+
const all: Awaited<ReturnType<typeof sdkListSessions>> = [];
|
|
2188
|
+
for (let page = 0; page < SDK_SESSION_MAX_PAGES; page++) {
|
|
2189
|
+
const batch = await sdkListSessions({
|
|
2190
|
+
dir,
|
|
2191
|
+
limit: SDK_SESSION_PAGE,
|
|
2192
|
+
offset: page * SDK_SESSION_PAGE,
|
|
2193
|
+
});
|
|
2194
|
+
all.push(...batch);
|
|
2195
|
+
if (batch.length < SDK_SESSION_PAGE) break;
|
|
2196
|
+
}
|
|
2197
|
+
return all;
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2170
2200
|
/**
|
|
2171
2201
|
* Scan a JSONL project directory for sessions that the SDK's listSessions missed.
|
|
2172
2202
|
* The SDK uses a 64KB head buffer; sessions with very large first messages
|
package/src/server/index.ts
CHANGED
|
@@ -31,6 +31,8 @@ import { extensionWebSocket } from "./ws/extensions.ts";
|
|
|
31
31
|
import { globalWebSocket } from "./ws/global.ts";
|
|
32
32
|
import { groupChatWebSocket } from "./ws/group-chat.ts";
|
|
33
33
|
import { remoteDesktopWebSocket } from "./ws/remote-desktop.ts";
|
|
34
|
+
import { lspWebSocket } from "./ws/lsp.ts";
|
|
35
|
+
import { lspManager } from "../services/lsp/lsp-manager.ts";
|
|
34
36
|
import { isRemoteDesktopEnabled } from "../services/remote-desktop/remote-desktop-flag.ts";
|
|
35
37
|
import { ok, err } from "../types/api.ts";
|
|
36
38
|
|
|
@@ -912,6 +914,14 @@ if (process.argv.includes("__serve__")) {
|
|
|
912
914
|
if (upgraded) return undefined;
|
|
913
915
|
return new Response("WebSocket upgrade failed", { status: 400 });
|
|
914
916
|
}
|
|
917
|
+
|
|
918
|
+
if (wsType === "lsp") {
|
|
919
|
+
const upgraded = server.upgrade(req, {
|
|
920
|
+
data: { type: "lsp", projectName },
|
|
921
|
+
});
|
|
922
|
+
if (upgraded) return undefined;
|
|
923
|
+
return new Response("WebSocket upgrade failed", { status: 400 });
|
|
924
|
+
}
|
|
915
925
|
}
|
|
916
926
|
|
|
917
927
|
return app.fetch(req, server);
|
|
@@ -928,6 +938,7 @@ if (process.argv.includes("__serve__")) {
|
|
|
928
938
|
else if (t === "global") globalWebSocket.open(ws);
|
|
929
939
|
else if (t === "remote-desktop") remoteDesktopWebSocket.open(ws);
|
|
930
940
|
else if (t === "terminal") terminalWebSocket.open(ws);
|
|
941
|
+
else if (t === "lsp") lspWebSocket.open(ws);
|
|
931
942
|
else ws.close(1008, "unknown socket type");
|
|
932
943
|
},
|
|
933
944
|
message(ws: any, msg: any) {
|
|
@@ -938,6 +949,7 @@ if (process.argv.includes("__serve__")) {
|
|
|
938
949
|
else if (t === "global") globalWebSocket.message(ws, msg);
|
|
939
950
|
else if (t === "remote-desktop") remoteDesktopWebSocket.message(ws, msg);
|
|
940
951
|
else if (t === "terminal") terminalWebSocket.message(ws, msg);
|
|
952
|
+
else if (t === "lsp") lspWebSocket.message(ws, msg);
|
|
941
953
|
},
|
|
942
954
|
close(ws: any) {
|
|
943
955
|
const t = ws.data?.type;
|
|
@@ -947,6 +959,7 @@ if (process.argv.includes("__serve__")) {
|
|
|
947
959
|
else if (t === "global") globalWebSocket.close(ws);
|
|
948
960
|
else if (t === "remote-desktop") remoteDesktopWebSocket.close(ws);
|
|
949
961
|
else if (t === "terminal") terminalWebSocket.close(ws);
|
|
962
|
+
else if (t === "lsp") lspWebSocket.close(ws);
|
|
950
963
|
},
|
|
951
964
|
} as Parameters<typeof Bun.serve>[0] extends { websocket?: infer W } ? W : never,
|
|
952
965
|
});
|
|
@@ -997,6 +1010,10 @@ if (process.argv.includes("__serve__")) {
|
|
|
997
1010
|
const gracefulShutdown = () => {
|
|
998
1011
|
try { schedulerStop?.(); } catch {}
|
|
999
1012
|
try { codexCleanupRef?.(); } catch {}
|
|
1013
|
+
// Language servers are long-lived children; most exit on stdin EOF, but a
|
|
1014
|
+
// resident rust-analyzer holding a crate graph is too expensive to leave
|
|
1015
|
+
// to chance. Synchronous because process.exit follows immediately.
|
|
1016
|
+
try { lspManager.killAllSync(); } catch {}
|
|
1000
1017
|
try { server.stop(true); } catch {}
|
|
1001
1018
|
process.exit(0);
|
|
1002
1019
|
};
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
search as chatSearchQuery,
|
|
29
29
|
startBackfill as chatSearchStartBackfill,
|
|
30
30
|
getIndexStatus as chatSearchGetIndexStatus,
|
|
31
|
+
getKnownSessionCount as chatSearchKnownCount,
|
|
31
32
|
} from "../../services/chat-search.service.ts";
|
|
32
33
|
import type { ChatSearchResult, ChatSearchResponse } from "../../types/chat.ts";
|
|
33
34
|
import { ok, err } from "../../types/api.ts";
|
|
@@ -250,15 +251,24 @@ chatRoutes.get("/search", async (c) => {
|
|
|
250
251
|
const rawQuery = c.req.query("q")?.trim() || "";
|
|
251
252
|
const limit = Math.min(parseInt(c.req.query("limit") ?? "30", 10) || 30, 100);
|
|
252
253
|
|
|
254
|
+
// An empty query has nothing to match, so it must not pay to enumerate: a
|
|
255
|
+
// dir-scoped `listSessions` pages the SDK until exhausted, and all this
|
|
256
|
+
// answer carries is the indexing chip's two numbers, which the index knows
|
|
257
|
+
// by itself.
|
|
258
|
+
if (!rawQuery) {
|
|
259
|
+
const indexing = { total: chatSearchKnownCount(projectPath), ...chatSearchGetIndexStatus(projectPath) };
|
|
260
|
+
return c.json(ok({ results: [], indexing } satisfies ChatSearchResponse));
|
|
261
|
+
}
|
|
262
|
+
|
|
253
263
|
// Enumerate sessions once (also drives title matches + metadata for content hits).
|
|
254
264
|
const sessions = await chatService.listSessions(undefined, projectPath);
|
|
255
|
-
const
|
|
256
|
-
const indexing = { total, ...chatSearchGetIndexStatus(projectPath) };
|
|
257
|
-
|
|
258
|
-
if (!rawQuery) return c.json(ok({ results: [], indexing } satisfies ChatSearchResponse));
|
|
265
|
+
const indexing = { total: sessions.length, ...chatSearchGetIndexStatus(projectPath) };
|
|
259
266
|
|
|
260
|
-
// Lazy self-refresh; UI shows an indexing indicator while this runs.
|
|
261
|
-
|
|
267
|
+
// Lazy self-refresh; UI shows an indexing indicator while this runs. The
|
|
268
|
+
// sessions are handed over rather than enumerated again: a dir-scoped list
|
|
269
|
+
// with no limit pages the SDK until exhausted, and this route was paying
|
|
270
|
+
// for that twice on every search.
|
|
271
|
+
chatSearchStartBackfill(projectPath, sessions);
|
|
262
272
|
|
|
263
273
|
const pinnedIds = getPinnedSessionIds();
|
|
264
274
|
const tagMap = getSessionTags(sessions.map((s) => s.id));
|
package/src/server/routes/git.ts
CHANGED
|
@@ -1,13 +1,92 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
+
import { resolve } from "node:path";
|
|
2
3
|
import { gitService } from "../../services/git.service.ts";
|
|
3
4
|
import { gitHunksService, type HunkRequest, type HunkScope } from "../../services/git-hunks/git-hunks.service.ts";
|
|
4
|
-
import { gitBlameService } from "../../services/git-blame/git-blame.service.ts";
|
|
5
|
+
import { assertSafeRev, gitBlameService } from "../../services/git-blame/git-blame.service.ts";
|
|
6
|
+
import { discoverGitRepos, isGitRepo } from "../../services/git-repos/git-repo-discovery.ts";
|
|
7
|
+
import { isInsideDir, realPathOrSelfSync } from "../../services/fs-ops/fs-real-path.ts";
|
|
5
8
|
import { ok, err } from "../../types/api.ts";
|
|
6
9
|
|
|
7
10
|
type Env = { Variables: { projectPath: string; projectName: string } };
|
|
8
11
|
|
|
9
12
|
export const gitRoutes = new Hono<Env>();
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* `?repo=` scopes every git route below to one repository inside the project.
|
|
16
|
+
*
|
|
17
|
+
* A workspace folder is often a container whose *children* are the
|
|
18
|
+
* repositories, so the project path and the git root are not the same
|
|
19
|
+
* directory. Rather than teach each of the twenty-odd handlers, the parameter
|
|
20
|
+
* is resolved once here and `projectPath` is replaced — every handler already
|
|
21
|
+
* reads that, and `git.service` already takes the directory to run in.
|
|
22
|
+
*
|
|
23
|
+
* It is validated, and a bad value is a 400 rather than a fallback to the
|
|
24
|
+
* project root. Falling back would run the command one directory up and answer
|
|
25
|
+
* with *a* history — the wrong one — which is indistinguishable from a working
|
|
26
|
+
* feature until someone acts on it.
|
|
27
|
+
*
|
|
28
|
+
* Both sides go through `realPathOrSelfSync` first. `resolve` is purely
|
|
29
|
+
* textual, so a symlink inside the project pointing anywhere on the host
|
|
30
|
+
* resolves to an in-project path, passes, and git runs in the link's target.
|
|
31
|
+
* Discovery refuses to *offer* such a path, but this parameter comes straight
|
|
32
|
+
* from the client and is not obliged to be one discovery returned.
|
|
33
|
+
*
|
|
34
|
+
* Containment is `isInsideDir`, which folds case on Windows: `c:\users\pc\ppm`
|
|
35
|
+
* and `C:\Users\PC\ppm` are one directory, and a case-sensitive prefix test
|
|
36
|
+
* answers 400 for the second — a path this server handed out itself.
|
|
37
|
+
*/
|
|
38
|
+
gitRoutes.use("*", async (c, next) => {
|
|
39
|
+
const repo = c.req.query("repo");
|
|
40
|
+
if (repo) {
|
|
41
|
+
const root = realPathOrSelfSync(resolve(c.get("projectPath")));
|
|
42
|
+
const target = realPathOrSelfSync(resolve(repo));
|
|
43
|
+
if (!isInsideDir(target, root)) {
|
|
44
|
+
return c.json(err("repo is outside the project"), 400);
|
|
45
|
+
}
|
|
46
|
+
if (!isGitRepo(target)) {
|
|
47
|
+
return c.json(err("repo is not a git repository"), 400);
|
|
48
|
+
}
|
|
49
|
+
c.set("projectPath", target);
|
|
50
|
+
}
|
|
51
|
+
await next();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The `ref`-ish query parameters, refused at the boundary rather than handed on.
|
|
56
|
+
*
|
|
57
|
+
* A revision reaches git as its own argv word, so the hazard is not a shell
|
|
58
|
+
* metacharacter but a value that changes what the command *is*: `?ref1=--output=/tmp/x`
|
|
59
|
+
* is an option, not a revision, and `git diff` honours it. `assertSafeRev` is
|
|
60
|
+
* the rule the blame path already states — no leading dash, no `..` range, none
|
|
61
|
+
* of what `check-ref-format` forbids — and `HEAD~1` and `main^` still pass,
|
|
62
|
+
* because those are what the diff viewer actually asks for.
|
|
63
|
+
*/
|
|
64
|
+
function invalidRev(...revs: Array<string | undefined>): string | null {
|
|
65
|
+
for (const rev of revs) {
|
|
66
|
+
if (rev === undefined) continue;
|
|
67
|
+
try {
|
|
68
|
+
assertSafeRev(rev);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return (e as Error).message;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* GET /git/repos — the repositories under this project.
|
|
78
|
+
*
|
|
79
|
+
* Answers for a project whose root is not a repository, which is the case the
|
|
80
|
+
* git surfaces used to report as an error.
|
|
81
|
+
*/
|
|
82
|
+
gitRoutes.get("/repos", (c) => {
|
|
83
|
+
try {
|
|
84
|
+
return c.json(ok(discoverGitRepos(c.get("projectPath"))));
|
|
85
|
+
} catch (e) {
|
|
86
|
+
return c.json(err((e as Error).message), 500);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
11
90
|
/** GET /git/status */
|
|
12
91
|
gitRoutes.get("/status", async (c) => {
|
|
13
92
|
try {
|
|
@@ -25,6 +104,8 @@ gitRoutes.get("/diff", async (c) => {
|
|
|
25
104
|
const projectPath = c.get("projectPath");
|
|
26
105
|
const ref1 = c.req.query("ref1") || undefined;
|
|
27
106
|
const ref2 = c.req.query("ref2") || undefined;
|
|
107
|
+
const bad = invalidRev(ref1, ref2);
|
|
108
|
+
if (bad) return c.json(err(bad), 400);
|
|
28
109
|
const diff = await gitService.diff(projectPath, ref1, ref2);
|
|
29
110
|
return c.json(ok({ diff }));
|
|
30
111
|
} catch (e) {
|
|
@@ -38,6 +119,8 @@ gitRoutes.get("/diff-stat", async (c) => {
|
|
|
38
119
|
const projectPath = c.get("projectPath");
|
|
39
120
|
const ref1 = c.req.query("ref1") || undefined;
|
|
40
121
|
const ref2 = c.req.query("ref2") || undefined;
|
|
122
|
+
const bad = invalidRev(ref1, ref2);
|
|
123
|
+
if (bad) return c.json(err(bad), 400);
|
|
41
124
|
const files = await gitService.diffStat(projectPath, ref1, ref2);
|
|
42
125
|
return c.json(ok(files));
|
|
43
126
|
} catch (e) {
|
|
@@ -52,6 +135,8 @@ gitRoutes.get("/file-diff", async (c) => {
|
|
|
52
135
|
const file = c.req.query("file");
|
|
53
136
|
if (!file) return c.json(err("Missing query: file"), 400);
|
|
54
137
|
const ref = c.req.query("ref") || undefined;
|
|
138
|
+
const bad = invalidRev(ref);
|
|
139
|
+
if (bad) return c.json(err(bad), 400);
|
|
55
140
|
const diff = await gitService.fileDiff(projectPath, file, ref);
|
|
56
141
|
return c.json(ok({ diff }));
|
|
57
142
|
} catch (e) {
|
|
@@ -69,6 +154,8 @@ gitRoutes.get("/file-full-diff", async (c) => {
|
|
|
69
154
|
if (!file) return c.json(err("Missing query: file"), 400);
|
|
70
155
|
const ref = c.req.query("ref") || "HEAD";
|
|
71
156
|
const ref2 = c.req.query("ref2") || undefined;
|
|
157
|
+
const bad = invalidRev(ref, ref2);
|
|
158
|
+
if (bad) return c.json(err(bad), 400);
|
|
72
159
|
const result = await gitService.fileFullDiff(projectPath, file, ref, ref2);
|
|
73
160
|
return c.json(ok(result));
|
|
74
161
|
} catch (e) {
|
|
@@ -185,6 +272,31 @@ gitRoutes.get("/blame", async (c) => {
|
|
|
185
272
|
}
|
|
186
273
|
});
|
|
187
274
|
|
|
275
|
+
/**
|
|
276
|
+
* GET /git/commit-line?hash=&path=&line= — the commit message and the one-line
|
|
277
|
+
* diff behind a blamed line, for the editor's hover.
|
|
278
|
+
*
|
|
279
|
+
* `path` and `line` are the path and line number *at that commit*, which is
|
|
280
|
+
* what `git blame --porcelain` reports; the browser passes them straight back
|
|
281
|
+
* from the blame it already has.
|
|
282
|
+
*/
|
|
283
|
+
gitRoutes.get("/commit-line", async (c) => {
|
|
284
|
+
try {
|
|
285
|
+
const projectPath = c.get("projectPath");
|
|
286
|
+
const hash = c.req.query("hash");
|
|
287
|
+
const filePath = c.req.query("path");
|
|
288
|
+
const line = Number(c.req.query("line"));
|
|
289
|
+
if (!hash) return c.json(err("Missing: hash"), 400);
|
|
290
|
+
if (!filePath) return c.json(err("Missing: path"), 400);
|
|
291
|
+
if (!Number.isInteger(line) || line < 1) return c.json(err("Invalid: line"), 400);
|
|
292
|
+
const result = await gitBlameService.lineDetail(projectPath, hash, filePath, line);
|
|
293
|
+
// An unknown hash or a path git never had is "no hover", not an error.
|
|
294
|
+
return c.json(ok(result));
|
|
295
|
+
} catch (e) {
|
|
296
|
+
return c.json(err((e as Error).message), 500);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
188
300
|
/** GET /git/hunks?path=&scope=worktree|index — the hunks the UI selects from */
|
|
189
301
|
gitRoutes.get("/hunks", async (c) => {
|
|
190
302
|
try {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language server status.
|
|
3
|
+
*
|
|
4
|
+
* This exists so "nothing is happening in the editor" has an answer. The
|
|
5
|
+
* common case for a fresh PPM install is that no language server is installed
|
|
6
|
+
* at all, which is indistinguishable from a broken feature unless something
|
|
7
|
+
* says so — hence the install hint travelling with the availability.
|
|
8
|
+
*
|
|
9
|
+
* Nothing here installs anything. A silent network install triggered by opening
|
|
10
|
+
* a file is not a thing an editor should do on the user's behalf.
|
|
11
|
+
*/
|
|
12
|
+
import { Hono } from "hono";
|
|
13
|
+
import { sep } from "node:path";
|
|
14
|
+
import { lspManager } from "../../services/lsp/lsp-manager.ts";
|
|
15
|
+
import { lspLanguageForPath } from "../../services/lsp/server-registry.ts";
|
|
16
|
+
import { ok, err } from "../../types/api.ts";
|
|
17
|
+
|
|
18
|
+
type Env = { Variables: { projectPath: string; projectName: string } };
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Is `rootPath` this project, or inside it?
|
|
22
|
+
*
|
|
23
|
+
* A bare `startsWith` is not that question: a project at `/srv/app` matched every server
|
|
24
|
+
* rooted in `/srv/app2`, so the indicator reported a neighbour's server as this project's —
|
|
25
|
+
* including its `ready` state, which is what the editor draws the server's name from.
|
|
26
|
+
*/
|
|
27
|
+
export function isWithinProject(rootPath: string, projectPath: string): boolean {
|
|
28
|
+
return rootPath === projectPath || rootPath.startsWith(projectPath.endsWith(sep) ? projectPath : projectPath + sep);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const lspRoutes = new Hono<Env>();
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* GET /lsp/status — which servers this project can use, and what is running.
|
|
35
|
+
*
|
|
36
|
+
* `path` narrows it to the server that would serve one file, which is what the
|
|
37
|
+
* editor's indicator asks for.
|
|
38
|
+
*/
|
|
39
|
+
lspRoutes.get("/status", async (c) => {
|
|
40
|
+
try {
|
|
41
|
+
const projectPath = c.get("projectPath");
|
|
42
|
+
const available = await lspManager.availability(projectPath);
|
|
43
|
+
const running = lspManager.running().filter((entry) => isWithinProject(entry.rootPath, projectPath));
|
|
44
|
+
|
|
45
|
+
const filePath = c.req.query("path");
|
|
46
|
+
const language = filePath ? lspLanguageForPath(filePath) : null;
|
|
47
|
+
|
|
48
|
+
return c.json(ok({
|
|
49
|
+
language,
|
|
50
|
+
servers: language ? available.filter((s) => s.languages.includes(language)) : available,
|
|
51
|
+
running,
|
|
52
|
+
}));
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return c.json(err((e as Error).message), 500);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export default lspRoutes;
|
|
@@ -3,6 +3,7 @@ import { resolveProjectPath } from "../helpers/resolve-project.ts";
|
|
|
3
3
|
import { chatRoutes } from "./chat.ts";
|
|
4
4
|
import { tagRoutes } from "./tag-routes.ts";
|
|
5
5
|
import { gitRoutes } from "./git.ts";
|
|
6
|
+
import { lspRoutes } from "./lsp.ts";
|
|
6
7
|
import { fileRoutes } from "./files.ts";
|
|
7
8
|
import { sqliteRoutes } from "./sqlite.ts";
|
|
8
9
|
import { workspaceRoutes } from "./workspace.ts";
|
|
@@ -29,6 +30,7 @@ projectScopedRouter.use("*", async (c, next) => {
|
|
|
29
30
|
projectScopedRouter.route("/chat", chatRoutes);
|
|
30
31
|
projectScopedRouter.route("/tags", tagRoutes);
|
|
31
32
|
projectScopedRouter.route("/git", gitRoutes);
|
|
33
|
+
projectScopedRouter.route("/lsp", lspRoutes);
|
|
32
34
|
projectScopedRouter.route("/files", fileRoutes);
|
|
33
35
|
projectScopedRouter.route("/sqlite", sqliteRoutes);
|
|
34
36
|
projectScopedRouter.route("/workspace", workspaceRoutes);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Choosing which precompressed copy of an asset to send.
|
|
3
|
+
*
|
|
4
|
+
* `scripts/precompress-web.ts` writes `<file>.br` and `<file>.gz` beside each
|
|
5
|
+
* text asset at build time. This decides which one a given request gets, and
|
|
6
|
+
* deliberately treats a missing variant as "send the original" — so a build
|
|
7
|
+
* that skipped the compression step still serves a working site, just with the
|
|
8
|
+
* bytes PPM sent before any of this existed.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type ContentEncoding = "br" | "gzip";
|
|
12
|
+
|
|
13
|
+
export interface ChosenVariant {
|
|
14
|
+
/** The file to send. The original when no variant applies. */
|
|
15
|
+
path: string;
|
|
16
|
+
/** What to declare in `Content-Encoding`, or null when sending the original. */
|
|
17
|
+
encoding: ContentEncoding | null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Extension for each encoding, matching what the build writes. */
|
|
21
|
+
const EXTENSION: Record<ContentEncoding, string> = { br: ".br", gzip: ".gz" };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Which encodings a client will accept, best first.
|
|
25
|
+
*
|
|
26
|
+
* `q=0` means *refuses* rather than "no preference", so it has to be honoured —
|
|
27
|
+
* a client that sends `gzip;q=0` and receives gzip cannot read the response.
|
|
28
|
+
* Beyond that the order here is PPM's preference, not the client's: brotli is
|
|
29
|
+
* ~20% smaller than gzip on this bundle and every browser that sends `br`
|
|
30
|
+
* handles it.
|
|
31
|
+
*/
|
|
32
|
+
export function acceptedEncodings(header: string | undefined): ContentEncoding[] {
|
|
33
|
+
if (!header) return [];
|
|
34
|
+
const refused = new Set<string>();
|
|
35
|
+
const offered = new Set<string>();
|
|
36
|
+
|
|
37
|
+
for (const part of header.split(",")) {
|
|
38
|
+
const [rawToken, ...params] = part.split(";");
|
|
39
|
+
const token = rawToken?.trim().toLowerCase();
|
|
40
|
+
if (!token) continue;
|
|
41
|
+
const q = params.map((p) => p.trim().toLowerCase()).find((p) => p.startsWith("q="));
|
|
42
|
+
if (q && Number(q.slice(2)) === 0) refused.add(token);
|
|
43
|
+
else offered.add(token);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (["br", "gzip"] as const).filter(
|
|
47
|
+
// `*` stands in for anything not named, which is how a client says "any".
|
|
48
|
+
(e) => !refused.has(e) && (offered.has(e) || (offered.has("*") && !refused.has("*"))),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The variant to send for `filePath`.
|
|
54
|
+
*
|
|
55
|
+
* `exists` is injected so this stays a pure decision — the caller owns the
|
|
56
|
+
* filesystem, and the tests do not need one.
|
|
57
|
+
*/
|
|
58
|
+
export function chooseVariant(
|
|
59
|
+
filePath: string,
|
|
60
|
+
acceptEncoding: string | undefined,
|
|
61
|
+
exists: (path: string) => boolean,
|
|
62
|
+
): ChosenVariant {
|
|
63
|
+
// A request for the variant itself is not a request to encode it again.
|
|
64
|
+
if (filePath.endsWith(".br") || filePath.endsWith(".gz")) {
|
|
65
|
+
return { path: filePath, encoding: null };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
for (const encoding of acceptedEncodings(acceptEncoding)) {
|
|
69
|
+
const candidate = filePath + EXTENSION[encoding];
|
|
70
|
+
if (exists(candidate)) return { path: candidate, encoding };
|
|
71
|
+
}
|
|
72
|
+
return { path: filePath, encoding: null };
|
|
73
|
+
}
|