@hienlh/ppm 0.17.16 → 0.17.17
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 +14 -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 +5 -1
- package/dist/web/assets/{ai-resource-editor-CsossqDO.js → ai-resource-editor-37UxM2lK.js} +1 -1
- package/dist/web/assets/{angular-html-CkxY2iBQ.js → angular-html-2g8YGiJY.js} +1 -1
- package/dist/web/assets/{angular-ts-BePeGkkC.js → angular-ts-BwSmoLfh.js} +1 -1
- package/dist/web/assets/{api-settings-DAk7D-NP.js → api-settings-BJTjIG4U.js} +1 -1
- package/dist/web/assets/{api-themes-84MT-XqR.js → api-themes-DuLpbQFV.js} +1 -1
- package/dist/web/assets/{apl-DBS7PWvB.js → apl-B44SMKHp.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-gLlhsjM9.js +1 -0
- package/dist/web/assets/{astro-Clbk1k4h.js → astro-E5620wek.js} +1 -1
- package/dist/web/assets/{audio-preview-DIkokvPM.js → audio-preview-BG8uEB67.js} +1 -1
- package/dist/web/assets/{blade-BeBsBuGS.js → blade-D-VQWAHB.js} +1 -1
- package/dist/web/assets/{bsl-DYigT3JZ.js → bsl-Bq5qFzpU.js} +1 -1
- package/dist/web/assets/{cairo-BjpO78wI.js → cairo-Cn9-ZKRa.js} +1 -1
- package/dist/web/assets/chat-tab-6G5LulPM.js +13 -0
- package/dist/web/assets/{cobol-CpuUx69s.js → cobol-IM3E3iCH.js} +1 -1
- package/dist/web/assets/code-editor-BlBFI3jn.js +10 -0
- package/dist/web/assets/{coffee-FoFd2Cxo.js → coffee-24wG7ekn.js} +1 -1
- package/dist/web/assets/{conflict-editor-Dqm1bkyL.js → conflict-editor-CYZjqn46.js} +3 -3
- package/dist/web/assets/{cpp-CO_nPfdr.js → cpp-DH9Cqt4g.js} +1 -1
- package/dist/web/assets/{crystal-D-UygAAF.js → crystal-4nZYHhdi.js} +1 -1
- package/dist/web/assets/{csv-preview-CvP4xzug.js → csv-preview-YxR9adj_.js} +1 -1
- package/dist/web/assets/data-grid-overlay-editor-DxdOKRAY.js +1 -0
- package/dist/web/assets/data-grid-types-CzEQU9PJ.js +1 -0
- package/dist/web/assets/database-viewer-CrdTyPIN.js +1 -0
- package/dist/web/assets/dialog-BpkAWOy8.js +1 -0
- package/dist/web/assets/{diff-viewer-BfWixe_z.js → diff-viewer-DiYj_kRC.js} +1 -1
- package/dist/web/assets/dist-Bn3E6I4R.js +11 -0
- package/dist/web/assets/{docx-preview-CguUoTKe.js → docx-preview-Dsrm2Hgu.js} +1 -1
- package/dist/web/assets/{edge-BSzxzX11.js → edge-DTI9d2Qi.js} +1 -1
- package/dist/web/assets/{elixir-DH1-Mrep.js → elixir-Ys0wioho.js} +1 -1
- package/dist/web/assets/{elm-B0ln5J70.js → elm-Cihc9TAz.js} +1 -1
- package/dist/web/assets/{erb-GIz6NnlZ.js → erb-BwYBWK2-.js} +1 -1
- package/dist/web/assets/{erlang-B8MgYhib.js → erlang-CzlD_Joo.js} +1 -1
- package/dist/web/assets/esm-JLkfN0k-.js +2 -0
- package/dist/web/assets/{extension-webview-DTpFt1eL.js → extension-webview-B8ph2gI9.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-D_-TrK6U.js → fortran-fixed-form-CT90EtSp.js} +1 -1
- package/dist/web/assets/{fsharp-C9cLCk2b.js → fsharp-LasxezlU.js} +1 -1
- package/dist/web/assets/{gdresource-CsZ3lXwY.js → gdresource-XqgPdfiE.js} +1 -1
- package/dist/web/assets/{git-commit-xmq0KqrA.js → git-commit-CZBgPolw.js} +1 -1
- package/dist/web/assets/{git-log-panel-DUX7N5tN.js → git-log-panel-qIsOpM57.js} +1 -1
- package/dist/web/assets/{git-rebase-D3O-jsSX.js → git-rebase-C2VzKDB1.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BKGq--Jw.js +1 -0
- package/dist/web/assets/glide-data-grid-BrQskOnP.js +138 -0
- package/dist/web/assets/{glimmer-js-g74gESrC.js → glimmer-js-DfjWcOLD.js} +1 -1
- package/dist/web/assets/{glimmer-ts-DF4aDWHT.js → glimmer-ts-DBldQATc.js} +1 -1
- package/dist/web/assets/{glsl-D5LmfW7l.js → glsl-CzNv1NPP.js} +1 -1
- package/dist/web/assets/{graphql-_KI4RuXL.js → graphql-DDyLtQb4.js} +1 -1
- package/dist/web/assets/group-chat-tab-DYgRs0zS.js +1 -0
- package/dist/web/assets/{hack-B1NaTC39.js → hack-CtoYNYkC.js} +1 -1
- package/dist/web/assets/{haml-DDFXadZ4.js → haml-CnBVap7G.js} +1 -1
- package/dist/web/assets/{handlebars-Bp-Jq3K9.js → handlebars-Dg51esUH.js} +1 -1
- package/dist/web/assets/{html-DyB9_5Tj.js → html-Ec2_evSy.js} +1 -1
- package/dist/web/assets/{html-derivative-CC60wi-3.js → html-derivative-Cy-F7ZqL.js} +1 -1
- package/dist/web/assets/{http-C-9qngH4.js → http-C236v8Tg.js} +1 -1
- package/dist/web/assets/{hurl-BtxgpNDs.js → hurl-0rMD2gPU.js} +1 -1
- package/dist/web/assets/{hxml-DOoOS9op.js → hxml-e5uS5jTD.js} +1 -1
- package/dist/web/assets/{image-preview-CZg6FQ3w.js → image-preview-B9EWGEFv.js} +1 -1
- package/dist/web/assets/index-BYFXiFsa.css +2 -0
- package/dist/web/assets/index-BiHrB3KU.js +50 -0
- package/dist/web/assets/info-3K5VOQVL-BOhGriBF.js +1 -0
- package/dist/web/assets/{jinja-cN-150ao.js → jinja-DybFmhfq.js} +1 -1
- package/dist/web/assets/{jison-CqjsqPq5.js → jison-hkHbixdZ.js} +1 -1
- package/dist/web/assets/{julia-C-I5m8W4.js → julia-QnxY6sRE.js} +1 -1
- package/dist/web/assets/{just-CgsSW9zs.js → just-1Rs-nm8g.js} +1 -1
- package/dist/web/assets/keybindings-store-CWi8IGEx.js +1 -0
- package/dist/web/assets/{latex-BFzR9N2d.js → latex-jEBQqA7u.js} +1 -1
- package/dist/web/assets/{liquid-BWfr-_iC.js → liquid-DfJaZpxG.js} +1 -1
- package/dist/web/assets/{lua-DsXVun6g.js → lua-ti0Jr6-C.js} +1 -1
- package/dist/web/assets/{markdown-renderer-CiQkvWP_.js → markdown-renderer-B4rtk2Hq.js} +3 -3
- package/dist/web/assets/markdown-renderer-XIhxiUQq.js +1 -0
- package/dist/web/assets/{marko-DWBbo09n.js → marko-DNj4AhPg.js} +1 -1
- package/dist/web/assets/{mdc-CUMe9LOG.js → mdc-DPFwQFe4.js} +1 -1
- package/dist/web/assets/mobile-bottom-sheet--5_YEewV.js +1 -0
- package/dist/web/assets/{nextflow-CoYbADOm.js → nextflow-BUrFV5aB.js} +1 -1
- package/dist/web/assets/{nginx-z-JRZREw.js → nginx-BrW9NdOb.js} +1 -1
- package/dist/web/assets/{nim-Ci4LHyBm.js → nim-DS_6PF2p.js} +1 -1
- package/dist/web/assets/notification-store-DEIj7OrE.js +1 -0
- package/dist/web/assets/{number-overlay-editor-lnnuUpPI.js → number-overlay-editor-CReXWiQ1.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-CdLFnL8a.js +1 -0
- package/dist/web/assets/{panel-store-D6RV_ztx.js → panel-store-DnbT1c8L.js} +1 -1
- package/dist/web/assets/{pdf-preview-B6ZqANpw.js → pdf-preview-Zl3KICd5.js} +1 -1
- package/dist/web/assets/{perl-pbDimKOO.js → perl-ytm9vKO_.js} +1 -1
- package/dist/web/assets/{php-B003E5v7.js → php-DWTD1Usw.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-COC-h0zz.js +1 -0
- package/dist/web/assets/{trash-2-CbbD5QF1.js → plus-DcuJuDC3.js} +1 -1
- package/dist/web/assets/postgres-viewer-BTupZTmP.js +3 -0
- package/dist/web/assets/{project-store-Cekcjcom.js → project-store-Sbnqc41N.js} +1 -1
- package/dist/web/assets/{pug-AoueAWJo.js → pug-Bt7KL3_r.js} +1 -1
- package/dist/web/assets/{qml-CepxioQA.js → qml-Dexdon5J.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-CiCfdJNL.js +1 -0
- package/dist/web/assets/{razor-lIvU-Gu-.js → razor-DnYCSl0G.js} +1 -1
- package/dist/web/assets/{rst-Dn-dwElE.js → rst-BEFYzwF8.js} +1 -1
- package/dist/web/assets/{ruby-DmsD1Iz5.js → ruby-BPaXFEjN.js} +1 -1
- package/dist/web/assets/{sas-6IM2P4YP.js → sas-CywiNBp8.js} +1 -1
- package/dist/web/assets/{scss-RgYEZQqh.js → scss-CGk0L6hN.js} +1 -1
- package/dist/web/assets/{settings-store-BkSf4SPQ.js → settings-store-DkRZhj-g.js} +2 -2
- package/dist/web/assets/settings-tab-BF069B1K.js +1 -0
- package/dist/web/assets/{shaderlab-B0MNEwt4.js → shaderlab-Byjk0kH7.js} +1 -1
- package/dist/web/assets/{shellsession-F8S4LrQI.js → shellsession-DbA70QB6.js} +1 -1
- package/dist/web/assets/{soy-DDlMbX7u.js → soy-Bm97kWiA.js} +1 -1
- package/dist/web/assets/sparkles-B3DmG8PJ.js +1 -0
- package/dist/web/assets/{sparql-kthmGAAe.js → sparql-CawLnniT.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BYNM0RRl.js → sql-query-editor-RwHY1p-a.js} +1 -1
- package/dist/web/assets/sqlite-viewer-3UxftoM7.js +1 -0
- package/dist/web/assets/{stata-Tfbew8La.js → stata-RifEDtNO.js} +1 -1
- package/dist/web/assets/{surrealql-C0LIGqRx.js → surrealql-DGRQa5Lm.js} +1 -1
- package/dist/web/assets/{svelte-CfTy8CGF.js → svelte-w9Hb12aM.js} +1 -1
- package/dist/web/assets/system-monitor-tab-Ck1cIP7g.js +1 -0
- package/dist/web/assets/{tab-store-CcLQfu8H.js → tab-store-vn0viMOP.js} +1 -1
- package/dist/web/assets/{templ-V5H1Sbfy.js → templ-BpUwjJXV.js} +1 -1
- package/dist/web/assets/{terminal-tab-CK3lX-0Y.js → terminal-tab-B9opPxft.js} +2 -2
- package/dist/web/assets/{tex-C3H3uMZf.js → tex-DJFSsuTD.js} +1 -1
- package/dist/web/assets/tool-cards-C7iLwehG.js +7 -0
- package/dist/web/assets/treemap-KZPCXAKY-CZwuSCtA.js +1 -0
- package/dist/web/assets/{ts-tags-7AXgG5YS.js → ts-tags-vp9Qvx2O.js} +1 -1
- package/dist/web/assets/{twig-BSyS38T3.js → twig-CoazxjRB.js} +1 -1
- package/dist/web/assets/{use-blob-url-CpyRr7Cx.js → use-blob-url-DdXgVqfz.js} +1 -1
- package/dist/web/assets/use-is-mobile-CE6AamG6.js +1 -0
- package/dist/web/assets/{use-monaco-theme-Jj2OxkAE.js → use-monaco-theme-jtYkroys.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-DGOXKrJC.js → vendor-mermaid-DPpYkrMf.js} +193 -193
- package/dist/web/assets/{video-preview-BOHxkwKG.js → video-preview-Ced_VIvq.js} +1 -1
- package/dist/web/assets/{vue-C4d_br9u.js → vue-CnshsiXd.js} +1 -1
- package/dist/web/assets/{vue-html-CGdoz4vW.js → vue-html-CZshynFp.js} +1 -1
- package/dist/web/assets/{vue-vine-CqNolQlN.js → vue-vine-C5gtp_T1.js} +1 -1
- package/dist/web/assets/{xml-UmCmu-Od.js → xml-BEGJasgj.js} +1 -1
- package/dist/web/assets/{xsl-DJG6USGh.js → xsl-DXpRLjYk.js} +1 -1
- package/dist/web/index.html +22 -20
- package/dist/web/monacoeditorwork/css.worker.bundle.js +122 -122
- package/dist/web/monacoeditorwork/editor.worker.bundle.js +78 -78
- package/dist/web/monacoeditorwork/html.worker.bundle.js +110 -110
- package/dist/web/monacoeditorwork/json.worker.bundle.js +108 -108
- package/dist/web/monacoeditorwork/ts.worker.bundle.js +81 -81
- package/dist/web/sw.js +1 -1
- package/docs/journal/binary-self-upgrade-260724.md +66 -0
- package/nul/docs/claude-agent-sdk-reference.md +780 -0
- package/nul/docs/code-standards.md +1080 -0
- package/nul/docs/codebase-summary.md +916 -0
- package/nul/docs/deployment-guide.md +702 -0
- package/nul/docs/design-guidelines.md +767 -0
- package/nul/docs/extension-development-guide.md +629 -0
- package/nul/docs/journals/260414-1400-ext-git-graph-port-complete.md +147 -0
- package/nul/docs/journals/260414-1452-git-graph-faithful-port.md +144 -0
- package/nul/docs/journals/260414-1810-git-graph-ui-improvements-complete.md +261 -0
- package/nul/docs/journals/260414-2001-bundled-extensions.md +219 -0
- package/nul/docs/journals/260415-frontend-memory-optimization.md +73 -0
- package/nul/docs/lessons-learned.md +70 -0
- package/nul/docs/project-changelog.md +574 -0
- package/nul/docs/project-overview-pdr.md +205 -0
- package/nul/docs/project-roadmap.md +222 -0
- package/nul/docs/system-architecture.md +1961 -0
- package/package.json +1 -1
- 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/spike-group-channel.mjs +156 -0
- package/spike-group-chat.mjs +181 -0
- package/src/server/routes/group-chat.ts +118 -9
- package/src/services/group-chat/agent-runner.ts +15 -2
- package/src/services/group-chat/context-window.ts +15 -0
- package/src/services/group-chat/group-chat.service.ts +178 -79
- package/src/services/group-chat/group-chat.store.ts +30 -0
- package/src/services/group-chat/responder-router.ts +110 -0
- package/src/services/group-chat/transcript-archive.ts +18 -0
- package/src/services/group-chat/turn-engine.ts +183 -105
- package/src/services/jsonl-transcript-parser.ts +36 -0
- package/src/types/group-chat-ws.ts +2 -2
- package/src/types/group-chat.ts +33 -4
- package/src/web/components/group-chat/group-chat-tab.tsx +109 -14
- package/src/web/components/group-chat/group-create-dialog.tsx +10 -3
- package/src/web/components/group-chat/group-full-transcript-view.tsx +9 -8
- package/src/web/components/group-chat/group-member-edit-dialog.tsx +108 -0
- package/src/web/components/group-chat/group-member-roster.tsx +51 -23
- package/src/web/components/group-chat/group-message-item.tsx +45 -26
- package/src/web/components/group-chat/group-transcript-messages.tsx +126 -0
- package/src/web/components/layout/mobile-drawer-tab-bar.tsx +10 -0
- package/src/web/components/layout/nav-section-rail.tsx +8 -2
- package/src/web/components/layout/upgrade-button.tsx +33 -11
- package/src/web/hooks/use-group-chat.ts +8 -1
- package/src/web/lib/api-group-chat.ts +47 -4
- package/src/web/lib/sidebar-tabs/tab-registry.ts +3 -1
- package/dist/web/assets/architecture-PBZL5I3N-NAS99xy0.js +0 -1
- package/dist/web/assets/chat-tab-Bh6l253v.js +0 -18
- package/dist/web/assets/click-outside-container-DXZVmhaX.js +0 -1
- package/dist/web/assets/code-editor-B7F-d4DK.js +0 -10
- package/dist/web/assets/data-grid-overlay-editor-CUlFsD-D.js +0 -1
- package/dist/web/assets/database-viewer-5oNTPgjF.js +0 -1
- package/dist/web/assets/dist-BsziT-tR.js +0 -11
- package/dist/web/assets/esm-CjVeOTNQ.js +0 -2
- package/dist/web/assets/gitGraph-HDMCJU4V-B4I3L4Sf.js +0 -1
- package/dist/web/assets/glide-data-grid-7vB1SNne.js +0 -138
- package/dist/web/assets/group-chat-tab-CNECY-zg.js +0 -1
- package/dist/web/assets/index-D2G6kmTs.js +0 -50
- package/dist/web/assets/index-DCmrZnq0.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-CBbbOe3C.js +0 -1
- package/dist/web/assets/input-24Nf_edC.js +0 -1
- package/dist/web/assets/keybindings-store-D8Cppv4w.js +0 -1
- package/dist/web/assets/notification-store-DOGxkWih.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-fr8-QSTF.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-Biu7_Pbb.js +0 -1
- package/dist/web/assets/postgres-viewer-B23xTCSs.js +0 -3
- package/dist/web/assets/radar-KQ55EAFF-CMtNRpK6.js +0 -1
- package/dist/web/assets/settings-tab-D5hAA1bY.js +0 -1
- package/dist/web/assets/sparkles-2ii4lR7b.js +0 -1
- package/dist/web/assets/sqlite-viewer-DW9f2Hqj.js +0 -1
- package/dist/web/assets/system-monitor-tab-B5f4pgdX.js +0 -1
- package/dist/web/assets/treemap-KZPCXAKY-ZYVFjoaN.js +0 -1
- package/dist/web/assets/use-websocket-DrDBgIWU.js +0 -1
- /package/dist/web/assets/{abap-BZ3J5hF3.js → abap-wT6fgqwv.js} +0 -0
- /package/dist/web/assets/{actionscript-3-CkyGfT-8.js → actionscript-3-CqcHpPYj.js} +0 -0
- /package/dist/web/assets/{ada-CxNLBoe7.js → ada-DWE3Hn4E.js} +0 -0
- /package/dist/web/assets/{andromeeda-BPN5rsDz.js → andromeeda-DpQ-y-Jt.js} +0 -0
- /package/dist/web/assets/{apache-C1F5wHL6.js → apache-LRTUP4r3.js} +0 -0
- /package/dist/web/assets/{apex-BaNixdO-.js → apex-DwVeH5_h.js} +0 -0
- /package/dist/web/assets/{api-client-Dvzcc_EO.js → api-client-BK4NPNoY.js} +0 -0
- /package/dist/web/assets/{applescript-Cl_pdcch.js → applescript-DyQiO9JU.js} +0 -0
- /package/dist/web/assets/{apply-theme-ORrEdHKT.js → apply-theme-DxKsrDLA.js} +0 -0
- /package/dist/web/assets/{ara-B6UAE7M2.js → ara-Cf-OWd2S.js} +0 -0
- /package/dist/web/assets/{asciidoc-D9c9Twki.js → asciidoc-gocbKcVK.js} +0 -0
- /package/dist/web/assets/{asm-CNmtv7Y9.js → asm-C3meb5HY.js} +0 -0
- /package/dist/web/assets/{aurora-x-C9z-NyzR.js → aurora-x-BYcXaCIg.js} +0 -0
- /package/dist/web/assets/{awk-BfLHEnKa.js → awk-BcT6nIdN.js} +0 -0
- /package/dist/web/assets/{ayu-dark-Bn7trkt_.js → ayu-dark-CLZPoccg.js} +0 -0
- /package/dist/web/assets/{ayu-light-Dpya9hPf.js → ayu-light-CTyRQdS2.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-Cc0jfABD.js → ayu-mirage-DjqfqZdo.js} +0 -0
- /package/dist/web/assets/{ballerina-BtiCmN7T.js → ballerina-BCARR-zK.js} +0 -0
- /package/dist/web/assets/{bat-tmFM76zR.js → bat-_yaRjWOb.js} +0 -0
- /package/dist/web/assets/{beancount-BjPqRrcH.js → beancount-BPESBMS9.js} +0 -0
- /package/dist/web/assets/{berry-D0SQBxN2.js → berry-BSLE-Sf8.js} +0 -0
- /package/dist/web/assets/{bibtex-CkjRWQKr.js → bibtex-CvUWWCVx.js} +0 -0
- /package/dist/web/assets/{bicep-Bhq28Cxc.js → bicep--vcqqALZ.js} +0 -0
- /package/dist/web/assets/{bird2-DFGInYb3.js → bird2-Clclqgh6.js} +0 -0
- /package/dist/web/assets/{c-CP8cB4k_.js → c-CSC2LwTp.js} +0 -0
- /package/dist/web/assets/{c3-oRytyeWo.js → c3-Cl1_jUnm.js} +0 -0
- /package/dist/web/assets/{cadence-Inf1rGb7.js → cadence-BwAD7vSC.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-DAzribQo.js → catppuccin-frappe-hr0HKoFX.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-B6Y_mCCQ.js → catppuccin-latte-DXEIYlFO.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-COLbYqVL.js → catppuccin-macchiato-B2zST7sA.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-DKWaML1B.js → catppuccin-mocha-CvrdnYv9.js} +0 -0
- /package/dist/web/assets/{chevron-right-BBc6ATtm.js → chevron-right-DeUue2aK.js} +0 -0
- /package/dist/web/assets/{circle-question-mark-CveWaCux.js → circle-question-mark-PaJgx-3d.js} +0 -0
- /package/dist/web/assets/{clarity-_ZLLrrsX.js → clarity-BeQd5TQD.js} +0 -0
- /package/dist/web/assets/{clojure-DWGVCg_P.js → clojure-Csdo0vb_.js} +0 -0
- /package/dist/web/assets/{cmake-Cwh3mug7.js → cmake-Cf0q7ddg.js} +0 -0
- /package/dist/web/assets/{code-7ZAlTvsm.js → code-TekEnDFM.js} +0 -0
- /package/dist/web/assets/{codeowners-BdV6CFYi.js → codeowners-CUEzlC7R.js} +0 -0
- /package/dist/web/assets/{codeql-NvupDIDf.js → codeql-DxHyogQt.js} +0 -0
- /package/dist/web/assets/{common-lisp-B-vtBh5k.js → common-lisp-WLb-tAda.js} +0 -0
- /package/dist/web/assets/{coq-M8-FTfiZ.js → coq-DFtMD6Wn.js} +0 -0
- /package/dist/web/assets/{csharp-B7Ugdtd-.js → csharp-DEnvXVjs.js} +0 -0
- /package/dist/web/assets/{css-86k3Z-YA.js → css-DMPpCfkZ.js} +0 -0
- /package/dist/web/assets/{csv-BX5XYhfH.js → csv-DTSgNSaP.js} +0 -0
- /package/dist/web/assets/{csv-parser-d56Fzpwc.js → csv-parser-B_xNn07y.js} +0 -0
- /package/dist/web/assets/{cue-B7099gQa.js → cue-BEmVIZmd.js} +0 -0
- /package/dist/web/assets/{cypher-D99mWVIu.js → cypher-CncQVhvU.js} +0 -0
- /package/dist/web/assets/{d-CFE8oQwh.js → d-BzUSBVex.js} +0 -0
- /package/dist/web/assets/{dark-plus-BEeeDwdg.js → dark-plus-mysFNRq2.js} +0 -0
- /package/dist/web/assets/{dart-HVSWGnI5.js → dart-BBu3nkcE.js} +0 -0
- /package/dist/web/assets/{database-BLht7BVM.js → database-COYAMZaw.js} +0 -0
- /package/dist/web/assets/{dax-DjDgSJkh.js → dax-DcLVz9_9.js} +0 -0
- /package/dist/web/assets/{desktop-B5A3i7J1.js → desktop-DS2PdvoU.js} +0 -0
- /package/dist/web/assets/{diff-CpTrlaE9.js → diff-aUYk5Qys.js} +0 -0
- /package/dist/web/assets/{dist-BSCgJs-V.js → dist-Dxl3dqhC.js} +0 -0
- /package/dist/web/assets/{docker-xBhmJeHj.js → docker-12Lj1QUD.js} +0 -0
- /package/dist/web/assets/{dotenv-DKKhLEv5.js → dotenv-D-P4bzvl.js} +0 -0
- /package/dist/web/assets/{dracula-CVwQuzra.js → dracula-C-eRNn4o.js} +0 -0
- /package/dist/web/assets/{dracula-soft-CG6mB-lf.js → dracula-soft-CBB1BI7O.js} +0 -0
- /package/dist/web/assets/{dream-maker-SC-IdYY3.js → dream-maker-C_j5A0r7.js} +0 -0
- /package/dist/web/assets/{edit-diff-preview-C50i1H63.js → edit-diff-preview-CRMu-6r1.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CIBFq6W8.js → emacs-lisp-W54LT7rh.js} +0 -0
- /package/dist/web/assets/{everforest-dark-odRT_lec.js → everforest-dark-B_ISUDeh.js} +0 -0
- /package/dist/web/assets/{everforest-light-or1Voqjl.js → everforest-light-CNUYa354.js} +0 -0
- /package/dist/web/assets/{fennel-tQd1z3iu.js → fennel-DK82-oso.js} +0 -0
- /package/dist/web/assets/{file-exclamation-point-C-lL0g_E.js → file-exclamation-point-DBEC-Kst.js} +0 -0
- /package/dist/web/assets/{fish-DSuZQG0k.js → fish-CbJVJzQj.js} +0 -0
- /package/dist/web/assets/{fluent-D7xI8a8e.js → fluent-Cug5cOL1.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-BlAtcPd3.js → fortran-free-form-amHz32Zw.js} +0 -0
- /package/dist/web/assets/{gdscript-VsEQXBPm.js → gdscript-t_G6VYpv.js} +0 -0
- /package/dist/web/assets/{gdshader-iqHMOdwW.js → gdshader-DqZaHh4E.js} +0 -0
- /package/dist/web/assets/{genie-C4XU4g1a.js → genie-CIJtFlZK.js} +0 -0
- /package/dist/web/assets/{gherkin-C4nfQzAB.js → gherkin-CalidqLY.js} +0 -0
- /package/dist/web/assets/{github-dark-B_pbG3CC.js → github-dark-BG2xX0wa.js} +0 -0
- /package/dist/web/assets/{github-dark-default-kFbx7C95.js → github-dark-default-tDp_EOBs.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-CpVfQEqs.js → github-dark-dimmed-DlSfPwW2.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-DYKqQwZh.js → github-dark-high-contrast-qZM7j5KB.js} +0 -0
- /package/dist/web/assets/{github-light-gEYBmKaj.js → github-light-CnvWTiyb.js} +0 -0
- /package/dist/web/assets/{github-light-default-DVHfMPQ2.js → github-light-default-Dy6OAt2Q.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-ClVJDu-q.js → github-light-high-contrast-1BHQCOPl.js} +0 -0
- /package/dist/web/assets/{gleam-BLaPu7ft.js → gleam-D-2cpXVX.js} +0 -0
- /package/dist/web/assets/{gn-BKgerUyI.js → gn-C1cC4xLc.js} +0 -0
- /package/dist/web/assets/{gnuplot-cqJuEFb-.js → gnuplot-2Gp459mV.js} +0 -0
- /package/dist/web/assets/{go-B2EHdyD8.js → go-BA1q0q8h.js} +0 -0
- /package/dist/web/assets/{groovy-DdImoj8s.js → groovy-BlIa-VfI.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DlwstAds.js → gruvbox-dark-hard-BMIwVwaJ.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-CiYEd1vd.js → gruvbox-dark-medium-DxfuBW3n.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-C-wEa4h4.js → gruvbox-dark-soft-_NSslDDi.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-BqYmfna-.js → gruvbox-light-hard-CP5MIsL9.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-CxmfalT2.js → gruvbox-light-medium-BTMursH0.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-DGWXXMCB.js → gruvbox-light-soft-Bv6zFoVX.js} +0 -0
- /package/dist/web/assets/{haskell-H_C_IuVb.js → haskell-Da8UeSv-.js} +0 -0
- /package/dist/web/assets/{haxe-CGNSMpeZ.js → haxe-mcKlcxBa.js} +0 -0
- /package/dist/web/assets/{hcl-B7bSTSQf.js → hcl-BdZcx5JX.js} +0 -0
- /package/dist/web/assets/{hjson-DlJ-glQZ.js → hjson-pFXYbN4t.js} +0 -0
- /package/dist/web/assets/{hlsl-CehW5SJN.js → hlsl-Z0II0KR8.js} +0 -0
- /package/dist/web/assets/{horizon-Beabcz2d.js → horizon-CufN8DyP.js} +0 -0
- /package/dist/web/assets/{horizon-bright-BC87RXPa.js → horizon-bright-5qoQVyIY.js} +0 -0
- /package/dist/web/assets/{houston-Da7RFwUy.js → houston-DOFkQwep.js} +0 -0
- /package/dist/web/assets/{hy-m1H70w19.js → hy-BVbDMDcG.js} +0 -0
- /package/dist/web/assets/{imba-MExFsdAA.js → imba-DRM6LLS5.js} +0 -0
- /package/dist/web/assets/{ini-CJy_zmwy.js → ini-2KCnNvmz.js} +0 -0
- /package/dist/web/assets/{java-DqDFvJBH.js → java-BmvH-Ou1.js} +0 -0
- /package/dist/web/assets/{javascript-C3Wyv22X.js → javascript-B7VhU1Yc.js} +0 -0
- /package/dist/web/assets/{json-DnGBw_DZ.js → json-X1pNk0n7.js} +0 -0
- /package/dist/web/assets/{json5-CRN-zoN4.js → json5-CJeEJPTg.js} +0 -0
- /package/dist/web/assets/{jsonc-CKRUZNRo.js → jsonc-C1haTBsf.js} +0 -0
- /package/dist/web/assets/{jsonl-CGfD6FrH.js → jsonl-wQ8-AJgs.js} +0 -0
- /package/dist/web/assets/{jsonnet-nbFuDj0o.js → jsonnet-BrEjY3Xh.js} +0 -0
- /package/dist/web/assets/{jssm-D0ShzIqD.js → jssm-C6LgYbOs.js} +0 -0
- /package/dist/web/assets/{jsx-D27hbRbs.js → jsx-B2cfD_Fb.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-Ov3f8K0T.js → kanagawa-dragon-6UCcJpLw.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-CLyOqh-g.js → kanagawa-lotus-DOmfpsRg.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-Kj3dzabH.js → kanagawa-wave-CpxmPE7N.js} +0 -0
- /package/dist/web/assets/{kdl-DFF58Gu4.js → kdl-BrLEivmb.js} +0 -0
- /package/dist/web/assets/{kotlin-BM4PKaB4.js → kotlin-BO2FUnDB.js} +0 -0
- /package/dist/web/assets/{kusto-DrvHLCv5.js → kusto-Cev1yiq9.js} +0 -0
- /package/dist/web/assets/{laserwave-Db6i6ZkO.js → laserwave-BlEkf-eH.js} +0 -0
- /package/dist/web/assets/{lean-D0hEjzwk.js → lean-BLS3Xk2w.js} +0 -0
- /package/dist/web/assets/{less-BEj4npGG.js → less-BXmcsqcq.js} +0 -0
- /package/dist/web/assets/{lib-CBdlQ75W.js → lib-CxSBdrd7.js} +0 -0
- /package/dist/web/assets/{light-plus-DLIIbDea.js → light-plus-DS6zriYl.js} +0 -0
- /package/dist/web/assets/{llvm-DMt6umsO.js → llvm-C_wLnJgX.js} +0 -0
- /package/dist/web/assets/{log-BopvdtPW.js → log-Cg8pvmWi.js} +0 -0
- /package/dist/web/assets/{logo-CYSUFPFR.js → logo-C9-kEvPW.js} +0 -0
- /package/dist/web/assets/{luau-XC611HNO.js → luau-NwaGugfZ.js} +0 -0
- /package/dist/web/assets/{make-BMYZIfBj.js → make-DBpJE-Z8.js} +0 -0
- /package/dist/web/assets/{markdown-BLza5nvF.js → markdown-B7ZTAu7B.js} +0 -0
- /package/dist/web/assets/{material-theme-Uw27UfJW.js → material-theme-BsXH-Mss.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-dfqt8XBY.js → material-theme-darker-CW9OlIeY.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-CPtBTblV.js → material-theme-lighter-D2PAh0Kw.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-BfZgVqC-.js → material-theme-ocean-Vz6DBVi3.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-DAZoVYg8.js → material-theme-palenight-D-GleP3G.js} +0 -0
- /package/dist/web/assets/{matlab-cSzmquiW.js → matlab-C7MYlMSn.js} +0 -0
- /package/dist/web/assets/{mdx-Dq0kW5VM.js → mdx-FkOOX3Dq.js} +0 -0
- /package/dist/web/assets/{mermaid-DoIKF0yS.js → mermaid-C_9qw5it.js} +0 -0
- /package/dist/web/assets/{min-dark-DyraimDU.js → min-dark-BowNvxk2.js} +0 -0
- /package/dist/web/assets/{min-light-Co9cbcUv.js → min-light-x8oWUmbL.js} +0 -0
- /package/dist/web/assets/{mipsasm-ph6cKgHn.js → mipsasm-Dmi1AZOT.js} +0 -0
- /package/dist/web/assets/{mojo-BBT0XwmY.js → mojo-C6z7mry2.js} +0 -0
- /package/dist/web/assets/{monokai-IP0T5Rtg.js → monokai-BQ4e_Hn0.js} +0 -0
- /package/dist/web/assets/{moonbit-B8cogNXl.js → moonbit-CEeNIoB4.js} +0 -0
- /package/dist/web/assets/{move-DkY26NtM.js → move-bALfKUa7.js} +0 -0
- /package/dist/web/assets/{narrat-rBs3byG0.js → narrat-DX4JlAWT.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-DkO9wMLP.js → nextflow-groovy-CKQWtRkO.js} +0 -0
- /package/dist/web/assets/{night-owl-jVR4lFji.js → night-owl-D4PQd726.js} +0 -0
- /package/dist/web/assets/{night-owl-light-fBYJ7s3U.js → night-owl-light-BQo_YHll.js} +0 -0
- /package/dist/web/assets/{nix-WX9oavu6.js → nix-B1jThkGj.js} +0 -0
- /package/dist/web/assets/{nord-Cf7G21Pu.js → nord-35quHUKo.js} +0 -0
- /package/dist/web/assets/{nushell-DQdzcJ1H.js → nushell-L6DbJTuL.js} +0 -0
- /package/dist/web/assets/{objective-c-JSO2uvZ-.js → objective-c-CTZ4bR2U.js} +0 -0
- /package/dist/web/assets/{objective-cpp-CZMGJ9Fb.js → objective-cpp-Dm1YDIdA.js} +0 -0
- /package/dist/web/assets/{ocaml-C4S4NSDo.js → ocaml-B3n__LGy.js} +0 -0
- /package/dist/web/assets/{odin-Y2jXCgVq.js → odin-DmqZ8n3i.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-dVIxuoJY.js → one-dark-pro-16_UaUig.js} +0 -0
- /package/dist/web/assets/{one-light-BQ1IKfD1.js → one-light-B-GGjWn5.js} +0 -0
- /package/dist/web/assets/{openscad-Bddw4I3z.js → openscad-DTFB9Sj6.js} +0 -0
- /package/dist/web/assets/{pascal-BKVXrzC1.js → pascal-RcT1dQYN.js} +0 -0
- /package/dist/web/assets/{pkl-BTd-YRsO.js → pkl-Dr4yLQ_o.js} +0 -0
- /package/dist/web/assets/{plastic-eiGvBIxV.js → plastic-hp2Nry0R.js} +0 -0
- /package/dist/web/assets/{plsql-C290tieP.js → plsql-pFcO4WZ0.js} +0 -0
- /package/dist/web/assets/{po-DyDwh0tx.js → po-BkZ0_HvY.js} +0 -0
- /package/dist/web/assets/{poimandres-B87zc_g-.js → poimandres-BcTrxj7f.js} +0 -0
- /package/dist/web/assets/{polar-Cdub1YMT.js → polar-DHK3q8FF.js} +0 -0
- /package/dist/web/assets/{postcss-BcI_3K0v.js → postcss-Bv7WzijA.js} +0 -0
- /package/dist/web/assets/{powerquery-OdMrkJSe.js → powerquery-DpaU_hW9.js} +0 -0
- /package/dist/web/assets/{powershell-C8auT6xg.js → powershell-_Rqc0MGP.js} +0 -0
- /package/dist/web/assets/{prisma-DIbVv8PA.js → prisma-wyegE8us.js} +0 -0
- /package/dist/web/assets/{prolog-DbTOH3Ld.js → prolog-DspHCURv.js} +0 -0
- /package/dist/web/assets/{proto-C4Cq2dCD.js → proto-BOBiNGf5.js} +0 -0
- /package/dist/web/assets/{puppet-DJp3uqum.js → puppet-DfLvV8h2.js} +0 -0
- /package/dist/web/assets/{purescript-CLsV4rPU.js → purescript-BY5ZSOZy.js} +0 -0
- /package/dist/web/assets/{python-2gBtEza2.js → python-B758mMeg.js} +0 -0
- /package/dist/web/assets/{qmldir-DfhULcua.js → qmldir-C75bpHvy.js} +0 -0
- /package/dist/web/assets/{qss-DK--VTTV.js → qss-DcLTlbLd.js} +0 -0
- /package/dist/web/assets/{r-BArBO2Sa.js → r-D0G_Y1P5.js} +0 -0
- /package/dist/web/assets/{racket-5mijHsVy.js → racket-DTye_5qn.js} +0 -0
- /package/dist/web/assets/{raku-ir0suElk.js → raku-uJXBXkV0.js} +0 -0
- /package/dist/web/assets/{react-J9g6e3Rq.js → react-CorNPdie.js} +0 -0
- /package/dist/web/assets/{red-DSecpIOT.js → red-rs3HE3re.js} +0 -0
- /package/dist/web/assets/{reg-Dp30FusS.js → reg-DkTIaX7a.js} +0 -0
- /package/dist/web/assets/{regexp-DXJnEM_6.js → regexp-4TLSs4_m.js} +0 -0
- /package/dist/web/assets/{rel-Dr483ozj.js → rel-B0jumCjt.js} +0 -0
- /package/dist/web/assets/{resolve-theme-DJORYzKu.js → resolve-theme-CCoakF2E.js} +0 -0
- /package/dist/web/assets/{riscv-ZfBy5IA1.js → riscv-DtaWMlo0.js} +0 -0
- /package/dist/web/assets/{ron-ZJ_CljGP.js → ron-BCPxwJD6.js} +0 -0
- /package/dist/web/assets/{rose-pine-CcW_eJ6G.js → rose-pine-CNryoqGi.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-v2l_UF-j.js → rose-pine-dawn-C-gJOQVP.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-CNXkwf3D.js → rose-pine-moon-BdXSXpZh.js} +0 -0
- /package/dist/web/assets/{rosmsg-BMYMVW84.js → rosmsg-CPG8X-D5.js} +0 -0
- /package/dist/web/assets/{rust-BR-zJh5q.js → rust-CxfW3ePx.js} +0 -0
- /package/dist/web/assets/{sass-BukPOBFz.js → sass-D-7bxo_L.js} +0 -0
- /package/dist/web/assets/{save-DO5xjW95.js → save-BM4p9_9n.js} +0 -0
- /package/dist/web/assets/{scala-DUFY7D6D.js → scala-DyUsfHNc.js} +0 -0
- /package/dist/web/assets/{scheme-Dl-dNNxQ.js → scheme-ROgrwiO-.js} +0 -0
- /package/dist/web/assets/{sdbl-DdmlQhia.js → sdbl-B1EAQWpp.js} +0 -0
- /package/dist/web/assets/{shellscript-UyhrvGcd.js → shellscript-HhmB_Ufy.js} +0 -0
- /package/dist/web/assets/{shield-check-m2QzZTuZ.js → shield-check-C3qYSU8a.js} +0 -0
- /package/dist/web/assets/{shield-off-DNn7VzJe.js → shield-off-D5tU7gQT.js} +0 -0
- /package/dist/web/assets/{slack-dark-Cv6Szr-q.js → slack-dark-DnmSY72G.js} +0 -0
- /package/dist/web/assets/{slack-ochin-V6Ii3lAm.js → slack-ochin-q97gHjcd.js} +0 -0
- /package/dist/web/assets/{smalltalk-BUCv5G91.js → smalltalk-B-1waXvA.js} +0 -0
- /package/dist/web/assets/{snazzy-light-B67a78qi.js → snazzy-light-C8yWDN2g.js} +0 -0
- /package/dist/web/assets/{solarized-dark-ccWnfYyA.js → solarized-dark-ClVDEMJZ.js} +0 -0
- /package/dist/web/assets/{solarized-light-C3WyRO5I.js → solarized-light-Bts6CUIP.js} +0 -0
- /package/dist/web/assets/{solidity-BFbRPNi_.js → solidity-DYxwp0om.js} +0 -0
- /package/dist/web/assets/{splunk-zdpwCJLE.js → splunk-jK6-Sr06.js} +0 -0
- /package/dist/web/assets/{sql-B2IPUsfz.js → sql-DPpd8aUS.js} +0 -0
- /package/dist/web/assets/{ssh-config-Co4cXifq.js → ssh-config-Bimb9LVr.js} +0 -0
- /package/dist/web/assets/{stylus-CmI75XY8.js → stylus-B2DgJRJw.js} +0 -0
- /package/dist/web/assets/{swift-Dfks9YQI.js → swift-ChEH2nFL.js} +0 -0
- /package/dist/web/assets/{synthwave-84-B3LERzNS.js → synthwave-84-DwSLbgAm.js} +0 -0
- /package/dist/web/assets/{system-verilog-BFvldiwl.js → system-verilog-DoVBMhJ8.js} +0 -0
- /package/dist/web/assets/{systemd-Cu4Vvgbu.js → systemd--Ux4VAYD.js} +0 -0
- /package/dist/web/assets/{table-CAVmgQMT.js → table-Di8pv2Y_.js} +0 -0
- /package/dist/web/assets/{talonscript-Bnq32pUB.js → talonscript-DQNx9nak.js} +0 -0
- /package/dist/web/assets/{tasl-Nwe2K3J1.js → tasl-Bwy_Y9uD.js} +0 -0
- /package/dist/web/assets/{tcl-zOnpywrl.js → tcl-Drea-2jA.js} +0 -0
- /package/dist/web/assets/{terraform-Bc9Vj-n3.js → terraform-4rS5HoFk.js} +0 -0
- /package/dist/web/assets/{tokyo-night-9_KyM8M2.js → tokyo-night-C9MqaxIn.js} +0 -0
- /package/dist/web/assets/{toml-ByH-fxOY.js → toml-tSgOSv42.js} +0 -0
- /package/dist/web/assets/{tsv-DrCnDClP.js → tsv-BmL4O1Zx.js} +0 -0
- /package/dist/web/assets/{tsx-B8LafSYr.js → tsx-BwzeA880.js} +0 -0
- /package/dist/web/assets/{turtle-DuyP_QCJ.js → turtle-2DYvssFL.js} +0 -0
- /package/dist/web/assets/{typescript-BTBJb5RD.js → typescript-ZC-vonSh.js} +0 -0
- /package/dist/web/assets/{typespec-DdOFo7M5.js → typespec-DkCEO45F.js} +0 -0
- /package/dist/web/assets/{typst-LYvnBWQu.js → typst-DAZdb2n6.js} +0 -0
- /package/dist/web/assets/{utils-CTg5uAYR.js → utils-CSCvNZxE.js} +0 -0
- /package/dist/web/assets/{v-BuBYA1_x.js → v-B_wsb4C1.js} +0 -0
- /package/dist/web/assets/{vala-vRIBYYe3.js → vala-BDBNS784.js} +0 -0
- /package/dist/web/assets/{vb-DwGi-IYM.js → vb-CuOoJSSa.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-i6SHFTfU.js → vendor-xterm-CImj6i6Z.js} +0 -0
- /package/dist/web/assets/{verilog-6B1X4G2-.js → verilog-BCcOvOcc.js} +0 -0
- /package/dist/web/assets/{vesper-Dw1y_Ae7.js → vesper-vN8CREK5.js} +0 -0
- /package/dist/web/assets/{vhdl-DK8JwBzJ.js → vhdl-CI8PoqeM.js} +0 -0
- /package/dist/web/assets/{viml-BTKIEIqm.js → viml-B66dNP1B.js} +0 -0
- /package/dist/web/assets/{vitesse-black-BqqolhEg.js → vitesse-black-0bGIaCfD.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-B9JL5WQA.js → vitesse-dark-Dk-RSXq-.js} +0 -0
- /package/dist/web/assets/{vitesse-light-DYJKj2se.js → vitesse-light-BUsA5RhG.js} +0 -0
- /package/dist/web/assets/{vyper-D-jDI3WH.js → vyper-dNodzEa8.js} +0 -0
- /package/dist/web/assets/{wasm-1-GlNdpk.js → wasm-BDxaNPCj.js} +0 -0
- /package/dist/web/assets/{wasm-BBW4WmT2.js → wasm-d6SE2_qm.js} +0 -0
- /package/dist/web/assets/{wenyan-B6cM7sDO.js → wenyan-D0h8Uz55.js} +0 -0
- /package/dist/web/assets/{wgsl-FaHGQgko.js → wgsl-vKs_vsvQ.js} +0 -0
- /package/dist/web/assets/{wikitext-DtIyPUrk.js → wikitext-BIWsPJit.js} +0 -0
- /package/dist/web/assets/{wit-BMVRif5Y.js → wit-6vmKi2H3.js} +0 -0
- /package/dist/web/assets/{wolfram-DQsCGohn.js → wolfram-zoNg6F1a.js} +0 -0
- /package/dist/web/assets/{x-C2VSAp7O.js → x-BsFLg-T8.js} +0 -0
- /package/dist/web/assets/{yaml-C-Va56Gt.js → yaml-W95qP6-B.js} +0 -0
- /package/dist/web/assets/{zenscript-DdobKGI-.js → zenscript-BxircxDx.js} +0 -0
- /package/dist/web/assets/{zig-vqDFwj6q.js → zig-DD79WQtz.js} +0 -0
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
# PPM Extension Development Guide
|
|
2
|
+
|
|
3
|
+
Build extensions that add features to PPM. Extensions are TypeScript packages that hook into PPM's UI, commands, file system, and configuration.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Extension Basics
|
|
8
|
+
|
|
9
|
+
### Structure
|
|
10
|
+
|
|
11
|
+
A PPM extension is a directory with `package.json` manifest and TypeScript entry point:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
my-extension/
|
|
15
|
+
├── package.json
|
|
16
|
+
├── tsconfig.json
|
|
17
|
+
├── src/
|
|
18
|
+
│ └── extension.ts # Entry point with activate() & deactivate()
|
|
19
|
+
├── webview/ # Optional: webview HTML/CSS/JS
|
|
20
|
+
│ └── index.html
|
|
21
|
+
└── README.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Manifest (package.json)
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"name": "@org/ext-myfeature",
|
|
29
|
+
"version": "1.0.0",
|
|
30
|
+
"main": "src/extension.ts",
|
|
31
|
+
"engines": { "ppm": ">=0.9.0" },
|
|
32
|
+
"activationEvents": [
|
|
33
|
+
"onCommand:myext.doSomething",
|
|
34
|
+
"onView:myext.sidebar"
|
|
35
|
+
],
|
|
36
|
+
"contributes": {
|
|
37
|
+
"commands": [
|
|
38
|
+
{ "command": "myext.doSomething", "title": "My Feature: Do Something" }
|
|
39
|
+
],
|
|
40
|
+
"views": {
|
|
41
|
+
"sidebar": [
|
|
42
|
+
{ "id": "myext.sidebar", "name": "My Sidebar", "type": "tree" }
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"menus": {
|
|
46
|
+
"commandPalette": [
|
|
47
|
+
{ "command": "myext.doSomething" }
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
"configuration": {
|
|
51
|
+
"properties": {
|
|
52
|
+
"myext.setting": { "type": "boolean", "default": true }
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"ppm": {
|
|
57
|
+
"displayName": "My Feature",
|
|
58
|
+
"icon": "star",
|
|
59
|
+
"webviewDir": "webview"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Key fields:**
|
|
65
|
+
- `main` — TypeScript file with `export function activate(context, vscode) {}`
|
|
66
|
+
- `engines.ppm` — minimum PPM version (not `vscode`)
|
|
67
|
+
- `activationEvents` — when extension loads (commands, views, or startup)
|
|
68
|
+
- `contributes` — UI elements: commands, views, menus, config
|
|
69
|
+
- `ppm.displayName` — human-readable name in extension UI
|
|
70
|
+
- `ppm.icon` — icon name (standard VSCode icon set)
|
|
71
|
+
- `ppm.webviewDir` — directory containing webview HTML
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Activation & Lifecycle
|
|
76
|
+
|
|
77
|
+
Extensions run in an isolated Bun Worker thread. The Worker receives `context` and `vscode` API:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
/** Runs when activation event fires */
|
|
81
|
+
export function activate(context: ExtensionContext, vscode: VscodeApi): void {
|
|
82
|
+
console.log("Extension activated");
|
|
83
|
+
|
|
84
|
+
// Register commands, listeners, views, etc.
|
|
85
|
+
context.subscriptions.push(
|
|
86
|
+
vscode.commands.registerCommand("myext.foo", () => {
|
|
87
|
+
// ...
|
|
88
|
+
})
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Cleanup on disable/uninstall */
|
|
93
|
+
export function deactivate(): void {
|
|
94
|
+
console.log("Extension deactivated");
|
|
95
|
+
// Browser/streams are auto-closed; use this for final logging
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Important:** Push ALL disposables (commands, listeners, panels, views) to `context.subscriptions` for automatic cleanup.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## API Surface
|
|
104
|
+
|
|
105
|
+
### Commands
|
|
106
|
+
|
|
107
|
+
Register and execute commands:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
// Register
|
|
111
|
+
const cmd = vscode.commands.registerCommand("myext.foo", (arg1, arg2) => {
|
|
112
|
+
return "result";
|
|
113
|
+
});
|
|
114
|
+
context.subscriptions.push(cmd);
|
|
115
|
+
|
|
116
|
+
// Execute (from command palette or button click)
|
|
117
|
+
// vscode.commands.executeCommand("myext.foo", arg1, arg2);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Messages (Dialogs)
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Information
|
|
124
|
+
await vscode.window.showInformationMessage("Done!", "OK", "Cancel");
|
|
125
|
+
|
|
126
|
+
// Warning
|
|
127
|
+
await vscode.window.showWarningMessage("Are you sure?", "Yes", "No");
|
|
128
|
+
|
|
129
|
+
// Error
|
|
130
|
+
await vscode.window.showErrorMessage("Failed!", "Retry");
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Quick Pick
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
const selected = await vscode.window.showQuickPick(
|
|
137
|
+
[
|
|
138
|
+
{ label: "Option A", description: "First choice" },
|
|
139
|
+
{ label: "Option B", description: "Second choice" }
|
|
140
|
+
],
|
|
141
|
+
{
|
|
142
|
+
title: "Choose one",
|
|
143
|
+
placeHolder: "Start typing to filter...",
|
|
144
|
+
canPickMany: false,
|
|
145
|
+
matchOnDescription: true
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Input Box
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const input = await vscode.window.showInputBox({
|
|
154
|
+
title: "Enter name",
|
|
155
|
+
prompt: "What is your name?",
|
|
156
|
+
placeHolder: "John Doe",
|
|
157
|
+
password: false
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Status Bar
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
const item = vscode.window.createStatusBarItem(
|
|
165
|
+
vscode.StatusBarAlignment.Right,
|
|
166
|
+
100 // priority
|
|
167
|
+
);
|
|
168
|
+
item.text = "⚙️ Status";
|
|
169
|
+
item.tooltip = "Click for menu";
|
|
170
|
+
item.command = "myext.openMenu";
|
|
171
|
+
item.show();
|
|
172
|
+
context.subscriptions.push(item);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Tree View
|
|
176
|
+
|
|
177
|
+
Sidebar tree for displaying hierarchical data:
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
class MyTreeProvider {
|
|
181
|
+
getChildren(element?: NodeData): Promise<NodeData[]> {
|
|
182
|
+
if (!element) {
|
|
183
|
+
// Root items
|
|
184
|
+
return [
|
|
185
|
+
{ id: "1", label: "Item 1" },
|
|
186
|
+
{ id: "2", label: "Item 2" }
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
// Children of element
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
getTreeItem(element: NodeData) {
|
|
194
|
+
return {
|
|
195
|
+
id: element.id,
|
|
196
|
+
label: element.label,
|
|
197
|
+
collapsibleState: element.children?.length ?
|
|
198
|
+
vscode.TreeItemCollapsibleState.Collapsed :
|
|
199
|
+
vscode.TreeItemCollapsibleState.None,
|
|
200
|
+
command: { command: "myext.selectNode", arguments: [element.id] }
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const provider = new MyTreeProvider();
|
|
206
|
+
const tree = vscode.window.createTreeView("myext.tree", {
|
|
207
|
+
treeDataProvider: provider
|
|
208
|
+
});
|
|
209
|
+
context.subscriptions.push(tree);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**viewId** must match the `contributes.views[].id` in package.json.
|
|
213
|
+
|
|
214
|
+
### Webview Panel
|
|
215
|
+
|
|
216
|
+
Sandboxed iframe for custom UI:
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
const panel = vscode.window.createWebviewPanel(
|
|
220
|
+
"myext.panel", // viewType (unique)
|
|
221
|
+
"My Panel", // title (shown in tab)
|
|
222
|
+
vscode.ViewColumn.Active
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Set HTML (scripts auto-sandboxed, allow-scripts only)
|
|
226
|
+
panel.webview.html = `
|
|
227
|
+
<!DOCTYPE html>
|
|
228
|
+
<html>
|
|
229
|
+
<body>
|
|
230
|
+
<button id="btn">Click me</button>
|
|
231
|
+
<script>
|
|
232
|
+
const vscode = acquireVsCodeApi();
|
|
233
|
+
document.getElementById("btn").onclick = () => {
|
|
234
|
+
vscode.postMessage({ type: "buttonClicked" });
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
window.addEventListener("message", (e) => {
|
|
238
|
+
console.log("From extension:", e.data);
|
|
239
|
+
});
|
|
240
|
+
</script>
|
|
241
|
+
</body>
|
|
242
|
+
</html>
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
// Receive messages from webview
|
|
246
|
+
panel.webview.onDidReceiveMessage(async (msg) => {
|
|
247
|
+
if (msg.type === "buttonClicked") {
|
|
248
|
+
await vscode.window.showInformationMessage("Button clicked!");
|
|
249
|
+
await panel.webview.postMessage({ type: "response", data: "Hello from extension" });
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
context.subscriptions.push(panel.onDidDispose(() => {
|
|
254
|
+
console.log("Panel closed");
|
|
255
|
+
}));
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Configuration
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// Read
|
|
262
|
+
const config = vscode.workspace.getConfiguration("myext");
|
|
263
|
+
const timeout = config.get<number>("timeout", 5000);
|
|
264
|
+
|
|
265
|
+
// Update
|
|
266
|
+
await config.update("timeout", 10000, vscode.ConfigurationTarget.Global);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### Storage (Memento)
|
|
270
|
+
|
|
271
|
+
Persist data across sessions:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// Global (user-wide)
|
|
275
|
+
await context.globalState.update("key", { foo: "bar" });
|
|
276
|
+
const value = context.globalState.get("key");
|
|
277
|
+
|
|
278
|
+
// Workspace-scoped
|
|
279
|
+
await context.workspaceState.update("project", "data");
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Process Spawning (Subprocess Execution)
|
|
283
|
+
|
|
284
|
+
Extensions needing to run external commands use the RPC `process:spawn` handler. This is essential for extensions that interact with CLIs (git, docker, node, etc.).
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
// Inside your extension (via RPC)
|
|
288
|
+
const rpc = (context as any).rpc;
|
|
289
|
+
|
|
290
|
+
const result = await rpc.request("process:spawn", [
|
|
291
|
+
"git", // command (must be in allowlist)
|
|
292
|
+
["log", "--oneline", "-n", "10"], // args array
|
|
293
|
+
{ cwd: process.cwd() } // options: { cwd?: string, timeout?: number }
|
|
294
|
+
]);
|
|
295
|
+
|
|
296
|
+
// Result structure
|
|
297
|
+
if (!result.error) {
|
|
298
|
+
const { code, stdout, stderr } = result;
|
|
299
|
+
console.log("Exit code:", code);
|
|
300
|
+
console.log("Output:", stdout);
|
|
301
|
+
} else {
|
|
302
|
+
console.error("Command failed:", result.error);
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Allowed Commands** (security allowlist):
|
|
307
|
+
- `git` — Version control operations
|
|
308
|
+
- `node`, `bun` — JavaScript runtimes
|
|
309
|
+
- `npm`, `yarn`, `pnpm` — Package managers
|
|
310
|
+
- `docker` — Container operations
|
|
311
|
+
- `psql` — PostgreSQL CLI
|
|
312
|
+
- `sqlite3` — SQLite CLI
|
|
313
|
+
- `python3`, `python` — Python runtime
|
|
314
|
+
|
|
315
|
+
**Restrictions:**
|
|
316
|
+
- CWD limited to current project root (no path escaping)
|
|
317
|
+
- 30-second timeout by default
|
|
318
|
+
- Stdout/stderr captured as strings
|
|
319
|
+
- Non-zero exit codes returned as error
|
|
320
|
+
|
|
321
|
+
**Example: Git Graph Extension**
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
// In ext-git-graph, spawn git to fetch log
|
|
325
|
+
export async function activate(context: ExtensionContext, vscode: any) {
|
|
326
|
+
const rpc = (context as any).rpc;
|
|
327
|
+
|
|
328
|
+
context.subscriptions.push(
|
|
329
|
+
vscode.commands.registerCommand("git-graph.view", async () => {
|
|
330
|
+
try {
|
|
331
|
+
const result = await rpc.request("process:spawn", [
|
|
332
|
+
"git",
|
|
333
|
+
["log", "--all", "--oneline", "--graph"],
|
|
334
|
+
{ cwd: process.cwd() }
|
|
335
|
+
]);
|
|
336
|
+
|
|
337
|
+
if (result.error) {
|
|
338
|
+
await vscode.window.showErrorMessage(`Git error: ${result.error}`);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Parse result.stdout and render graph in webview
|
|
343
|
+
const commits = parseGitLog(result.stdout);
|
|
344
|
+
const panel = vscode.window.createWebviewPanel("git-graph", "Git Graph", vscode.ViewColumn.Active);
|
|
345
|
+
panel.webview.html = renderSvgGraph(commits);
|
|
346
|
+
} catch (e) {
|
|
347
|
+
await vscode.window.showErrorMessage(`Failed to load git graph: ${e}`);
|
|
348
|
+
}
|
|
349
|
+
})
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### Utilities
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
// URI
|
|
358
|
+
const uri = vscode.Uri.file("/path/to/file");
|
|
359
|
+
const webUri = panel.webview.asWebviewUri(uri);
|
|
360
|
+
|
|
361
|
+
// Disposable
|
|
362
|
+
const disposable = vscode.Disposable.from(
|
|
363
|
+
vscode.commands.registerCommand("a", () => {}),
|
|
364
|
+
vscode.commands.registerCommand("b", () => {})
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
// EventEmitter
|
|
368
|
+
const emitter = new vscode.EventEmitter<string>();
|
|
369
|
+
emitter.fire("event data"); // Notify listeners
|
|
370
|
+
// const unsub = emitter.event((data) => {});
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## API Support Matrix
|
|
376
|
+
|
|
377
|
+
| Feature | Status | Notes |
|
|
378
|
+
|---------|--------|-------|
|
|
379
|
+
| **Commands** | ✅ Supported | `registerCommand`, `executeCommand` |
|
|
380
|
+
| **Messages** | ✅ Supported | Info, warning, error dialogs |
|
|
381
|
+
| **Quick Pick** | ✅ Supported | Single/multi-select, filtering |
|
|
382
|
+
| **Input Box** | ✅ Supported | Text input with validation (client-side) |
|
|
383
|
+
| **Status Bar** | ✅ Supported | Left/right alignment, priority, commands |
|
|
384
|
+
| **Tree View** | ✅ Supported | Hierarchical sidebar trees |
|
|
385
|
+
| **Webview Panel** | ✅ Supported | Sandboxed iframe, 2-way messaging |
|
|
386
|
+
| **Workspace Config** | ✅ Supported | Read/write user & workspace settings |
|
|
387
|
+
| **Workspace FS** | ⚠️ Partial | Read, write, stat, readDirectory (no watch) |
|
|
388
|
+
| **Process Spawn** | ✅ Supported | Run external commands (git, npm, etc.) |
|
|
389
|
+
| **Storage (Memento)** | ✅ Supported | Global & workspace state, auto-persisted |
|
|
390
|
+
| **Uri** | ✅ Supported | File/webview URI utilities |
|
|
391
|
+
| **EventEmitter** | ✅ Supported | Custom event streams |
|
|
392
|
+
| **Disposable** | ✅ Supported | Cleanup & resource management |
|
|
393
|
+
| **Environment** | ✅ Supported | App name, machine ID |
|
|
394
|
+
| **Languages** | ❌ Not supported | Syntax highlighting, language services |
|
|
395
|
+
| **Debug** | ❌ Not supported | Debugger integration |
|
|
396
|
+
| **Tasks** | ❌ Not supported | Task provider, task execution |
|
|
397
|
+
| **SCM** | ❌ Not supported | Source control providers |
|
|
398
|
+
| **Notebooks** | ❌ Not supported | Notebook editing |
|
|
399
|
+
| **Authentication** | ❌ Not supported | Auth provider, sessions |
|
|
400
|
+
| **Tests** | ❌ Not supported | Test controller |
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Webview Details
|
|
405
|
+
|
|
406
|
+
### Sandbox
|
|
407
|
+
|
|
408
|
+
Webviews run in a sandboxed iframe with **`allow-scripts` only** — no inline styles, event handlers, or external scripts. Use a bundler or inline `<style>` tags.
|
|
409
|
+
|
|
410
|
+
### Communication
|
|
411
|
+
|
|
412
|
+
**From webview to extension:**
|
|
413
|
+
```typescript
|
|
414
|
+
const vscode = acquireVsCodeApi();
|
|
415
|
+
vscode.postMessage({ type: "action", data: "..." });
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**From extension to webview:**
|
|
419
|
+
```typescript
|
|
420
|
+
panel.webview.postMessage({ type: "update", data: "..." });
|
|
421
|
+
panel.webview.onDidReceiveMessage((msg) => {
|
|
422
|
+
console.log("From webview:", msg);
|
|
423
|
+
});
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### HTML Setup
|
|
427
|
+
|
|
428
|
+
```html
|
|
429
|
+
<!DOCTYPE html>
|
|
430
|
+
<html>
|
|
431
|
+
<head>
|
|
432
|
+
<style>
|
|
433
|
+
body { font-family: sans-serif; padding: 20px; }
|
|
434
|
+
button { padding: 8px 16px; cursor: pointer; }
|
|
435
|
+
</style>
|
|
436
|
+
</head>
|
|
437
|
+
<body>
|
|
438
|
+
<h1>My Webview</h1>
|
|
439
|
+
<button id="btn">Send Message</button>
|
|
440
|
+
|
|
441
|
+
<script>
|
|
442
|
+
const vscode = acquireVsCodeApi();
|
|
443
|
+
|
|
444
|
+
document.getElementById("btn").onclick = () => {
|
|
445
|
+
vscode.postMessage({ type: "click", time: Date.now() });
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
window.addEventListener("message", (e) => {
|
|
449
|
+
const { type, data } = e.data;
|
|
450
|
+
if (type === "update") {
|
|
451
|
+
document.body.innerHTML += `<p>${data}</p>`;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
</script>
|
|
455
|
+
</body>
|
|
456
|
+
</html>
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
## Porting from VSCode
|
|
462
|
+
|
|
463
|
+
PPM uses the same API shape as VSCode. Porting is straightforward:
|
|
464
|
+
|
|
465
|
+
### 1. Update imports
|
|
466
|
+
|
|
467
|
+
**Before (VSCode):**
|
|
468
|
+
```typescript
|
|
469
|
+
import * as vscode from "vscode";
|
|
470
|
+
|
|
471
|
+
export function activate(context: vscode.ExtensionContext) {
|
|
472
|
+
// ...
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
**After (PPM):**
|
|
477
|
+
```typescript
|
|
478
|
+
import type { ExtensionContext } from "@ppm/vscode-compat";
|
|
479
|
+
|
|
480
|
+
export function activate(context: ExtensionContext, vscode: any) {
|
|
481
|
+
// vscode is passed as 2nd argument
|
|
482
|
+
// ...
|
|
483
|
+
}
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Or import for type checking:
|
|
487
|
+
```typescript
|
|
488
|
+
import * as vscode from "@ppm/vscode-compat";
|
|
489
|
+
|
|
490
|
+
export function activate(context: ExtensionContext, _vscode: typeof vscode) {
|
|
491
|
+
// ...
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 2. Update package.json
|
|
496
|
+
|
|
497
|
+
```json
|
|
498
|
+
{
|
|
499
|
+
"engines": { "ppm": ">=0.9.0" } // was vscode
|
|
500
|
+
}
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### 3. Check API support
|
|
504
|
+
|
|
505
|
+
Verify unsupported features aren't used (see API Support Matrix above).
|
|
506
|
+
|
|
507
|
+
### 4. Test
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
ppm ext dev ./path/to/extension
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## Examples
|
|
516
|
+
|
|
517
|
+
### Database Viewer
|
|
518
|
+
|
|
519
|
+
See `packages/ext-database/` in the PPM repo for a complete reference extension:
|
|
520
|
+
|
|
521
|
+
- **Tree view** of database connections
|
|
522
|
+
- **Commands** to open query panel
|
|
523
|
+
- **Webview panel** for SQL editor
|
|
524
|
+
- **Status bar** icon
|
|
525
|
+
- **Configuration** (maxRows, autoConnect)
|
|
526
|
+
- **RPC to backend** for queries
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
export function activate(context: ExtensionContext, vscode: any) {
|
|
530
|
+
// Tree view
|
|
531
|
+
const provider = new ConnectionTreeProvider();
|
|
532
|
+
const tree = vscode.window.createTreeView("ppm-db.connections", {
|
|
533
|
+
treeDataProvider: provider
|
|
534
|
+
});
|
|
535
|
+
context.subscriptions.push(tree);
|
|
536
|
+
|
|
537
|
+
// Command
|
|
538
|
+
context.subscriptions.push(
|
|
539
|
+
vscode.commands.registerCommand("ppm-db.openViewer", (connId) => {
|
|
540
|
+
const panel = vscode.window.createWebviewPanel(
|
|
541
|
+
"ppm-db.query",
|
|
542
|
+
"Query",
|
|
543
|
+
vscode.ViewColumn.Active
|
|
544
|
+
);
|
|
545
|
+
panel.webview.html = `...`;
|
|
546
|
+
panel.webview.onDidReceiveMessage(async (msg) => {
|
|
547
|
+
if (msg.type === "query") {
|
|
548
|
+
const res = await fetch(`/api/db/${connId}/query`, {
|
|
549
|
+
method: "POST",
|
|
550
|
+
body: JSON.stringify({ sql: msg.sql })
|
|
551
|
+
});
|
|
552
|
+
await panel.webview.postMessage(await res.json());
|
|
553
|
+
}
|
|
554
|
+
});
|
|
555
|
+
})
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
// Status bar
|
|
559
|
+
const status = vscode.window.createStatusBarItem(
|
|
560
|
+
vscode.StatusBarAlignment.Right
|
|
561
|
+
);
|
|
562
|
+
status.text = "DB";
|
|
563
|
+
status.show();
|
|
564
|
+
context.subscriptions.push(status);
|
|
565
|
+
}
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Git Graph
|
|
569
|
+
|
|
570
|
+
See `packages/ext-git-graph/` for an extension using **process:spawn** to run git commands:
|
|
571
|
+
|
|
572
|
+
- **Process spawning** via RPC to execute `git log` across any registered project
|
|
573
|
+
- **SVG graph rendering** faithful port of vscode-git-graph algorithm:
|
|
574
|
+
- Single SVG overlay with continuous branch paths (Bézier curves)
|
|
575
|
+
- Shadow lines for visual depth
|
|
576
|
+
- HEAD and stash node indicators
|
|
577
|
+
- Color-coded column tracking for branch visualization
|
|
578
|
+
- **Webview panel** for interactive visualization with scrolling commit list
|
|
579
|
+
- **Commit details** panel with author, date, message, and file changes
|
|
580
|
+
- **Context menu** for actions (checkout, cherry-pick, etc.)
|
|
581
|
+
- **Search/find** widget with navigation within the graph
|
|
582
|
+
|
|
583
|
+
Key patterns:
|
|
584
|
+
- Use `process:spawn` RPC to safely run git commands from any registered project root
|
|
585
|
+
- Parse git log output and compute graph coordinates (row, column, edge routing)
|
|
586
|
+
- Render single SVG overlay synchronized with commit list rows
|
|
587
|
+
- Implement custom graph rendering algorithm (path computation, Bézier curves, node placement)
|
|
588
|
+
- Two-way messaging between extension and webview for interactions and detail panel updates
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
## Best Practices
|
|
593
|
+
|
|
594
|
+
1. **Cleanup**: Always push disposables to `context.subscriptions`.
|
|
595
|
+
2. **Errors**: Catch and show errors via `showErrorMessage()`.
|
|
596
|
+
3. **Async**: Use `await` for RPC calls; block UI during long operations.
|
|
597
|
+
4. **Storage**: Use `Memento` for persistence, not file system (unless granted access).
|
|
598
|
+
5. **Webview Security**: Never use `eval()`, `innerHTML` with user input, or external CDNs.
|
|
599
|
+
6. **Activation**: Lazy-load expensive code via activation events, not on require.
|
|
600
|
+
7. **Testing**: Use `ppm ext dev` to load locally before publishing.
|
|
601
|
+
|
|
602
|
+
---
|
|
603
|
+
|
|
604
|
+
## Publishing
|
|
605
|
+
|
|
606
|
+
Register your extension with PPM's extension registry (coming in v0.9). For now, distribute via npm or GitHub.
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
## Troubleshooting
|
|
611
|
+
|
|
612
|
+
| Issue | Solution |
|
|
613
|
+
|-------|----------|
|
|
614
|
+
| Extension doesn't activate | Check `activationEvents` in package.json matches your commands/views |
|
|
615
|
+
| Command not found | Verify `contributes.commands[].command` id |
|
|
616
|
+
| Tree view empty | Implement `getChildren()` and `getTreeItem()` in provider |
|
|
617
|
+
| Webview blank | Check `panel.webview.html` is valid HTML; test in browser first |
|
|
618
|
+
| RPC timeout | Network issue or long-running request; add retry logic |
|
|
619
|
+
| Storage not persisted | Use `Memento.update()`, not local variables |
|
|
620
|
+
| Unsupported API error | Check API Support Matrix; file issue if critical |
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## Learn More
|
|
625
|
+
|
|
626
|
+
- [VSCode Extension API](https://code.visualstudio.com/api) — reference (PPM subset)
|
|
627
|
+
- `packages/ext-database/` — working example
|
|
628
|
+
- `packages/vscode-compat/src/` — API implementation
|
|
629
|
+
- GitHub issues — feature requests & bugs
|