@hienlh/ppm 0.20.5 → 0.20.7
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 +16 -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/dist/web/assets/{accounts-settings-section-Cmmozwer.js → accounts-settings-section-Df1KoGg7.js} +1 -1
- package/dist/web/assets/{ai-resource-editor-BlrWV3xU.js → ai-resource-editor-C6s6A57b.js} +1 -1
- package/dist/web/assets/ai-settings-section-BQTsEJzp.js +1 -0
- package/dist/web/assets/{ai-settings-section-dDsgddSt.js → ai-settings-section-CMIkIxZU.js} +1 -1
- package/dist/web/assets/{angular-html-BtJLNcMw.js → angular-html-K0aKyuHe.js} +1 -1
- package/dist/web/assets/{angular-ts-CQiu5F_W.js → angular-ts-CLY0DVNM.js} +1 -1
- package/dist/web/assets/{apl-CKZvgs-w.js → apl-Cl1oeOZc.js} +1 -1
- package/dist/web/assets/{appearance-settings-section-DRxziHFt.js → appearance-settings-section-B7CwHA7Y.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-CkWx_Sv3.js +1 -0
- package/dist/web/assets/{astro-D0b8ssLD.js → astro-S8gLldib.js} +1 -1
- package/dist/web/assets/{audio-preview-B4E5_7TW.js → audio-preview-C2PCzvr5.js} +1 -1
- package/dist/web/assets/{blade-DOIpINLw.js → blade-DZ96Anzi.js} +1 -1
- package/dist/web/assets/{bsl-CJ7_JlQ8.js → bsl-BrlZLefQ.js} +1 -1
- package/dist/web/assets/{cairo-5CpV2T1P.js → cairo-B0UdH8CG.js} +1 -1
- package/dist/web/assets/chat-tab-BJokwok-.js +15 -0
- package/dist/web/assets/click-outside-container-XmmmdSm7.js +1 -0
- package/dist/web/assets/{cobol-BreMVrtc.js → cobol-DCeQgIC6.js} +1 -1
- package/dist/web/assets/code-editor-BVyFjaoM.js +7 -0
- package/dist/web/assets/{coffee-D7DoKh5b.js → coffee-D3V0ISG7.js} +1 -1
- package/dist/web/assets/{conflict-editor-D9_sr59D.js → conflict-editor-hGsVMmtG.js} +1 -1
- package/dist/web/assets/{cpp-BnWeWAoE.js → cpp-UPgqRL5h.js} +1 -1
- package/dist/web/assets/{crystal-D2pJbFUn.js → crystal-B7BOJUR4.js} +1 -1
- package/dist/web/assets/{csv-preview-BMC8jnpF.js → csv-preview-DiSiq6UJ.js} +1 -1
- package/dist/web/assets/data-grid-overlay-editor-QyH_oklj.js +1 -0
- package/dist/web/assets/database-viewer-BWQMTwjf.js +1 -0
- package/dist/web/assets/{diff-viewer-B4PlZ1Dt.js → diff-viewer-Usuuf35X.js} +1 -1
- package/dist/web/assets/dist-CQbltjRp.js +11 -0
- package/dist/web/assets/{edge-aqGMtbY3.js → edge-Dw-s4XKj.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-xdDQvPhs.js → edit-diff-preview-F7YlT9fY.js} +1 -1
- package/dist/web/assets/{elixir-CsYMBLc5.js → elixir-Dntyzyed.js} +1 -1
- package/dist/web/assets/{elm-BU8C2gFp.js → elm-C83eppJ0.js} +1 -1
- package/dist/web/assets/{erb-Z_E49ab8.js → erb-Bjv2Lozz.js} +1 -1
- package/dist/web/assets/{erlang-BRqOjXH9.js → erlang-5PAcE8_t.js} +1 -1
- package/dist/web/assets/esm-Brdy2Atb.js +2 -0
- package/dist/web/assets/{explorer-body-SvWDS84f.js → explorer-body-BL9hg1yr.js} +1 -1
- package/dist/web/assets/{explorer-window-content-DBHBTA7B.js → explorer-window-content-C3BSd4Qf.js} +1 -1
- package/dist/web/assets/{extension-manager-section-BSt5I_H8.js → extension-manager-section-CE0aB9ed.js} +1 -1
- package/dist/web/assets/{extension-webview-DBGMUU97.js → extension-webview-CGhuot2v.js} +1 -1
- package/dist/web/assets/{files-settings-section-0dwYLZou.js → files-settings-section-D_sgDKwF.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-CWbxmDGR.js → fortran-fixed-form-Di9Yw_ao.js} +1 -1
- package/dist/web/assets/{fsharp-DKMYbq6I.js → fsharp-IRAdAkHt.js} +1 -1
- package/dist/web/assets/{gdresource-B3yFau4V.js → gdresource-DVdwnvP-.js} +1 -1
- package/dist/web/assets/{general-settings-section-BgLy_6yj.js → general-settings-section-D7DMjoNj.js} +1 -1
- package/dist/web/assets/{git-commit-BW0p3Ekk.js → git-commit-CD6jLHvg.js} +1 -1
- package/dist/web/assets/{git-log-panel-BkgmcWk1.js → git-log-panel-prL5-n-F.js} +1 -1
- package/dist/web/assets/{git-rebase-DrvmQCS7.js → git-rebase-DvxNkg7t.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BUlbZgyf.js +1 -0
- package/dist/web/assets/glide-data-grid-lbUFJwCD.js +141 -0
- package/dist/web/assets/{glimmer-js-BY1XApJJ.js → glimmer-js-aM9jbY2M.js} +1 -1
- package/dist/web/assets/{glimmer-ts-DPZtxF8N.js → glimmer-ts-Bd4jKeuF.js} +1 -1
- package/dist/web/assets/{glsl-DZ8G_Hvf.js → glsl-CUUtWNTx.js} +1 -1
- package/dist/web/assets/{graphql-Ck06uCZy.js → graphql-DkY6xCcc.js} +1 -1
- package/dist/web/assets/{group-chat-tab-Cy9zIynj.js → group-chat-tab-C4oY3IKi.js} +1 -1
- package/dist/web/assets/{hack-pLogDwAs.js → hack-DnaR9DJk.js} +1 -1
- package/dist/web/assets/{haml-CBqeCQ2A.js → haml-BDubxAIK.js} +1 -1
- package/dist/web/assets/{handlebars-B66JmVtp.js → handlebars-OxsbI1gt.js} +1 -1
- package/dist/web/assets/{html-Dk4wmfwC.js → html-Cjiwd8dp.js} +1 -1
- package/dist/web/assets/{html-derivative-CJWqfN51.js → html-derivative-CfzXt9Cs.js} +1 -1
- package/dist/web/assets/{http-CexhotTh.js → http-DRF6Wp6Y.js} +1 -1
- package/dist/web/assets/{hurl-BScKFk3Z.js → hurl-6SunVID_.js} +1 -1
- package/dist/web/assets/{hxml-DAle7vtu.js → hxml-CR72N708.js} +1 -1
- package/dist/web/assets/{image-preview-fuU4h2nr.js → image-preview-C7dCEQCx.js} +1 -1
- package/dist/web/assets/{index-DYGLdCpe.js → index-A3ripVe5.js} +6 -6
- package/dist/web/assets/{index-CuYtJ5xF.css → index-B9Wbjl0o.css} +1 -1
- package/dist/web/assets/info-3K5VOQVL-DXzjBxZf.js +1 -0
- package/dist/web/assets/{jinja-yHpyD80t.js → jinja-CYjAWnk3.js} +1 -1
- package/dist/web/assets/{jira-watcher-section-DRQx632s.js → jira-watcher-section-DvKEiqtb.js} +1 -1
- package/dist/web/assets/{jison-BY6WLJVu.js → jison-UERnq4ds.js} +1 -1
- package/dist/web/assets/{julia-Dd_iYQDT.js → julia-WAZzVFSs.js} +1 -1
- package/dist/web/assets/{just-BTuUKpxF.js → just-B1YYfl1D.js} +1 -1
- package/dist/web/assets/{keybindings-store-C2HZ1mT4.js → keybindings-store-BOJPwIOB.js} +1 -1
- package/dist/web/assets/{keyboard-shortcuts-section-WiZSZ-Wr.js → keyboard-shortcuts-section-CPsFUned.js} +1 -1
- package/dist/web/assets/{latex-Dt3OUlMZ.js → latex-B6zwM9GI.js} +1 -1
- package/dist/web/assets/{liquid-BxPJU2ix.js → liquid-n4OK-yxz.js} +1 -1
- package/dist/web/assets/{lua-DEGIvn7d.js → lua-DJYn-zFg.js} +1 -1
- package/dist/web/assets/{markdown-renderer-BFYBVcZP.js → markdown-renderer-C1KVXiXr.js} +3 -3
- package/dist/web/assets/{markdown-renderer-CklcWnd6.js → markdown-renderer-HPQE8ilD.js} +1 -1
- package/dist/web/assets/{marko-BDxwBJur.js → marko-C27Qtq0P.js} +1 -1
- package/dist/web/assets/{mdc-B8aXPTg7.js → mdc-CypKG7qW.js} +1 -1
- package/dist/web/assets/{mobile-explorer-sheet-D1OXw7op.js → mobile-explorer-sheet-DkvtLBgs.js} +1 -1
- package/dist/web/assets/{nextflow-DBVZnnT_.js → nextflow-DuRHA0PY.js} +1 -1
- package/dist/web/assets/{nginx-Crpyd-Do.js → nginx-vxFTb1fh.js} +1 -1
- package/dist/web/assets/{nim-BSqTBYDj.js → nim-ChQDNOKe.js} +1 -1
- package/dist/web/assets/{notification-store-DyKshGRs.js → notification-store-B1pBUO0W.js} +1 -1
- package/dist/web/assets/{notifications-settings-section-BEQEjvan.js → notifications-settings-section-CaQVTa3a.js} +1 -1
- package/dist/web/assets/{number-overlay-editor-DRjTIcPH.js → number-overlay-editor-HmOZ3ETg.js} +1 -1
- package/dist/web/assets/{overview-panel-DiiA3B_Z.js → overview-panel-CaU5AtCB.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-DrX3I-bv.js +1 -0
- package/dist/web/assets/{pdf-preview-DmQazeeV.js → pdf-preview-QeXX_VpL.js} +1 -1
- package/dist/web/assets/{perl-BU0kbB-K.js → perl-BKH-mNmF.js} +1 -1
- package/dist/web/assets/{php-D9n1ikHN.js → php-W3oWF62o.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-czhViDrP.js +1 -0
- package/dist/web/assets/postgres-viewer-DO50GwMs.js +3 -0
- package/dist/web/assets/{ppmbot-settings-section-PzCLPm8a.js → ppmbot-settings-section-B_00Zb-K.js} +1 -1
- package/dist/web/assets/{process-table-C2TdkJck.js → process-table-DweR4FR3.js} +1 -1
- package/dist/web/assets/{proxy-settings-section-DsZ6KcHD.js → proxy-settings-section-sGhA3t_m.js} +1 -1
- package/dist/web/assets/{pug-BOpaczDr.js → pug-DscH2YvH.js} +1 -1
- package/dist/web/assets/{qml-B-cQXhrg.js → qml-CbBrfy74.js} +1 -1
- package/dist/web/assets/{query-audit-section-2eX9-6mO.js → query-audit-section-BtqND9WE.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-BAHP0n2V.js +1 -0
- package/dist/web/assets/{razor-DFB0pNCh.js → razor-_oKX4NEv.js} +1 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-DMn2uDXn.js +2 -0
- package/dist/web/assets/{remote-desktop-mobile-view-Bw6p5ikf.js → remote-desktop-mobile-view-xlO-gk_f.js} +1 -1
- package/dist/web/assets/{remote-desktop-readiness-gate-W0lAhHq9.js → remote-desktop-readiness-gate-BmyUd1vt.js} +1 -1
- package/dist/web/assets/{remote-desktop-window-content-P888YEqm.js → remote-desktop-window-content-BaPixhFs.js} +1 -1
- package/dist/web/assets/{rst-DAXedsgm.js → rst-C3yqfWYA.js} +1 -1
- package/dist/web/assets/{ruby-BCO4polC.js → ruby-BaanPyyv.js} +1 -1
- package/dist/web/assets/{sas-DfB5dcFC.js → sas-DQg1FY8E.js} +1 -1
- package/dist/web/assets/{schedules-settings-section-C8YDAxlo.js → schedules-settings-section-Ctu9STMV.js} +1 -1
- package/dist/web/assets/{scss-BknIVgn7.js → scss-N-LxVilh.js} +1 -1
- package/dist/web/assets/{settings-body-B5v3_Tnb.js → settings-body-B0ZdO6qx.js} +2 -2
- package/dist/web/assets/{settings-store-CzLnTR8p.js → settings-store-Bsu_5zIU.js} +2 -2
- package/dist/web/assets/settings-tab-BQvukPz5.js +1 -0
- package/dist/web/assets/{settings-window-content-BIosR7RY.js → settings-window-content-DUmULFsq.js} +1 -1
- package/dist/web/assets/{shaderlab-CPu31TpY.js → shaderlab-BShqbudx.js} +1 -1
- package/dist/web/assets/{shellsession-CFX4c_TM.js → shellsession-B8_nNEok.js} +1 -1
- package/dist/web/assets/{soy-rz9hilgm.js → soy-CW5oqa-M.js} +1 -1
- package/dist/web/assets/{sparql-Bo8ZDeqE.js → sparql-BJFHPosZ.js} +1 -1
- package/dist/web/assets/{sql-query-editor-DMihDPnw.js → sql-query-editor-DPtExW0C.js} +1 -1
- package/dist/web/assets/sqlite-viewer-DkzvIzyG.js +1 -0
- package/dist/web/assets/{stata-B5J-QMyE.js → stata-twP3WAnN.js} +1 -1
- package/dist/web/assets/{surrealql-Caw1ADnG.js → surrealql-CqwoQxwG.js} +1 -1
- package/dist/web/assets/{svelte-D3oMVcxz.js → svelte-CoTGkG7y.js} +1 -1
- package/dist/web/assets/{system-monitor-body-IUamfS5w.js → system-monitor-body-Bfx7yImc.js} +2 -2
- package/dist/web/assets/system-monitor-tab-Bn7sDAiO.js +1 -0
- package/dist/web/assets/{system-monitor-window-content-Bq3BS7Mg.js → system-monitor-window-content-DVwdAvly.js} +1 -1
- package/dist/web/assets/{tab-host-window-content-vfYLLIKU.js → tab-host-window-content-By35Ri11.js} +1 -1
- package/dist/web/assets/team-member-sheet-B8vZnJrJ.js +2 -0
- package/dist/web/assets/{team-member-window-content-D5cYZzBq.js → team-member-window-content-2_P22CXN.js} +1 -1
- package/dist/web/assets/{templ-BAdNyIOL.js → templ-BSuNrgD0.js} +1 -1
- package/dist/web/assets/{terminal-tab-C89DQllY.js → terminal-tab-DqAZMwhA.js} +1 -1
- package/dist/web/assets/{tex-IQ8mELOR.js → tex-DTdKTZSa.js} +1 -1
- package/dist/web/assets/{tool-cards-CWotDH_2.js → tool-cards-CiCZqw1w.js} +3 -3
- package/dist/web/assets/treemap-KZPCXAKY-DL_-JS7u.js +1 -0
- package/dist/web/assets/{ts-tags-D1DDO2jl.js → ts-tags-jpjff8fb.js} +1 -1
- package/dist/web/assets/{twig-C8Fd5RvV.js → twig-Utgjq3Am.js} +1 -1
- package/dist/web/assets/{use-accounts-data-lmmmG4ep.js → use-accounts-data-DMQAUXSO.js} +1 -1
- package/dist/web/assets/{use-monaco-theme-0ziS4xlp.js → use-monaco-theme-Ck1i7NEe.js} +1 -1
- package/dist/web/assets/{use-remote-desktop-display-choice-qBZ8ej7J.js → use-remote-desktop-display-choice-DVDOUQg2.js} +1 -1
- package/dist/web/assets/use-websocket-BkBvJbEt.js +1 -0
- package/dist/web/assets/{vendor-mermaid-CfY1-PkA.js → vendor-mermaid-CXxglerV.js} +193 -193
- package/dist/web/assets/{video-preview-B8xALVkh.js → video-preview-DzzFr0gI.js} +1 -1
- package/dist/web/assets/{vue-EvccXlkP.js → vue-CUms54DI.js} +1 -1
- package/dist/web/assets/{vue-html-Dg0xUJCh.js → vue-html-D7fbWTZW.js} +1 -1
- package/dist/web/assets/{vue-vine-BdrMg72k.js → vue-vine-BontZ1iR.js} +1 -1
- package/dist/web/assets/{xml-MmDclzxK.js → xml-CVHJ-Tda.js} +1 -1
- package/dist/web/assets/{xsl-DQEFs6Dd.js → xsl-BUDXwDuV.js} +1 -1
- package/dist/web/index.html +25 -25
- package/dist/web/sw.js +1 -1
- package/docs/architecture/ai-chat-and-providers.md +92 -0
- package/package.json +1 -1
- package/schemas/ppm-config.schema.json +18 -1
- package/src/providers/claude-agent-sdk.ts +21 -13
- package/src/providers/cli-provider-base.ts +3 -1
- package/src/providers/codex-app-server/codex-history.ts +5 -3
- package/src/providers/codex-app-server/codex-provider.ts +16 -2
- package/src/providers/codex-app-server/codex-rollout-header.ts +2 -1
- package/src/providers/cursor-cli/cursor-history.ts +4 -2
- package/src/server/routes/settings.ts +15 -1
- package/src/server/ws/chat.ts +2 -2
- package/src/services/chat.service.ts +95 -2
- package/src/services/codex-native-memory.ts +66 -0
- package/src/services/db.service.ts +18 -4
- package/src/services/jsonl-transcript-parser.ts +2 -1
- package/src/services/provider-shared-context.ts +152 -0
- package/src/shared/provider-context.ts +13 -0
- package/src/types/chat.ts +6 -0
- package/src/types/config.ts +29 -0
- package/src/web/components/chat/chat-history-bar.tsx +6 -3
- package/src/web/components/chat/chat-tab.tsx +7 -0
- package/src/web/components/settings/ai-settings-section.tsx +34 -5
- package/src/web/components/settings/codex-context-settings.tsx +100 -0
- package/src/web/hooks/use-chat.ts +75 -14
- package/src/web/hooks/use-websocket.ts +20 -7
- package/src/web/lib/api-settings.ts +3 -0
- package/src/web/lib/ws-client.ts +55 -4
- package/.release-bin/zip +0 -15
- package/.release-node-shim.sh +0 -11
- package/dist/web/assets/ai-settings-section-PaEh_o0w.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-DfR8k8Bc.js +0 -1
- package/dist/web/assets/chat-tab-MNuc18Os.js +0 -15
- package/dist/web/assets/code-editor-DYkmDRRF.js +0 -7
- package/dist/web/assets/data-grid-overlay-editor-CbBkhhJa.js +0 -1
- package/dist/web/assets/data-grid-types-DeY60CLU.js +0 -1
- package/dist/web/assets/database-viewer-Box3z5-Q.js +0 -1
- package/dist/web/assets/dist-BKOM_AoT.js +0 -11
- package/dist/web/assets/esm-B-vXxHUd.js +0 -2
- package/dist/web/assets/gitGraph-HDMCJU4V-CPd78aaT.js +0 -1
- package/dist/web/assets/glide-data-grid-CZVu-zCw.js +0 -141
- package/dist/web/assets/info-3K5VOQVL-BciNds6R.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-ClD3l2Bs.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-PU6kD0rW.js +0 -1
- package/dist/web/assets/postgres-viewer-Cd_wXjkT.js +0 -3
- package/dist/web/assets/radar-KQ55EAFF-4LzjL0Zt.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-CMXSUcAN.js +0 -2
- package/dist/web/assets/settings-tab-CauShulf.js +0 -1
- package/dist/web/assets/sqlite-viewer-jCIGt2GP.js +0 -1
- package/dist/web/assets/system-monitor-tab-DaWeif4k.js +0 -1
- package/dist/web/assets/team-member-sheet-Be7OSGMT.js +0 -2
- package/dist/web/assets/treemap-KZPCXAKY-DiumLNMg.js +0 -1
- package/dist/web/assets/use-websocket-DAvfbjxh.js +0 -1
- /package/dist/web/assets/{abap-D-o-bvtI.js → abap-BGbkXtK3.js} +0 -0
- /package/dist/web/assets/{actionscript-3-D2tIzAm8.js → actionscript-3-CTWUcAG5.js} +0 -0
- /package/dist/web/assets/{ada-DxatBcxS.js → ada-2xQ2Am_-.js} +0 -0
- /package/dist/web/assets/{andromeeda-D0LK9YJ3.js → andromeeda-DfXLrHKa.js} +0 -0
- /package/dist/web/assets/{apache-B7uMPNiW.js → apache-CBLZGsyo.js} +0 -0
- /package/dist/web/assets/{apex-B7GiXrAr.js → apex-UYnVUoc7.js} +0 -0
- /package/dist/web/assets/{api-settings-D18Q4Ocp.js → api-settings-ClKLkiR9.js} +0 -0
- /package/dist/web/assets/{api-themes-sSv-6OLk.js → api-themes-B_Za9tdP.js} +0 -0
- /package/dist/web/assets/{applescript-D_SIFkKe.js → applescript-9me9Xoqf.js} +0 -0
- /package/dist/web/assets/{ara-C3iECgdg.js → ara-CHhiJzie.js} +0 -0
- /package/dist/web/assets/{asciidoc-gc8z_MMY.js → asciidoc-CKk0H4sD.js} +0 -0
- /package/dist/web/assets/{asm-27qeoPOI.js → asm-CVc_SeQB.js} +0 -0
- /package/dist/web/assets/{aurora-x-C5J9fWe1.js → aurora-x-BRYBKvUk.js} +0 -0
- /package/dist/web/assets/{awk-B7GBzF92.js → awk-BsBtss7k.js} +0 -0
- /package/dist/web/assets/{ayu-dark-XlnQhuLL.js → ayu-dark-x3ChmRrr.js} +0 -0
- /package/dist/web/assets/{ayu-light-DKLLilkU.js → ayu-light-DUbhGec6.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-Dv-XOprJ.js → ayu-mirage-Bc9Dyu4v.js} +0 -0
- /package/dist/web/assets/{ballerina-DACRT-sT.js → ballerina-B0CV6yyC.js} +0 -0
- /package/dist/web/assets/{bat-BlQCq2XE.js → bat-BmukVhcd.js} +0 -0
- /package/dist/web/assets/{beancount-DYDztRI0.js → beancount-DfRKW4qX.js} +0 -0
- /package/dist/web/assets/{berry-BE5YKqvx.js → berry-BXO-GbOz.js} +0 -0
- /package/dist/web/assets/{bibtex-CAm7mgEm.js → bibtex-BIMgGN81.js} +0 -0
- /package/dist/web/assets/{bicep-BKgAbfVa.js → bicep-CIaj_N_V.js} +0 -0
- /package/dist/web/assets/{bird2-yrBNbW1G.js → bird2-Ca5CJ-1r.js} +0 -0
- /package/dist/web/assets/{c-txZFr4RM.js → c-BgN-FzVO.js} +0 -0
- /package/dist/web/assets/{c3-D_DrzBUd.js → c3-B366g85t.js} +0 -0
- /package/dist/web/assets/{cadence-CUFCEgG9.js → cadence-BDCY3xvX.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-_yqa69dV.js → can-open-in-ppm-DyFXJvuW.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-Dn32MuhA.js → catppuccin-frappe-C2dWlEOM.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-Dewo7yDf.js → catppuccin-latte-B6AgUzC2.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-D8WOWZeo.js → catppuccin-macchiato-D2r_sUYa.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-b0md48XM.js → catppuccin-mocha-CCJOmGcr.js} +0 -0
- /package/dist/web/assets/{clarity-Ct3UqLBj.js → clarity-7c_yM38y.js} +0 -0
- /package/dist/web/assets/{clojure-CwP5aPEo.js → clojure-Cx30u1gg.js} +0 -0
- /package/dist/web/assets/{cmake-D5RF49e5.js → cmake-D8nfcw9r.js} +0 -0
- /package/dist/web/assets/{codeowners-Cl5897L_.js → codeowners-z9VeFgy0.js} +0 -0
- /package/dist/web/assets/{codeql-BKh1RCg0.js → codeql-DXYEc0p7.js} +0 -0
- /package/dist/web/assets/{common-lisp-BhHuD6t0.js → common-lisp-QB2DYRB7.js} +0 -0
- /package/dist/web/assets/{coq-Dco3qwD8.js → coq-DC4-vZSI.js} +0 -0
- /package/dist/web/assets/{csharp-Dpjw9ZA9.js → csharp-iBJcXIuz.js} +0 -0
- /package/dist/web/assets/{css-CPe4cabH.js → css-DzLteUnC.js} +0 -0
- /package/dist/web/assets/{csv-parser-DbxGKdMG.js → csv-parser-0OmrzV4G.js} +0 -0
- /package/dist/web/assets/{csv-BAcTN8Kt.js → csv-plVZ5iV_.js} +0 -0
- /package/dist/web/assets/{cue-Cr6y60TA.js → cue-MFyM4FwJ.js} +0 -0
- /package/dist/web/assets/{cypher-DWtqXXFP.js → cypher-BmV76dTw.js} +0 -0
- /package/dist/web/assets/{d-BASiTZk4.js → d-CukQ97B6.js} +0 -0
- /package/dist/web/assets/{dark-plus-56kmnrcl.js → dark-plus-BDhlhnd-.js} +0 -0
- /package/dist/web/assets/{dart-C5mZnjoE.js → dart-BEDiNp89.js} +0 -0
- /package/dist/web/assets/{dax-B4I2e7d8.js → dax-CKMJPpmb.js} +0 -0
- /package/dist/web/assets/{desktop-DekGg0BT.js → desktop-CjjGerHK.js} +0 -0
- /package/dist/web/assets/{diff-CWnJBd73.js → diff-CuRWQEJk.js} +0 -0
- /package/dist/web/assets/{dist-B0J2eYBz.js → dist-BuUB-Gou.js} +0 -0
- /package/dist/web/assets/{docker-DevchDxK.js → docker-BzeqNwXY.js} +0 -0
- /package/dist/web/assets/{docx-preview-Xy7SZ7Vf.js → docx-preview-Dg8lD3f3.js} +0 -0
- /package/dist/web/assets/{dotenv-DCvtdaGJ.js → dotenv-maAByz4s.js} +0 -0
- /package/dist/web/assets/{dracula-8U6Vkk3l.js → dracula-BK-58eQL.js} +0 -0
- /package/dist/web/assets/{dracula-soft-Bfeew5Wg.js → dracula-soft-BiBFiJ4B.js} +0 -0
- /package/dist/web/assets/{dream-maker-DDTJVuoy.js → dream-maker-SLz866k9.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CEHJqI4m.js → emacs-lisp-DVVSBvYb.js} +0 -0
- /package/dist/web/assets/{everforest-dark-CHHLt7cq.js → everforest-dark-B3wCaZGh.js} +0 -0
- /package/dist/web/assets/{everforest-light-TcTbK1sM.js → everforest-light-BOv6DEcT.js} +0 -0
- /package/dist/web/assets/{fennel-Bh4vsA1A.js → fennel-mxeAVgSR.js} +0 -0
- /package/dist/web/assets/{fish-D0T0fILG.js → fish-CNPEh-7O.js} +0 -0
- /package/dist/web/assets/{fluent-CgXDXdyy.js → fluent-DzjF371g.js} +0 -0
- /package/dist/web/assets/{format-bytes-Bc6SqF7M.js → format-bytes-BxBoqnS1.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-CUg3Xhz4.js → fortran-free-form-BwcDAA-k.js} +0 -0
- /package/dist/web/assets/{gdscript-Cx056p_k.js → gdscript-Dw53oyoq.js} +0 -0
- /package/dist/web/assets/{gdshader-Dj1qP4I5.js → gdshader-Ch4uX8TL.js} +0 -0
- /package/dist/web/assets/{genie-SBt15wn7.js → genie-BmyA3sav.js} +0 -0
- /package/dist/web/assets/{gherkin-bTJiHIrB.js → gherkin-TJfGbfw6.js} +0 -0
- /package/dist/web/assets/{github-dark-BOPhyugs.js → github-dark-DfjGEBZm.js} +0 -0
- /package/dist/web/assets/{github-dark-default-Cktqe6NF.js → github-dark-default-C05CO5WG.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-CeWfII_B.js → github-dark-dimmed-tc58hIbY.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-CTx8LpdV.js → github-dark-high-contrast-Cbjouhax.js} +0 -0
- /package/dist/web/assets/{github-light-DVsO5Un1.js → github-light-DyPx5kxT.js} +0 -0
- /package/dist/web/assets/{github-light-default-BiyPxicr.js → github-light-default-CwQhvvq0.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-BPlnke0a.js → github-light-high-contrast-BSEfGuGA.js} +0 -0
- /package/dist/web/assets/{gleam-CWSxvD0C.js → gleam-CO9BliEd.js} +0 -0
- /package/dist/web/assets/{gn-D7NUVJuv.js → gn-3w7c2jXR.js} +0 -0
- /package/dist/web/assets/{gnuplot-c5uXmJKc.js → gnuplot-B9V8Da0h.js} +0 -0
- /package/dist/web/assets/{go-CRsHi4Cw.js → go-DZFS3BH_.js} +0 -0
- /package/dist/web/assets/{groovy-DpV0RA5r.js → groovy-BoXoCYbJ.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DD9fguUN.js → gruvbox-dark-hard-PlwQadvn.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-BvcwpYJ-.js → gruvbox-dark-medium-BCuSx7jF.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-48dCxX9M.js → gruvbox-dark-soft-BxNVGg5m.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-CjJ994Ip.js → gruvbox-light-hard-Caj_mHvE.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-DQJQZ_rV.js → gruvbox-light-medium-BbWauaVM.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-AqsC9mKw.js → gruvbox-light-soft-sTtAiBhF.js} +0 -0
- /package/dist/web/assets/{haskell-B5V7yvmh.js → haskell-DdAcCutT.js} +0 -0
- /package/dist/web/assets/{haxe-LWTKfPKr.js → haxe-CAaBQSbQ.js} +0 -0
- /package/dist/web/assets/{hcl-QmNZdAtI.js → hcl-D1Y6h8Ni.js} +0 -0
- /package/dist/web/assets/{hjson-CboJsAzK.js → hjson-C7gAy4J-.js} +0 -0
- /package/dist/web/assets/{hlsl-Bd-DO_WL.js → hlsl-BLCpvTDs.js} +0 -0
- /package/dist/web/assets/{horizon-CU8Bi_ss.js → horizon-A4TcfP_V.js} +0 -0
- /package/dist/web/assets/{horizon-bright-iSQ3_3jP.js → horizon-bright-D4gSyLkJ.js} +0 -0
- /package/dist/web/assets/{houston-CTXv3Puz.js → houston-B57jZ5OJ.js} +0 -0
- /package/dist/web/assets/{hy-Cd4hTidD.js → hy-C-_Ikdzx.js} +0 -0
- /package/dist/web/assets/{image-gallery-J8h8IY0c.js → image-gallery-DZFo6X0Q.js} +0 -0
- /package/dist/web/assets/{imba-BipCHEY2.js → imba-BwypdGq0.js} +0 -0
- /package/dist/web/assets/{ini-Dd1KkMrB.js → ini-DFC2fVTV.js} +0 -0
- /package/dist/web/assets/{java-rGr0OQD8.js → java-K2R-OeI_.js} +0 -0
- /package/dist/web/assets/{javascript-DHhCH2TN.js → javascript-Dwc_x-Qy.js} +0 -0
- /package/dist/web/assets/{json-CMMLBCUf.js → json-BWJ0jCOR.js} +0 -0
- /package/dist/web/assets/{json5-mPOwTOsB.js → json5-CyjYMs2j.js} +0 -0
- /package/dist/web/assets/{jsonc-Bie0E6D3.js → jsonc-DpY-971T.js} +0 -0
- /package/dist/web/assets/{jsonl-CpqHmtC1.js → jsonl-MOid1Cv5.js} +0 -0
- /package/dist/web/assets/{jsonnet-D21Ms51e.js → jsonnet-C8r7u8hK.js} +0 -0
- /package/dist/web/assets/{jssm-BXnl1nur.js → jssm-aiVzgRKq.js} +0 -0
- /package/dist/web/assets/{jsx-Chnii_vB.js → jsx-BouDi2uL.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-DhxR0UjL.js → kanagawa-dragon-BDBacW42.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-fupRg5wp.js → kanagawa-lotus-Bjc_h4S5.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-DSWbRS9M.js → kanagawa-wave-h12w2GK-.js} +0 -0
- /package/dist/web/assets/{kdl-DirGHqUy.js → kdl-By4Gal6E.js} +0 -0
- /package/dist/web/assets/{kotlin-DkhUVMDC.js → kotlin-BaieUpjq.js} +0 -0
- /package/dist/web/assets/{kusto-DU7OpovF.js → kusto-bFewy_Sb.js} +0 -0
- /package/dist/web/assets/{laserwave-iLKb1ZCT.js → laserwave-DpFhqINu.js} +0 -0
- /package/dist/web/assets/{lean-Cuvh_QAP.js → lean-DDn2i30H.js} +0 -0
- /package/dist/web/assets/{less-B5tQZOdI.js → less-DtaLKtJv.js} +0 -0
- /package/dist/web/assets/{lib-el9rA30D.js → lib-Bss7BrXJ.js} +0 -0
- /package/dist/web/assets/{libesm-CdttTIAd.js → libesm-DJd6dkYL.js} +0 -0
- /package/dist/web/assets/{light-plus-DiHU2KL5.js → light-plus-BiMMZ8in.js} +0 -0
- /package/dist/web/assets/{llvm-sCBTKCKN.js → llvm-BI0xMYjk.js} +0 -0
- /package/dist/web/assets/{log-DtyR34Ie.js → log-BDnXCvPh.js} +0 -0
- /package/dist/web/assets/{logo-CP91aQyG.js → logo-DeOTbfcP.js} +0 -0
- /package/dist/web/assets/{luau-nfGo2ulP.js → luau-C8pWPPhP.js} +0 -0
- /package/dist/web/assets/{make-XbDn9GHe.js → make-Du6n4Vqb.js} +0 -0
- /package/dist/web/assets/{markdown-BB1_3xLr.js → markdown-CQOwzr1d.js} +0 -0
- /package/dist/web/assets/{material-theme-CIx_sxAy.js → material-theme-V1uvvG3T.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-DsQeueDD.js → material-theme-darker-YOeOea0A.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-x_lMi74j.js → material-theme-lighter-gsPcqGZh.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-Bkgh25P8.js → material-theme-ocean-DXpcGhUO.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-CoOjdbti.js → material-theme-palenight-CuXKc4Kv.js} +0 -0
- /package/dist/web/assets/{matlab-D6xZas_8.js → matlab-DKfAoKWM.js} +0 -0
- /package/dist/web/assets/{mdx-Cl5_YNoz.js → mdx-B3lHrBfA.js} +0 -0
- /package/dist/web/assets/{media-url-BMeBaB0q.js → media-url-TGgkntUW.js} +0 -0
- /package/dist/web/assets/{mermaid-8Eow4jz_.js → mermaid-aFxjKRiq.js} +0 -0
- /package/dist/web/assets/{min-dark-D4DhjgRE.js → min-dark-z_K9sY1g.js} +0 -0
- /package/dist/web/assets/{min-light-DzAckd0t.js → min-light-CKEPOwP-.js} +0 -0
- /package/dist/web/assets/{mipsasm-zI_zu0tj.js → mipsasm-Czl4687V.js} +0 -0
- /package/dist/web/assets/{mojo-DQnGGPHf.js → mojo-XEmb6dMz.js} +0 -0
- /package/dist/web/assets/{monokai-CrFoD2VD.js → monokai-CeewfP-T.js} +0 -0
- /package/dist/web/assets/{moonbit-DdphIGs6.js → moonbit-BFs6rC9o.js} +0 -0
- /package/dist/web/assets/{move-BUlkn0xW.js → move-Dru-OXAq.js} +0 -0
- /package/dist/web/assets/{narrat-CbOBdtCn.js → narrat-C6i2yGbz.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-CeVLUTuQ.js → nextflow-groovy-CNbSHaJ-.js} +0 -0
- /package/dist/web/assets/{night-owl-Bm4LhUR1.js → night-owl-XXoqvAPs.js} +0 -0
- /package/dist/web/assets/{night-owl-light-DtcBiMEf.js → night-owl-light-Dm8251t1.js} +0 -0
- /package/dist/web/assets/{nix-DrdwQ70g.js → nix-DUvtyLsY.js} +0 -0
- /package/dist/web/assets/{nord-B0Head1v.js → nord-DapQODEA.js} +0 -0
- /package/dist/web/assets/{nushell-CmUdltKn.js → nushell-WDWgg9A2.js} +0 -0
- /package/dist/web/assets/{objective-c-BGDR33XN.js → objective-c-Dg6Li1Kw.js} +0 -0
- /package/dist/web/assets/{objective-cpp-Buc1Zhd0.js → objective-cpp-DLTQ4Pyg.js} +0 -0
- /package/dist/web/assets/{ocaml-xdzl9rRD.js → ocaml-gH2M-t6b.js} +0 -0
- /package/dist/web/assets/{odin-DiUFngnd.js → odin-BBj0SPaN.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-BURxmIp3.js → one-dark-pro-C8irccD3.js} +0 -0
- /package/dist/web/assets/{one-light-BMRMInAj.js → one-light-THMntV-R.js} +0 -0
- /package/dist/web/assets/{openscad-DAgLA5J3.js → openscad-BEjRF8ZV.js} +0 -0
- /package/dist/web/assets/{pascal-CoDZxcRB.js → pascal-C7Kr1uH_.js} +0 -0
- /package/dist/web/assets/{pkl-DzKM6BuM.js → pkl-CBAaOrr-.js} +0 -0
- /package/dist/web/assets/{plastic-vF15LmNS.js → plastic-B1qtUEVU.js} +0 -0
- /package/dist/web/assets/{plsql-C1v07teA.js → plsql-KzVm4VQQ.js} +0 -0
- /package/dist/web/assets/{po-CLLC8BuA.js → po-BDthh1AB.js} +0 -0
- /package/dist/web/assets/{poimandres-Uq0xysxM.js → poimandres-DIsV0oVO.js} +0 -0
- /package/dist/web/assets/{polar-2-luY1Pc.js → polar-HfZSDZob.js} +0 -0
- /package/dist/web/assets/{postcss-lbFhe0rz.js → postcss-D2mpQWcD.js} +0 -0
- /package/dist/web/assets/{powerquery-RL8O9Wie.js → powerquery-BmWOahNZ.js} +0 -0
- /package/dist/web/assets/{powershell-upFWhb-b.js → powershell-DuBkKB6U.js} +0 -0
- /package/dist/web/assets/{prisma-DBtYaWFk.js → prisma-DMOCr8t3.js} +0 -0
- /package/dist/web/assets/{prolog-D8jSMykJ.js → prolog-OntlFpI5.js} +0 -0
- /package/dist/web/assets/{proto-BM4eadF7.js → proto-kD5tYlX3.js} +0 -0
- /package/dist/web/assets/{puppet-BQDQ3Snu.js → puppet-CO4XS5MF.js} +0 -0
- /package/dist/web/assets/{purescript-Cj2aTX4s.js → purescript-D_e2LzQx.js} +0 -0
- /package/dist/web/assets/{python-BYpqq6u4.js → python-BcK-Cw6k.js} +0 -0
- /package/dist/web/assets/{qmldir-4uiTcwAu.js → qmldir-B-9b87fC.js} +0 -0
- /package/dist/web/assets/{qss-D5xB-Mqo.js → qss-hWjUDAxi.js} +0 -0
- /package/dist/web/assets/{r-P6Ujy8rf.js → r-D0sNqudq.js} +0 -0
- /package/dist/web/assets/{racket-COKgCFuM.js → racket-9cjYYXcq.js} +0 -0
- /package/dist/web/assets/{raku-z14Q9i7K.js → raku-ntPupo_R.js} +0 -0
- /package/dist/web/assets/{red-ObAvgvQ5.js → red-D814sEjX.js} +0 -0
- /package/dist/web/assets/{reg-Qv4f0JFA.js → reg-bPzNEQh4.js} +0 -0
- /package/dist/web/assets/{regexp-CEOVGIzy.js → regexp-B_zg64Ge.js} +0 -0
- /package/dist/web/assets/{rel-cWOyTUwd.js → rel-CoB0Qjm-.js} +0 -0
- /package/dist/web/assets/{riscv-BZDwx-lv.js → riscv-DcVTEi_B.js} +0 -0
- /package/dist/web/assets/{ron-BpjosPS0.js → ron-CcAQMYzM.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-BbGt9Wy_.js → rose-pine-dawn-DkSLvjDV.js} +0 -0
- /package/dist/web/assets/{rose-pine-DhxfJWcm.js → rose-pine-jtG38kvA.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-dj4Zxgik.js → rose-pine-moon-DJx8AxMs.js} +0 -0
- /package/dist/web/assets/{rosmsg-EciOaHo2.js → rosmsg-BnfYFiWk.js} +0 -0
- /package/dist/web/assets/{run-in-terminal-wHKwAnWP.js → run-in-terminal-Sb6TFU4f.js} +0 -0
- /package/dist/web/assets/{rust-C_eH59O_.js → rust-DxgQnpfl.js} +0 -0
- /package/dist/web/assets/{sass-Dos3R5lL.js → sass-DTgjjspH.js} +0 -0
- /package/dist/web/assets/{scala-8lVKsTvf.js → scala-xEozebyS.js} +0 -0
- /package/dist/web/assets/{scheme-Bd3VdaZj.js → scheme-sfgxdr_D.js} +0 -0
- /package/dist/web/assets/{sdbl-C4Yrjlgh.js → sdbl-BpdzD-Uv.js} +0 -0
- /package/dist/web/assets/{send-to-chat-BI7-fFpG.js → send-to-chat-BDws0-k0.js} +0 -0
- /package/dist/web/assets/{separator-W_hJcXPk.js → separator-GeVzERIl.js} +0 -0
- /package/dist/web/assets/{shellscript-OFZbPKZH.js → shellscript-B2o7zCrN.js} +0 -0
- /package/dist/web/assets/{slack-dark-aL6vlxZs.js → slack-dark-DxfgNfgJ.js} +0 -0
- /package/dist/web/assets/{slack-ochin-BKt1E7sL.js → slack-ochin-BMSGMkt8.js} +0 -0
- /package/dist/web/assets/{smalltalk-D6qVBL1U.js → smalltalk-DCb8haRt.js} +0 -0
- /package/dist/web/assets/{snazzy-light-BrWerT0t.js → snazzy-light-Y06j56Vj.js} +0 -0
- /package/dist/web/assets/{solarized-dark-CzxTJgVQ.js → solarized-dark-z1W-RVhp.js} +0 -0
- /package/dist/web/assets/{solarized-light-BecaDAnG.js → solarized-light-BRAGTpW5.js} +0 -0
- /package/dist/web/assets/{solidity-C9t7pZ84.js → solidity-CDTZVMHy.js} +0 -0
- /package/dist/web/assets/{splunk-CtxfFKtF.js → splunk-CFjv6-V_.js} +0 -0
- /package/dist/web/assets/{sql-7FE_Duz0.js → sql-Ce-1ETwT.js} +0 -0
- /package/dist/web/assets/{ssh-config-3Fr37ACC.js → ssh-config-Bcs3SD-x.js} +0 -0
- /package/dist/web/assets/{stylus-BP4mE1sO.js → stylus-Co5Var6O.js} +0 -0
- /package/dist/web/assets/{swift-0uqTFouD.js → swift-Irt_r7Fy.js} +0 -0
- /package/dist/web/assets/{synthwave-84-DQaNM3DI.js → synthwave-84-BOgCDIL-.js} +0 -0
- /package/dist/web/assets/{system-verilog-DUIVrZHZ.js → system-verilog-DSwfS0ci.js} +0 -0
- /package/dist/web/assets/{systemd-CtNo_WIh.js → systemd-C-HqVFLV.js} +0 -0
- /package/dist/web/assets/{talonscript-B0HXaCVT.js → talonscript-B7lshRGY.js} +0 -0
- /package/dist/web/assets/{tasl-Cb7RAl11.js → tasl-BZXSTCA-.js} +0 -0
- /package/dist/web/assets/{tcl-B79aC6l5.js → tcl-B_vaMM01.js} +0 -0
- /package/dist/web/assets/{terraform-75jJDjpW.js → terraform-B7kDBVtX.js} +0 -0
- /package/dist/web/assets/{tokyo-night-Cz9Uh9qb.js → tokyo-night-CW1uC1bG.js} +0 -0
- /package/dist/web/assets/{toml-CD6y9A-z.js → toml-Af6Dxufp.js} +0 -0
- /package/dist/web/assets/{tsv-CXJMbBrb.js → tsv-BSFZ-g3s.js} +0 -0
- /package/dist/web/assets/{tsx-BuYN0I2t.js → tsx-CN8kIwG_.js} +0 -0
- /package/dist/web/assets/{turtle-DWH-Rjse.js → turtle-BSUyR8DV.js} +0 -0
- /package/dist/web/assets/{typescript-BPd-hsrR.js → typescript-2AZeIhCA.js} +0 -0
- /package/dist/web/assets/{typespec-B0wvVykx.js → typespec-DRZ0XiHC.js} +0 -0
- /package/dist/web/assets/{typst-DWG2c48-.js → typst-p1gfDr4O.js} +0 -0
- /package/dist/web/assets/{use-blob-url-CrwoZJUJ.js → use-blob-url-BMtoAEL4.js} +0 -0
- /package/dist/web/assets/{use-open-team-member-CSUU7Z8N.js → use-open-team-member-C9EUqPvl.js} +0 -0
- /package/dist/web/assets/{v-Ch6E4Egd.js → v-B705HYgD.js} +0 -0
- /package/dist/web/assets/{vala-CGVKwbPx.js → vala-CyU0S4KW.js} +0 -0
- /package/dist/web/assets/{vb-BIEbSxyT.js → vb-DCWUzR_1.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-YQlzIWv2.js → vendor-xterm-MrmaYoD2.js} +0 -0
- /package/dist/web/assets/{verilog-A-3pYPad.js → verilog-CrRE3TC7.js} +0 -0
- /package/dist/web/assets/{vesper-CK1naZAV.js → vesper-BH5N5eRr.js} +0 -0
- /package/dist/web/assets/{vhdl-CVawmgMg.js → vhdl-CT1Mz-fu.js} +0 -0
- /package/dist/web/assets/{viml-CiWjaqBY.js → viml-B0LtAesb.js} +0 -0
- /package/dist/web/assets/{vitesse-black-PYXW4-BO.js → vitesse-black-DqQvxGCJ.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-BU5s4AuG.js → vitesse-dark-C6MRSe2N.js} +0 -0
- /package/dist/web/assets/{vitesse-light-DgkIT-N7.js → vitesse-light-B-8DQ5R9.js} +0 -0
- /package/dist/web/assets/{vyper-D8cRDPp3.js → vyper-D7YgYuMk.js} +0 -0
- /package/dist/web/assets/{wasm-ClFJgzmT.js → wasm-BgEp8ivq.js} +0 -0
- /package/dist/web/assets/{wasm-C02wlRbP.js → wasm-Dj9JHuDf.js} +0 -0
- /package/dist/web/assets/{wenyan-B8plxIr8.js → wenyan-CLcU30u4.js} +0 -0
- /package/dist/web/assets/{wgsl-CVujtm3V.js → wgsl-DEtNo0DR.js} +0 -0
- /package/dist/web/assets/{wikitext-CmcG9B69.js → wikitext-CXiDN9zY.js} +0 -0
- /package/dist/web/assets/{wit--gl2Jium.js → wit-0hROlx_P.js} +0 -0
- /package/dist/web/assets/{wolfram-6T_1D-NS.js → wolfram-nhKFI8Qz.js} +0 -0
- /package/dist/web/assets/{yaml-CIVV9uA1.js → yaml-CNoUgoPD.js} +0 -0
- /package/dist/web/assets/{zenscript-CoT4yNdA.js → zenscript-BgGAyJ15.js} +0 -0
- /package/dist/web/assets/{zig-BWs2Qo3G.js → zig-Be_I-6Rs.js} +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { readdir, open, realpath, stat } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import type { AIProvider } from "../types/chat.ts";
|
|
6
|
+
import { readCodexNativeMemory } from "./codex-native-memory.ts";
|
|
7
|
+
|
|
8
|
+
type Source = { path: string; directory?: boolean; indexOnly?: boolean };
|
|
9
|
+
const MAX_FILES = 48;
|
|
10
|
+
const MAX_FILE_BYTES = 4_000;
|
|
11
|
+
const MAX_CONTEXT_CHARS = 12_000;
|
|
12
|
+
|
|
13
|
+
/** Explicit instruction sources only: never scan provider settings, auth or transcripts. */
|
|
14
|
+
export async function buildSharedProviderContext(
|
|
15
|
+
projectPath: string,
|
|
16
|
+
providers: AIProvider[],
|
|
17
|
+
options: { userHome?: string; codexHomes?: string[]; recipientProviderId?: string } = {},
|
|
18
|
+
): Promise<string> {
|
|
19
|
+
const project = resolve(projectPath);
|
|
20
|
+
const canonicalProject = (await realpath(project).catch(() => project)).normalize("NFC");
|
|
21
|
+
const home = options.userHome ?? homedir();
|
|
22
|
+
const claudeHome = options.userHome ? join(home, ".claude") : process.env.CLAUDE_CONFIG_DIR || join(home, ".claude");
|
|
23
|
+
const claudeMemory = join(claudeHome, "projects", canonicalProject.replace(/[^a-zA-Z0-9]/g, "-"), "memory");
|
|
24
|
+
const recipient = options.recipientProviderId;
|
|
25
|
+
const sources: Source[] = [
|
|
26
|
+
// Native indexes come first so rules cannot crowd out existing memories.
|
|
27
|
+
...(recipient === "claude" ? [] : [
|
|
28
|
+
{ path: claudeMemory, directory: true, indexOnly: true },
|
|
29
|
+
{ path: join(project, "CLAUDE.md") },
|
|
30
|
+
{ path: join(project, "CLAUDE.local.md") },
|
|
31
|
+
{ path: join(claudeHome, "CLAUDE.md") },
|
|
32
|
+
{ path: join(claudeHome, "rules"), directory: true },
|
|
33
|
+
]),
|
|
34
|
+
...(recipient === "codex" ? [] : [{ path: join(project, "AGENTS.md") }]),
|
|
35
|
+
];
|
|
36
|
+
let codexHomes = options.codexHomes;
|
|
37
|
+
if (!codexHomes) {
|
|
38
|
+
codexHomes = [join(home, ".codex")];
|
|
39
|
+
if (!options.userHome) {
|
|
40
|
+
if (process.env.CODEX_HOME) codexHomes.push(process.env.CODEX_HOME);
|
|
41
|
+
const { listCodexAccounts } = await import("./codex-account.service.ts");
|
|
42
|
+
codexHomes.push(...listCodexAccounts().map((account) => account.home));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const codexHome of recipient === "codex" ? [] : new Set(codexHomes)) {
|
|
46
|
+
sources.push({ path: join(codexHome, "AGENTS.md") });
|
|
47
|
+
}
|
|
48
|
+
const ids = new Set(["claude", "codex", "cursor", ...providers.map((p) => p.id)]);
|
|
49
|
+
for (const id of ids) {
|
|
50
|
+
if (!/^[a-z0-9_-]+$/i.test(id)) continue;
|
|
51
|
+
// Only known native loaders are excluded: new providers still get their
|
|
52
|
+
// conventional sources until their adapter explicitly handles native loading.
|
|
53
|
+
if (!(id === recipient && ["claude", "codex", "cursor"].includes(id))) {
|
|
54
|
+
sources.push({ path: join(project, `.${id}`, "rules"), directory: true });
|
|
55
|
+
}
|
|
56
|
+
if (!(id === "claude" && recipient === "claude")) {
|
|
57
|
+
sources.push({ path: join(project, `.${id}`, "memory"), directory: true, indexOnly: true });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const provider of providers) {
|
|
61
|
+
try { sources.push(...(provider.getSharedContextSources?.(project) ?? [])); }
|
|
62
|
+
catch { /* An unavailable provider must not prevent other providers from chatting. */ }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const seen = new Set<string>();
|
|
66
|
+
const sections: string[] = [];
|
|
67
|
+
const available: string[] = [];
|
|
68
|
+
const revision = createHash("sha256");
|
|
69
|
+
let remaining = MAX_CONTEXT_CHARS;
|
|
70
|
+
let nativeBudget = 4_000;
|
|
71
|
+
// Codex already loads its own native memory; share it with other runtimes.
|
|
72
|
+
for (const memory of recipient === "codex" ? [] : readCodexNativeMemory(canonicalProject, codexHomes)) {
|
|
73
|
+
revision.update(memory.path).update(memory.content);
|
|
74
|
+
if (nativeBudget < 512) continue;
|
|
75
|
+
const content = memory.content.slice(0, nativeBudget - 256);
|
|
76
|
+
const section = `Native Codex memory record: ${JSON.stringify(memory.path)}\n${content}\n${content.length < memory.content.length ? "[Excerpt; the original record has more content.]\n" : ""}`;
|
|
77
|
+
sections.push(section);
|
|
78
|
+
remaining -= section.length;
|
|
79
|
+
nativeBudget -= section.length;
|
|
80
|
+
}
|
|
81
|
+
let count = 0;
|
|
82
|
+
let visited = 0;
|
|
83
|
+
async function fingerprintTopics(path: string, depth = 0): Promise<void> {
|
|
84
|
+
if (depth > 3 || visited >= 256) return;
|
|
85
|
+
visited++;
|
|
86
|
+
try {
|
|
87
|
+
const entries = (await readdir(path, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name));
|
|
88
|
+
for (const entry of entries.slice(0, MAX_FILES)) {
|
|
89
|
+
const child = join(path, entry.name);
|
|
90
|
+
if (entry.isDirectory()) await fingerprintTopics(child, depth + 1);
|
|
91
|
+
else if (entry.isFile() && /\.(md|mdc)$/i.test(entry.name)) {
|
|
92
|
+
const info = await stat(child);
|
|
93
|
+
revision.update(JSON.stringify([child, info.size, info.mtimeMs, info.ctimeMs]));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch { /* Optional topic folders may disappear while being edited. */ }
|
|
97
|
+
}
|
|
98
|
+
async function collect(source: Source, depth = 0): Promise<void> {
|
|
99
|
+
if (count >= MAX_FILES || depth > 3 || visited >= 256) return;
|
|
100
|
+
visited++;
|
|
101
|
+
try {
|
|
102
|
+
const path = await realpath(source.path);
|
|
103
|
+
const key = process.platform === "win32" ? path.toLowerCase() : path;
|
|
104
|
+
if (seen.has(key)) return;
|
|
105
|
+
seen.add(key);
|
|
106
|
+
if (source.directory) {
|
|
107
|
+
available.push(`Native source directory: ${JSON.stringify(path)}`);
|
|
108
|
+
if (source.indexOnly) {
|
|
109
|
+
await fingerprintTopics(path);
|
|
110
|
+
await collect({ path: join(path, "MEMORY.md") }, depth + 1);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const entries = (await readdir(path, { withFileTypes: true })).sort((a, b) =>
|
|
114
|
+
Number(b.name.toLowerCase() === "memory.md") - Number(a.name.toLowerCase() === "memory.md") || a.name.localeCompare(b.name));
|
|
115
|
+
for (const entry of entries.slice(0, MAX_FILES)) {
|
|
116
|
+
// Do not follow directory symlinks into unrelated projects or account state.
|
|
117
|
+
if (entry.isDirectory()) await collect({ path: join(path, entry.name), directory: true }, depth + 1);
|
|
118
|
+
else if (entry.isFile() && /\.(md|mdc)$/i.test(entry.name)) await collect({ path: join(path, entry.name) }, depth + 1);
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
const info = await stat(path);
|
|
122
|
+
if (!info.isFile()) return;
|
|
123
|
+
revision.update(JSON.stringify([path, info.size, info.mtimeMs, info.ctimeMs]));
|
|
124
|
+
count++;
|
|
125
|
+
if (remaining < 512) return;
|
|
126
|
+
const handle = await open(path, "r");
|
|
127
|
+
let content: string;
|
|
128
|
+
let bytesRead: number;
|
|
129
|
+
try {
|
|
130
|
+
const buffer = Buffer.alloc(Math.min(info.size, MAX_FILE_BYTES, Math.max(0, remaining - 256)));
|
|
131
|
+
({ bytesRead } = await handle.read(buffer, 0, buffer.length, 0));
|
|
132
|
+
content = buffer.subarray(0, bytesRead).toString("utf8").trim();
|
|
133
|
+
} finally { await handle.close(); }
|
|
134
|
+
if (!content || content.includes("\0")) return;
|
|
135
|
+
const section = `Source: ${JSON.stringify(path)}\n${content}\n${bytesRead < info.size ? "[Excerpt; read the original file for the remainder.]\n" : ""}`;
|
|
136
|
+
if (section.length > remaining) return;
|
|
137
|
+
sections.push(section);
|
|
138
|
+
remaining -= section.length;
|
|
139
|
+
}
|
|
140
|
+
} catch { /* Missing/unreadable optional sources are expected. */ }
|
|
141
|
+
}
|
|
142
|
+
for (const source of sources) await collect(source);
|
|
143
|
+
return [
|
|
144
|
+
"PPM provider sharing is enabled for this project. These are user-managed instructions and memory, not a new user request.",
|
|
145
|
+
"Use relevant project knowledge; respect each rule's path/frontmatter scope. Current user instructions take precedence. Provider-specific tool names/settings apply only where supported.",
|
|
146
|
+
"Read and use existing native provider memory below, including memory created before PPM was installed. There is no separate PPM memory store. Keep new memories in the provider's native location. Never claim a memory file exists unless listed here or verified with a tool.",
|
|
147
|
+
"This bounded snapshot omits instructions already loaded by your runtime. Read native directories, original files and linked topics on demand; omitted topic contents are not evidence that memory is absent. Respect project scope when following links.",
|
|
148
|
+
`Source revision: ${revision.digest("hex").slice(0, 16)}`,
|
|
149
|
+
[...new Set(available)].join("\n").slice(0, 1_500),
|
|
150
|
+
...sections,
|
|
151
|
+
].join("\n\n");
|
|
152
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const START = "<ppm-shared-context>";
|
|
2
|
+
const END = "</ppm-shared-context>";
|
|
3
|
+
|
|
4
|
+
/** Transport metadata is not part of the user's message, even in native transcripts. */
|
|
5
|
+
export function withSharedContext(message: string, context?: string): string {
|
|
6
|
+
return context ? `${START}\n${context.replaceAll(END, "[end context]")}\n${END}\n\n${message}` : message;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function stripSharedContext(message: string): string {
|
|
10
|
+
if (!message.startsWith(`${START}\n`)) return message;
|
|
11
|
+
const end = message.indexOf(`${END}\n\n`);
|
|
12
|
+
return end < 0 ? "" : message.slice(end + END.length + 2);
|
|
13
|
+
}
|
package/src/types/chat.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export interface SendMessageOpts {
|
|
2
|
+
/** PPM's bounded, project-scoped shared instructions; kept separate from user text. */
|
|
3
|
+
sharedContext?: string;
|
|
2
4
|
permissionMode?: import("./config").PermissionMode | string;
|
|
3
5
|
priority?: 'now' | 'next' | 'later';
|
|
4
6
|
images?: Array<{ data: string; mediaType: string }>;
|
|
@@ -25,6 +27,10 @@ export interface SendMessageOpts {
|
|
|
25
27
|
export interface AIProvider {
|
|
26
28
|
id: string;
|
|
27
29
|
name: string;
|
|
30
|
+
/** Handles opts.sharedContext without using it as the user's saved message/title. */
|
|
31
|
+
supportsSharedContext?: boolean;
|
|
32
|
+
/** Additional instruction/memory sources; never return credentials or transcripts. */
|
|
33
|
+
getSharedContextSources?(projectPath: string): Array<{ path: string; directory?: boolean }>;
|
|
28
34
|
|
|
29
35
|
// Session lifecycle (required)
|
|
30
36
|
createSession(config: SessionConfig): Promise<Session>;
|
package/src/types/config.ts
CHANGED
|
@@ -76,6 +76,8 @@ export interface ProjectConfig {
|
|
|
76
76
|
|
|
77
77
|
export interface AIConfig {
|
|
78
78
|
default_provider: string;
|
|
79
|
+
/** Share project rules and memory between providers. Unset defaults to true. */
|
|
80
|
+
share_provider_context?: boolean;
|
|
79
81
|
providers: Record<string, AIProviderConfig>;
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -109,6 +111,10 @@ export interface AIProviderConfig {
|
|
|
109
111
|
|
|
110
112
|
// CLI-specific (Cursor, Codex, Gemini)
|
|
111
113
|
cli_command?: string;
|
|
114
|
+
|
|
115
|
+
// Codex config overrides in tokens. Null/unset inherits Codex's configuration.
|
|
116
|
+
model_context_window?: number | null;
|
|
117
|
+
model_auto_compact_token_limit?: number | null;
|
|
112
118
|
}
|
|
113
119
|
|
|
114
120
|
/**
|
|
@@ -134,6 +140,7 @@ export const DEFAULT_CONFIG: PpmConfig = {
|
|
|
134
140
|
projects: [],
|
|
135
141
|
ai: {
|
|
136
142
|
default_provider: "claude",
|
|
143
|
+
share_provider_context: true,
|
|
137
144
|
providers: {
|
|
138
145
|
claude: {
|
|
139
146
|
type: "agent-sdk",
|
|
@@ -203,6 +210,7 @@ function migrateThemeValue(theme: unknown): ThemeConfig | null {
|
|
|
203
210
|
/** Validate AI provider config fields. Returns array of error messages (empty = valid). */
|
|
204
211
|
export function validateAIProviderConfig(config: Partial<AIProviderConfig>): string[] {
|
|
205
212
|
const errors: string[] = [];
|
|
213
|
+
errors.push(...validateCodexContextConfig(config));
|
|
206
214
|
if (config.type != null && !VALID_TYPES.includes(config.type as any)) {
|
|
207
215
|
errors.push(`type must be one of: ${VALID_TYPES.join(", ")}`);
|
|
208
216
|
}
|
|
@@ -254,6 +262,22 @@ export function validateAIProviderConfig(config: Partial<AIProviderConfig>): str
|
|
|
254
262
|
return errors;
|
|
255
263
|
}
|
|
256
264
|
|
|
265
|
+
/** Also validate the merged provider config so partial updates cannot break the pair. */
|
|
266
|
+
export function validateCodexContextConfig(config: Partial<AIProviderConfig>): string[] {
|
|
267
|
+
const errors: string[] = [];
|
|
268
|
+
for (const key of ["model_context_window", "model_auto_compact_token_limit"] as const) {
|
|
269
|
+
const value = config[key];
|
|
270
|
+
if (value != null && (!Number.isSafeInteger(value) || value < 1)) {
|
|
271
|
+
errors.push(`${key} must be a positive safe integer or null`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (config.model_context_window != null && config.model_auto_compact_token_limit != null
|
|
275
|
+
&& config.model_auto_compact_token_limit > config.model_context_window) {
|
|
276
|
+
errors.push("model_auto_compact_token_limit must not exceed model_context_window");
|
|
277
|
+
}
|
|
278
|
+
return errors;
|
|
279
|
+
}
|
|
280
|
+
|
|
257
281
|
/** Validate default_provider references an existing provider key */
|
|
258
282
|
export function validateDefaultProvider(defaultProvider: string, providers: Record<string, unknown>): string | null {
|
|
259
283
|
if (!providers[defaultProvider]) {
|
|
@@ -269,6 +293,11 @@ export function validateDefaultProvider(defaultProvider: string, providers: Reco
|
|
|
269
293
|
export function sanitizeConfig(config: PpmConfig): boolean {
|
|
270
294
|
let dirty = false;
|
|
271
295
|
|
|
296
|
+
if (typeof config.ai.share_provider_context !== "boolean") {
|
|
297
|
+
config.ai.share_provider_context = true;
|
|
298
|
+
dirty = true;
|
|
299
|
+
}
|
|
300
|
+
|
|
272
301
|
// Migrate/repair theme (legacy string → {style, mode})
|
|
273
302
|
const migrated = migrateThemeValue(config.theme);
|
|
274
303
|
if (migrated) {
|
|
@@ -279,8 +279,11 @@ export function ChatHistoryBar({
|
|
|
279
279
|
// Usage badge display — Claude (SDK) and Codex both expose usage limits
|
|
280
280
|
const isClaudeProvider = !providerId || providerId === "claude";
|
|
281
281
|
const isCodexProvider = providerId === "codex";
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
// Account events can arrive before the new quota snapshot. Never attach the
|
|
283
|
+
// previous account's numbers to the newly selected account's name.
|
|
284
|
+
const usageMatchesAccount = !pickedAccountId || pickedAccountId === usageInfo.activeAccountId;
|
|
285
|
+
const fiveHourPct = usageMatchesAccount && usageInfo.fiveHour != null ? Math.round(usageInfo.fiveHour * 100) : null;
|
|
286
|
+
const sevenDayPct = usageMatchesAccount && usageInfo.sevenDay != null ? Math.round(usageInfo.sevenDay * 100) : null;
|
|
284
287
|
const worstPct = Math.max(fiveHourPct ?? 0, sevenDayPct ?? 0);
|
|
285
288
|
const usageColor = fiveHourPct != null || sevenDayPct != null ? pctColor(worstPct) : "text-text-subtle";
|
|
286
289
|
// Order matters, and the obvious order is wrong. With no session, the usage endpoint has
|
|
@@ -288,7 +291,7 @@ export function ChatHistoryBar({
|
|
|
288
291
|
// so letting it win would show a name that has nothing to do with this tab, which is the
|
|
289
292
|
// exact confusion the claim exists to remove. The claim (and, once a turn is running, the
|
|
290
293
|
// account the stream reports) is specific to this chat and outranks it.
|
|
291
|
-
const accountLabel = pickedAccountLabel ?? usageInfo.activeAccountLabel ?? null;
|
|
294
|
+
const accountLabel = pickedAccountLabel ?? (usageMatchesAccount ? usageInfo.activeAccountLabel : null) ?? null;
|
|
292
295
|
|
|
293
296
|
return (
|
|
294
297
|
<div className="border-b border-border/50">
|
|
@@ -262,6 +262,13 @@ export function ChatTab({ metadata, tabId }: ChatTabProps) {
|
|
|
262
262
|
if (liveAccount) setServingAccount(liveAccount);
|
|
263
263
|
}, [liveAccount]);
|
|
264
264
|
|
|
265
|
+
// Automatic rotation keeps the same session id, so useUsage's polling scope
|
|
266
|
+
// does not change. Re-read its binding as soon as the stream names an account.
|
|
267
|
+
const liveAccountId = liveAccount?.id;
|
|
268
|
+
useEffect(() => {
|
|
269
|
+
if (liveAccountId) void reloadUsage();
|
|
270
|
+
}, [liveAccountId, reloadUsage]);
|
|
271
|
+
|
|
265
272
|
// A different conversation has a different account; carrying this one's over would label
|
|
266
273
|
// it wrongly until the next turn corrected it.
|
|
267
274
|
useEffect(() => { setServingAccount(null); }, [sessionId]);
|
|
@@ -14,6 +14,7 @@ import { getAISettings, updateAISettings, type AISettings } from "@/lib/api-sett
|
|
|
14
14
|
import { api } from "@/lib/api-client";
|
|
15
15
|
import { ProviderBadge } from "@/components/chat/provider-selector";
|
|
16
16
|
import { openSettings } from "./open-settings";
|
|
17
|
+
import { CodexContextSettings } from "./codex-context-settings";
|
|
17
18
|
import type { ModelOption } from "../../../types/chat";
|
|
18
19
|
|
|
19
20
|
const EFFORT_OPTIONS = [
|
|
@@ -73,23 +74,26 @@ export function AISettingsSection({ compact }: { compact?: boolean } = {}) {
|
|
|
73
74
|
const config = settings?.providers[activeTab];
|
|
74
75
|
const isSdkProvider = config?.type === "agent-sdk" || (!config?.type && activeTab === "claude");
|
|
75
76
|
|
|
76
|
-
const
|
|
77
|
-
if (!settings) return;
|
|
77
|
+
const handleSettingsSave = async (patch: Partial<AISettings>) => {
|
|
78
|
+
if (!settings) return false;
|
|
78
79
|
setSaving(true);
|
|
79
80
|
setError(null);
|
|
80
81
|
try {
|
|
81
|
-
const updated = await updateAISettings(
|
|
82
|
-
providers: { [activeTab]: { [field]: value } },
|
|
83
|
-
});
|
|
82
|
+
const updated = await updateAISettings(patch);
|
|
84
83
|
setSettings(updated);
|
|
85
84
|
setRevision((r) => r + 1);
|
|
85
|
+
return true;
|
|
86
86
|
} catch (e) {
|
|
87
87
|
setError((e as Error).message);
|
|
88
|
+
return false;
|
|
88
89
|
} finally {
|
|
89
90
|
setSaving(false);
|
|
90
91
|
}
|
|
91
92
|
};
|
|
92
93
|
|
|
94
|
+
const handleSave = (field: string, value: unknown) =>
|
|
95
|
+
handleSettingsSave({ providers: { [activeTab]: { [field]: value } } });
|
|
96
|
+
|
|
93
97
|
const labelSize = compact ? "text-[11px]" : "text-sm";
|
|
94
98
|
const headingSize = compact ? "text-xs" : "text-sm";
|
|
95
99
|
const gapSize = compact ? "space-y-2" : "space-y-4";
|
|
@@ -116,6 +120,25 @@ export function AISettingsSection({ compact }: { compact?: boolean } = {}) {
|
|
|
116
120
|
<div className={gapSize}>
|
|
117
121
|
<h3 className={`${headingSize} font-medium text-text-secondary`}>AI Settings</h3>
|
|
118
122
|
|
|
123
|
+
<div className="flex items-start justify-between gap-3 rounded-md border border-border p-3">
|
|
124
|
+
<div className={fieldGap}>
|
|
125
|
+
<Label htmlFor="ai-share-provider-context" className={compact ? labelSize : undefined}>
|
|
126
|
+
Share rules and memory between providers
|
|
127
|
+
</Label>
|
|
128
|
+
<p id="ai-share-provider-context-description" className={`${compact ? "text-[9px]" : "text-[11px]"} text-muted-foreground`}>
|
|
129
|
+
Share project rules and memory, plus global instruction files, across providers.
|
|
130
|
+
Applies from the next project-chat message. Turning off keeps context already sent.
|
|
131
|
+
</p>
|
|
132
|
+
</div>
|
|
133
|
+
<Switch
|
|
134
|
+
id="ai-share-provider-context"
|
|
135
|
+
aria-describedby="ai-share-provider-context-description"
|
|
136
|
+
checked={settings.share_provider_context ?? true}
|
|
137
|
+
disabled={saving}
|
|
138
|
+
onCheckedChange={(checked) => handleSettingsSave({ share_provider_context: checked })}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
119
142
|
{/* Provider tabs */}
|
|
120
143
|
{providerTabs.length > 1 && (
|
|
121
144
|
<div className="flex gap-0.5 border-b border-border/50 -mx-1 px-1">
|
|
@@ -173,6 +196,12 @@ export function AISettingsSection({ compact }: { compact?: boolean } = {}) {
|
|
|
173
196
|
</div>
|
|
174
197
|
)}
|
|
175
198
|
|
|
199
|
+
{activeTab === "codex" && (
|
|
200
|
+
<CodexContextSettings key={JSON.stringify([config?.model_context_window, config?.model_auto_compact_token_limit])} config={config}
|
|
201
|
+
compact={compact} saving={saving}
|
|
202
|
+
onSave={(patch) => handleSettingsSave({ providers: { codex: patch } })} />
|
|
203
|
+
)}
|
|
204
|
+
|
|
176
205
|
{/* SDK-specific fields */}
|
|
177
206
|
{isSdkProvider && (
|
|
178
207
|
<>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { useState, type FormEvent } from "react";
|
|
2
|
+
import { Input } from "@/components/ui/input";
|
|
3
|
+
import { Label } from "@/components/ui/label";
|
|
4
|
+
import type { AIProviderSettings } from "@/lib/api-settings";
|
|
5
|
+
|
|
6
|
+
type ContextSettings = Pick<AIProviderSettings, "model_context_window" | "model_auto_compact_token_limit">;
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
config?: ContextSettings;
|
|
10
|
+
compact?: boolean;
|
|
11
|
+
saving: boolean;
|
|
12
|
+
onSave: (settings: ContextSettings) => Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const WINDOW_PRESETS = [128000, 272000, 400000, 512000, 872000, 1000000];
|
|
16
|
+
const COMPACT_PRESETS = [100000, 200000, 230000, 350000, 450000, 750000, 900000];
|
|
17
|
+
|
|
18
|
+
function TokenLimitSelect({ id, label, value, presets, disabled, compact, onChange }: {
|
|
19
|
+
id: string; label: string; value: string; presets: number[]; disabled: boolean;
|
|
20
|
+
compact?: boolean; onChange: (value: string) => void;
|
|
21
|
+
}) {
|
|
22
|
+
const [custom, setCustom] = useState(Boolean(value) && !presets.includes(Number(value)));
|
|
23
|
+
const size = compact ? "text-[11px]" : "text-sm";
|
|
24
|
+
return (
|
|
25
|
+
<div className="space-y-1">
|
|
26
|
+
<Label htmlFor={id} className={size}>{label}</Label>
|
|
27
|
+
<select id={id} value={custom ? "custom" : value || "default"} disabled={disabled}
|
|
28
|
+
aria-describedby="codex-context-help"
|
|
29
|
+
className={`w-full min-h-11 sm:min-h-0 rounded-md border border-input bg-background px-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 ${compact ? "h-7" : "h-9"} ${size}`}
|
|
30
|
+
onChange={(e) => {
|
|
31
|
+
const next = e.target.value;
|
|
32
|
+
setCustom(next === "custom");
|
|
33
|
+
if (next !== "custom") onChange(next === "default" ? "" : next);
|
|
34
|
+
}}>
|
|
35
|
+
<option value="default">Codex default</option>
|
|
36
|
+
{presets.map((tokens) => <option key={tokens} value={String(tokens)}>
|
|
37
|
+
{tokens === 1000000 ? "1M" : `${tokens / 1000}K`} tokens
|
|
38
|
+
</option>)}
|
|
39
|
+
<option value="custom">Custom...</option>
|
|
40
|
+
</select>
|
|
41
|
+
{custom && <Input id={`${id}-custom`} aria-label={`Custom ${label.toLowerCase()}`}
|
|
42
|
+
type="number" min={1} step={1} required value={value} disabled={disabled}
|
|
43
|
+
placeholder="Enter tokens" aria-describedby="codex-context-help"
|
|
44
|
+
className={`min-h-11 sm:min-h-0 ${compact ? "h-7 text-[11px]" : ""}`}
|
|
45
|
+
onChange={(e) => onChange(e.target.value)} />}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function CodexContextSettings({ config, compact, saving, onSave }: Props) {
|
|
51
|
+
const [windowTokens, setWindowTokens] = useState(String(config?.model_context_window ?? ""));
|
|
52
|
+
const [compactTokens, setCompactTokens] = useState(String(config?.model_auto_compact_token_limit ?? ""));
|
|
53
|
+
const [error, setError] = useState<string | null>(null);
|
|
54
|
+
const textSize = compact ? "text-[11px]" : "text-sm";
|
|
55
|
+
const helpSize = compact ? "text-[9px]" : "text-[11px]";
|
|
56
|
+
|
|
57
|
+
async function save(event: FormEvent) {
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
const windowValue = windowTokens.trim() ? Number(windowTokens) : null;
|
|
60
|
+
const compactValue = compactTokens.trim() ? Number(compactTokens) : null;
|
|
61
|
+
if ([windowValue, compactValue].some((v) => v !== null && (!Number.isSafeInteger(v) || v <= 0))) {
|
|
62
|
+
setError("Enter positive whole numbers of tokens, or leave blank for Codex defaults.");
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (windowValue !== null && compactValue !== null && compactValue > windowValue) {
|
|
66
|
+
setError("Auto-compact threshold must not exceed the context window.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
setError(null);
|
|
70
|
+
await onSave({ model_context_window: windowValue, model_auto_compact_token_limit: compactValue });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<form onSubmit={save} className="space-y-2 rounded-md border border-border p-3">
|
|
75
|
+
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
|
|
76
|
+
<TokenLimitSelect id="codex-context-window" label="Context window (tokens)"
|
|
77
|
+
value={windowTokens} presets={WINDOW_PRESETS} disabled={saving} compact={compact}
|
|
78
|
+
onChange={(value) => { setWindowTokens(value); setError(null); }} />
|
|
79
|
+
<TokenLimitSelect id="codex-compact-threshold" label="Auto-compact threshold (tokens)"
|
|
80
|
+
value={compactTokens} presets={COMPACT_PRESETS} disabled={saving} compact={compact}
|
|
81
|
+
onChange={(value) => { setCompactTokens(value); setError(null); }} />
|
|
82
|
+
</div>
|
|
83
|
+
<p id="codex-context-help" className={`${helpSize} text-muted-foreground`}>
|
|
84
|
+
Choose Codex default to use Codex configuration and model defaults, or Custom to enter a value.
|
|
85
|
+
Presets are shortcuts, not a list of limits supported by your model;
|
|
86
|
+
increasing these values does not unlock a larger context window.
|
|
87
|
+
Applies to new sessions and sessions resumed after a PPM restart.
|
|
88
|
+
</p>
|
|
89
|
+
{error && <p role="alert" className={`${textSize} text-error`}>{error}</p>}
|
|
90
|
+
<div className="flex flex-wrap items-center justify-between gap-2">
|
|
91
|
+
<a href="https://learn.chatgpt.com/docs/config-file/config-reference" target="_blank" rel="noreferrer"
|
|
92
|
+
className={`${helpSize} text-primary underline`}>Codex context documentation</a>
|
|
93
|
+
<button type="submit" disabled={saving}
|
|
94
|
+
className={`min-h-11 sm:min-h-0 rounded-md border border-border px-3 py-1.5 hover:bg-surface-elevated disabled:opacity-50 ${textSize}`}>
|
|
95
|
+
{saving ? "Saving..." : "Save context settings"}
|
|
96
|
+
</button>
|
|
97
|
+
</div>
|
|
98
|
+
</form>
|
|
99
|
+
);
|
|
100
|
+
}
|