@hienlh/ppm 0.19.6 → 0.19.8
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 +13 -0
- package/CLAUDE.md +15 -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-D65EHybd.js +1 -0
- package/dist/web/assets/{ai-resource-editor-BeoI2Jp8.js → ai-resource-editor-DmOGQ_1E.js} +1 -1
- package/dist/web/assets/{ai-settings-section-Bc91w0K4.js → ai-settings-section-DP53HaV9.js} +1 -1
- package/dist/web/assets/{ai-settings-section-edmjpNtG.js → ai-settings-section-Dlv_XYy3.js} +1 -1
- package/dist/web/assets/{angular-html-BuHNQIbQ.js → angular-html-C8nsn2VC.js} +1 -1
- package/dist/web/assets/{angular-ts-DHRWoLc-.js → angular-ts-Caw9nRCH.js} +1 -1
- package/dist/web/assets/{apl-C1VSWVei.js → apl-Dhu1LORF.js} +1 -1
- package/dist/web/assets/{appearance-settings-section-CvX5XncT.js → appearance-settings-section-WuJwZW7v.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-BZBxtErN.js +1 -0
- package/dist/web/assets/{astro-RX-rChsZ.js → astro-DwkX9sLZ.js} +1 -1
- package/dist/web/assets/{audio-preview-CCd1jdje.js → audio-preview-CkGZO8Uy.js} +1 -1
- package/dist/web/assets/{blade-CZ6bxMbK.js → blade-D1fC9Osx.js} +1 -1
- package/dist/web/assets/{bsl-BhgCXLWk.js → bsl-pur-PRip.js} +1 -1
- package/dist/web/assets/{cairo-BrwygPkn.js → cairo-DDJs9amR.js} +1 -1
- package/dist/web/assets/chat-tab-B3tKoaUT.js +15 -0
- package/dist/web/assets/{cobol-C5TGW1Ir.js → cobol-Bo0usdoM.js} +1 -1
- package/dist/web/assets/code-editor-8BjOSWul.js +7 -0
- package/dist/web/assets/{coffee-CFgKlmgI.js → coffee-DBBsbX1e.js} +1 -1
- package/dist/web/assets/{conflict-editor-Dwogm7g8.js → conflict-editor-D2JPf7dR.js} +1 -1
- package/dist/web/assets/{cpp-BhG5q3-d.js → cpp-6CTO78A-.js} +1 -1
- package/dist/web/assets/{crystal-DvuI7_tY.js → crystal-DAlvpAP7.js} +1 -1
- package/dist/web/assets/{csv-preview-CcgWfErD.js → csv-preview-DfHSVE7o.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-DP1xkog4.js → data-grid-overlay-editor-iRrpAV0e.js} +1 -1
- package/dist/web/assets/{database-viewer-DXlx5CrZ.js → database-viewer-BwSf-V1L.js} +1 -1
- package/dist/web/assets/{diff-viewer-tYKO0wXX.js → diff-viewer-CQU6j7uQ.js} +1 -1
- package/dist/web/assets/{edge-BSIEsmlI.js → edge-D0tZrpC7.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-DeHb85DN.js → edit-diff-preview-DUgmjNre.js} +1 -1
- package/dist/web/assets/{elixir-BF-lrGXM.js → elixir-C1E6-o4G.js} +1 -1
- package/dist/web/assets/{elm-8mCsJOeN.js → elm-BKyTfeQX.js} +1 -1
- package/dist/web/assets/{erb-Dw5PUVKa.js → erb-Cdnr4BMI.js} +1 -1
- package/dist/web/assets/{erlang-BvjBIA6O.js → erlang-N1237mFq.js} +1 -1
- package/dist/web/assets/{esm-Bt9OwSnU.js → esm-ClNnmD9t.js} +1 -1
- package/dist/web/assets/{explorer-body-BPnA8ztG.js → explorer-body-B2FmdPAx.js} +2 -2
- package/dist/web/assets/{explorer-window-content-BMPhgAnl.js → explorer-window-content-CtSMepys.js} +1 -1
- package/dist/web/assets/{extension-manager-section-Cepy9w0W.js → extension-manager-section-CBRXxG8W.js} +1 -1
- package/dist/web/assets/{extension-webview-83orjfAz.js → extension-webview-yfMof39w.js} +1 -1
- package/dist/web/assets/{files-settings-section-A_5QWv4b.js → files-settings-section-Dxn0H4jj.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-CRjUJe9K.js → fortran-fixed-form-D_f9tVv0.js} +1 -1
- package/dist/web/assets/{fsharp-CjUIHIHp.js → fsharp-DEJmdhc2.js} +1 -1
- package/dist/web/assets/{gdresource-x_NUQFrZ.js → gdresource-Dmmrx2gP.js} +1 -1
- package/dist/web/assets/general-settings-section-C3ccyyOe.js +1 -0
- package/dist/web/assets/{git-commit-BOpxSbns.js → git-commit-qwJ867ig.js} +1 -1
- package/dist/web/assets/{git-log-panel-D9iuuwL4.js → git-log-panel-d2XBsNFP.js} +1 -1
- package/dist/web/assets/{git-rebase-BW4xlK7k.js → git-rebase-Dkv8Zw86.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BHxJbXfV.js +1 -0
- package/dist/web/assets/{glide-data-grid-Ch5Ap1WP.js → glide-data-grid-5Un6IKEP.js} +7 -7
- package/dist/web/assets/{glimmer-js-CT9jrmFj.js → glimmer-js-CcrXn8lQ.js} +1 -1
- package/dist/web/assets/{glimmer-ts-CjQT1lxK.js → glimmer-ts-CLab3lU7.js} +1 -1
- package/dist/web/assets/{glsl-DsFJvtg5.js → glsl-DXhkG9dU.js} +1 -1
- package/dist/web/assets/{graphql-Dhlnmkn_.js → graphql-Cuqsx8r3.js} +1 -1
- package/dist/web/assets/group-chat-tab-COcbheaZ.js +1 -0
- package/dist/web/assets/{hack-BKHbsJ7u.js → hack-C_CBVdBc.js} +1 -1
- package/dist/web/assets/{haml-C1Ih25Y2.js → haml-CBWfzZpv.js} +1 -1
- package/dist/web/assets/{handlebars-CaFitvmC.js → handlebars-4e8OR-VI.js} +1 -1
- package/dist/web/assets/{html-BwpKIE6V.js → html-C5X4urn_.js} +1 -1
- package/dist/web/assets/{html-derivative-uuTEquZU.js → html-derivative-nH-jXfsL.js} +1 -1
- package/dist/web/assets/{http-Cv4Pg5cR.js → http-CQgaG7eu.js} +1 -1
- package/dist/web/assets/{hurl-DubkI6TG.js → hurl-B8gidJhu.js} +1 -1
- package/dist/web/assets/{hxml-B9OVZFAB.js → hxml-BAK94GX8.js} +1 -1
- package/dist/web/assets/{image-preview-DRbZ0FA2.js → image-preview-1kGj4W9R.js} +1 -1
- package/dist/web/assets/{index-LEL-8oU_.js → index-DB-bD6Cx.js} +24 -24
- package/dist/web/assets/index-N-pnuwFP.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-DI4p3vbH.js +1 -0
- package/dist/web/assets/{jinja-BHb1jyl6.js → jinja-BuAjvj8M.js} +1 -1
- package/dist/web/assets/{jira-watcher-section-DznCP9IR.js → jira-watcher-section-BmDvZZ76.js} +1 -1
- package/dist/web/assets/{jison-CtpfXDzp.js → jison-Dhhs26-L.js} +1 -1
- package/dist/web/assets/{julia-TYjgpazU.js → julia-gZavIyll.js} +1 -1
- package/dist/web/assets/{just-D27bzZuW.js → just-DDHrFReO.js} +1 -1
- package/dist/web/assets/{keybindings-store-BUeQf1S6.js → keybindings-store-DAMW7K3e.js} +1 -1
- package/dist/web/assets/{keyboard-shortcuts-section-C-BeYTwO.js → keyboard-shortcuts-section-BsZKKzf2.js} +1 -1
- package/dist/web/assets/{latex-D_MzopTn.js → latex-BdGZa8ov.js} +1 -1
- package/dist/web/assets/{liquid-BG_FG0Pe.js → liquid-urFfd9Fr.js} +1 -1
- package/dist/web/assets/{lua-Bl29oC2L.js → lua-CcS6tnB5.js} +1 -1
- package/dist/web/assets/{markdown-renderer-B47WcMMs.js → markdown-renderer-BtrHvth9.js} +3 -3
- package/dist/web/assets/{markdown-renderer-Dcq0J7Yw.js → markdown-renderer-Dy4Vz3VW.js} +1 -1
- package/dist/web/assets/{marko-D-HI7dbm.js → marko-CSQqk4oG.js} +1 -1
- package/dist/web/assets/{mdc-y444JQTQ.js → mdc-CYIe80m_.js} +1 -1
- package/dist/web/assets/{mobile-bottom-sheet-BD5b7KJF.js → mobile-bottom-sheet-B3uDlD79.js} +1 -1
- package/dist/web/assets/{mobile-explorer-sheet-RG64iGIe.js → mobile-explorer-sheet-BL1t1Ptr.js} +1 -1
- package/dist/web/assets/{nextflow-C5sKcldC.js → nextflow-C-W8vX8I.js} +1 -1
- package/dist/web/assets/{nginx-bXnEC3wm.js → nginx-COGi5you.js} +1 -1
- package/dist/web/assets/{nim-pevhf4WD.js → nim-CPitYGel.js} +1 -1
- package/dist/web/assets/{notification-store-CmvMzpl2.js → notification-store-DIwuBHMP.js} +1 -1
- package/dist/web/assets/{notifications-settings-section--zzeoLfi.js → notifications-settings-section-CpnG8Ep4.js} +1 -1
- package/dist/web/assets/{number-overlay-editor-B7WINIW4.js → number-overlay-editor-C_eD-Bdr.js} +1 -1
- package/dist/web/assets/{overview-panel-mhN0qw6Q.js → overview-panel-Cm2HRtEz.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-YNQWTi_-.js +1 -0
- package/dist/web/assets/{pdf-preview-CGn99JWL.js → pdf-preview-9Olujr_E.js} +1 -1
- package/dist/web/assets/{perl-B1KUtMnW.js → perl-B0yW3hbb.js} +1 -1
- package/dist/web/assets/{php-BGmVZBAJ.js → php-BNMYN5Jp.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-E3Wiw76n.js +1 -0
- package/dist/web/assets/{postgres-viewer-D-mPRQRC.js → postgres-viewer-qQtI_Qan.js} +3 -3
- package/dist/web/assets/{ppmbot-settings-section-Dy1CBG9d.js → ppmbot-settings-section-C_yNqYo1.js} +1 -1
- package/dist/web/assets/{process-table-DSLrAJC5.js → process-table-DH95ASxx.js} +1 -1
- package/dist/web/assets/{proxy-settings-section-COr2LOQV.js → proxy-settings-section-7OpR2hAD.js} +1 -1
- package/dist/web/assets/{pug-BfN8CpEH.js → pug-CP5fxsxD.js} +1 -1
- package/dist/web/assets/{qml-D6fRdLZt.js → qml-CHGpQosY.js} +1 -1
- package/dist/web/assets/{query-audit-section-CShd9Vo1.js → query-audit-section-CHncxP-Z.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-BPQJUKON.js +1 -0
- package/dist/web/assets/{razor-fg-9AScR.js → razor-Cfe0AYo4.js} +1 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-Db21Gh-Y.js +2 -0
- package/dist/web/assets/{remote-desktop-mobile-view-Dj3n_7MA.js → remote-desktop-mobile-view-CiKtuPVS.js} +1 -1
- package/dist/web/assets/{remote-desktop-readiness-gate-CR2jZ4pW.js → remote-desktop-readiness-gate-BSBIPU4d.js} +1 -1
- package/dist/web/assets/{remote-desktop-window-content-BhQizWi0.js → remote-desktop-window-content-CJOxXllZ.js} +1 -1
- package/dist/web/assets/{rst-BZgx076b.js → rst-DxSSGshb.js} +1 -1
- package/dist/web/assets/{ruby-iUkWDcLo.js → ruby-rbK5SsJa.js} +1 -1
- package/dist/web/assets/{sas-CLXO0lZ6.js → sas-DDM28fbb.js} +1 -1
- package/dist/web/assets/schedules-settings-section-Q5X3kNJ8.js +1 -0
- package/dist/web/assets/{scss-DQqteGaG.js → scss-TDl-6ro4.js} +1 -1
- package/dist/web/assets/settings-body-5804QGDH.js +2 -0
- package/dist/web/assets/settings-store-DWUx3865.js +2 -0
- package/dist/web/assets/settings-tab-DgJP4K6b.js +1 -0
- package/dist/web/assets/settings-window-content-lyNwahx3.js +1 -0
- package/dist/web/assets/{shaderlab-CeMTqagR.js → shaderlab-CCvmDgGS.js} +1 -1
- package/dist/web/assets/{shellsession-BAkquZAV.js → shellsession-BzKS9yKh.js} +1 -1
- package/dist/web/assets/{soy-Bxm9Ez55.js → soy-QfO35nDh.js} +1 -1
- package/dist/web/assets/{sparql-C1phwdLc.js → sparql-D29RDfp2.js} +1 -1
- package/dist/web/assets/sql-query-editor-DH3H3gvx.js +1 -0
- package/dist/web/assets/{sqlite-viewer-Gi8hYwKJ.js → sqlite-viewer-DkmaTXae.js} +1 -1
- package/dist/web/assets/{stata-DGNMQdEb.js → stata-Be6j_SNv.js} +1 -1
- package/dist/web/assets/streaming-store-DDst3zA7.js +1 -0
- package/dist/web/assets/{surrealql-ByVrV320.js → surrealql-CykFjgNG.js} +1 -1
- package/dist/web/assets/{svelte-CNWjIMhl.js → svelte-CdBF8z4-.js} +1 -1
- package/dist/web/assets/system-monitor-body-KuahlPOb.js +2 -0
- package/dist/web/assets/system-monitor-tab-BK-nYh25.js +1 -0
- package/dist/web/assets/{system-monitor-window-content-BUHL5rX-.js → system-monitor-window-content-C5TkD158.js} +1 -1
- package/dist/web/assets/{tab-host-window-content-2gwUy-OA.js → tab-host-window-content-BwDnxvbx.js} +1 -1
- package/dist/web/assets/team-member-sheet-Cg82OxYB.js +2 -0
- package/dist/web/assets/{team-member-window-content-BvqhkPjH.js → team-member-window-content-FxBRzgMW.js} +1 -1
- package/dist/web/assets/{templ-Cf0gQL4I.js → templ-BVHE2CNb.js} +1 -1
- package/dist/web/assets/{terminal-tab-CbHDqCBe.js → terminal-tab-Bro7kJBK.js} +2 -2
- package/dist/web/assets/{tex-BTIqPw_R.js → tex-C8XwrbBw.js} +1 -1
- package/dist/web/assets/{tool-cards-DIoAqDka.js → tool-cards-BDmz33Y9.js} +5 -5
- package/dist/web/assets/treemap-KZPCXAKY-C2CvKBQR.js +1 -0
- package/dist/web/assets/{ts-tags-B8dN_Yf6.js → ts-tags-BIHk5AM0.js} +1 -1
- package/dist/web/assets/{twig-BgemonbJ.js → twig-YcE6Q2Ox.js} +1 -1
- package/dist/web/assets/{use-accounts-data-B8ltBkBj.js → use-accounts-data-CvfdFWm3.js} +1 -1
- package/dist/web/assets/use-monaco-theme-D3Owwbo5.js +1 -0
- package/dist/web/assets/{use-remote-desktop-display-choice--W-pnzPS.js → use-remote-desktop-display-choice-DOg4xZ-8.js} +1 -1
- package/dist/web/assets/{use-websocket-Dek_fwOD.js → use-websocket-4y-ICdd7.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-BKWscKt0.js → vendor-mermaid-CKKtYuTV.js} +1 -1
- package/dist/web/assets/{video-preview-DijwhDXk.js → video-preview-C70-MurL.js} +1 -1
- package/dist/web/assets/{vue-html-DYEQFAiK.js → vue-html-D1y9feOj.js} +1 -1
- package/dist/web/assets/{vue-D3D4lbXz.js → vue-q7m01V0h.js} +1 -1
- package/dist/web/assets/{vue-vine-D0OPNscN.js → vue-vine-DrIGs03v.js} +1 -1
- package/dist/web/assets/{xml-DHaWgpya.js → xml-oyvc1920.js} +1 -1
- package/dist/web/assets/{xsl-DVRN8JsA.js → xsl-BbIGdNPF.js} +1 -1
- package/dist/web/index.html +12 -11
- package/dist/web/sw.js +1 -1
- 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/src/providers/registry.ts +18 -3
- package/src/server/routes/settings.ts +1 -0
- package/src/services/config.service.ts +28 -0
- package/src/services/db.service.ts +39 -2
- package/src/services/edge-forwarder.ts +191 -191
- package/src/services/prod-db-guard.ts +98 -0
- package/src/services/windows-process-tree.ts +351 -351
- package/src/types/config.ts +14 -0
- package/src/web/app.tsx +8 -0
- package/src/web/components/layout/status-bar.tsx +3 -0
- package/src/web/components/layout/wake-lock-indicator.tsx +50 -0
- package/src/web/components/settings/general-settings-section.tsx +37 -3
- package/src/web/hooks/use-wake-lock.ts +148 -0
- package/src/web/stores/settings-store.ts +12 -0
- package/src/web/stores/wake-lock-store.ts +21 -0
- package/dist/web/assets/accounts-settings-section-DGsB-ynw.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-Ca5IpdzP.js +0 -1
- package/dist/web/assets/chat-tab-BHO6ceZp.js +0 -15
- package/dist/web/assets/code-editor-1ZV6iSCc.js +0 -7
- package/dist/web/assets/general-settings-section-CFDRUc2E.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BloZfB0Q.js +0 -1
- package/dist/web/assets/group-chat-tab-CfTivWze.js +0 -1
- package/dist/web/assets/index-nP3uxXvR.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-c0W8wp5o.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-D_BoHr_M.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-BaLfuEf8.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-DBIZEaIU.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-yFKdq8Cb.js +0 -2
- package/dist/web/assets/schedules-settings-section-f6VP9Mde.js +0 -1
- package/dist/web/assets/settings-body-BRJapYD0.js +0 -2
- package/dist/web/assets/settings-store-Brjd0QnO.js +0 -2
- package/dist/web/assets/settings-tab-hHtSuYDb.js +0 -1
- package/dist/web/assets/settings-window-content-CUrGhhKI.js +0 -1
- package/dist/web/assets/sql-query-editor-DxS_r9dM.js +0 -1
- package/dist/web/assets/system-monitor-body-CdWv_LBB.js +0 -2
- package/dist/web/assets/system-monitor-tab-DBMjRETL.js +0 -1
- package/dist/web/assets/team-member-sheet-B-3ri_oc.js +0 -2
- package/dist/web/assets/treemap-KZPCXAKY-DFiG9UYW.js +0 -1
- package/dist/web/assets/use-monaco-theme-2YgX5HEz.js +0 -1
- /package/dist/web/assets/{abap-h3QyH8MW.js → abap-Cq9nYQyd.js} +0 -0
- /package/dist/web/assets/{actionscript-3-mkxkq-FN.js → actionscript-3-DL8rUIy0.js} +0 -0
- /package/dist/web/assets/{ada-DhISK_EH.js → ada-BY8TLuhY.js} +0 -0
- /package/dist/web/assets/{andromeeda-DnlWWesX.js → andromeeda-CyVfHsS0.js} +0 -0
- /package/dist/web/assets/{apache-P5AK3sfA.js → apache-DTQUy73x.js} +0 -0
- /package/dist/web/assets/{apex-CJUPehg2.js → apex-CiSZngrZ.js} +0 -0
- /package/dist/web/assets/{api-settings-CTMdz_VF.js → api-settings-BVfemzZW.js} +0 -0
- /package/dist/web/assets/{api-themes-Cknp3Q-P.js → api-themes-BoOJPqwM.js} +0 -0
- /package/dist/web/assets/{applescript-Dx6GGbay.js → applescript-CzuRDd3h.js} +0 -0
- /package/dist/web/assets/{apply-theme-DxTXOAcV.js → apply-theme-r8tKDrCR.js} +0 -0
- /package/dist/web/assets/{ara-95Kx3qKb.js → ara-CSFV93kR.js} +0 -0
- /package/dist/web/assets/{asciidoc-Dp0RbIej.js → asciidoc-hOQNnXhz.js} +0 -0
- /package/dist/web/assets/{asm-C82coUjU.js → asm-DdG53NGR.js} +0 -0
- /package/dist/web/assets/{aurora-x-BFc3zeop.js → aurora-x-DJ7ORZG6.js} +0 -0
- /package/dist/web/assets/{awk-ChjC0icr.js → awk-B3FFpX_J.js} +0 -0
- /package/dist/web/assets/{ayu-dark-DYfUf_PB.js → ayu-dark-D_P1CfTe.js} +0 -0
- /package/dist/web/assets/{ayu-light-Bh6O0plO.js → ayu-light-Cz3YLUqH.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-DlNhHTGq.js → ayu-mirage-JcMq5tgJ.js} +0 -0
- /package/dist/web/assets/{ballerina-Ceoll3Sk.js → ballerina-7Hs4Rfpk.js} +0 -0
- /package/dist/web/assets/{bat-C7QS6Lfq.js → bat-COgQdnFA.js} +0 -0
- /package/dist/web/assets/{beancount-5NMEAZgs.js → beancount-BJ3CutBG.js} +0 -0
- /package/dist/web/assets/{berry-BBL83Vbk.js → berry-D7so2Cui.js} +0 -0
- /package/dist/web/assets/{bibtex-L7rPkPSG.js → bibtex-Ct3acHa1.js} +0 -0
- /package/dist/web/assets/{bicep-BOwHIINh.js → bicep-jXDwCQcm.js} +0 -0
- /package/dist/web/assets/{bird2-CWLsMom2.js → bird2-CjLD2cna.js} +0 -0
- /package/dist/web/assets/{button-BZtEJcUv.js → button-2WCAS8dI.js} +0 -0
- /package/dist/web/assets/{c-CD4Ku5Cr.js → c-CdgZojnL.js} +0 -0
- /package/dist/web/assets/{c3-CpMl-w3G.js → c3-DtpZYego.js} +0 -0
- /package/dist/web/assets/{cadence-CvgF6ehN.js → cadence-CPLkixoh.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-j3jh7fUo.js → can-open-in-ppm-BntPywsy.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-eo_dTm3F.js → catppuccin-frappe-Xt0_qJa9.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-DoiMCU_7.js → catppuccin-latte-CJnbLec5.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-UQxsK2Vh.js → catppuccin-macchiato-BPHP1wYB.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-J0i-8RNy.js → catppuccin-mocha-ssWJodGc.js} +0 -0
- /package/dist/web/assets/{clarity-DXYM8-SA.js → clarity-DB0408F6.js} +0 -0
- /package/dist/web/assets/{clojure-DzamsL69.js → clojure-dpRPlAO4.js} +0 -0
- /package/dist/web/assets/{cmake-CR6RP_T_.js → cmake-r2VkeX9y.js} +0 -0
- /package/dist/web/assets/{codeowners-D1s6-IyY.js → codeowners-v5nQqHiB.js} +0 -0
- /package/dist/web/assets/{codeql-DAqNWMkS.js → codeql-BSSEhKRR.js} +0 -0
- /package/dist/web/assets/{common-lisp-8e-KtitB.js → common-lisp-BXb2MMMA.js} +0 -0
- /package/dist/web/assets/{coq-UEq0WUcO.js → coq-BjBNi73X.js} +0 -0
- /package/dist/web/assets/{csharp-wxJ0TuCm.js → csharp-CdPjZRbV.js} +0 -0
- /package/dist/web/assets/{css-Cerub-yB.js → css-BuxbQOHL.js} +0 -0
- /package/dist/web/assets/{csv-Bh9_WD_h.js → csv-Dj-eoZwH.js} +0 -0
- /package/dist/web/assets/{csv-parser-BPIDt6ni.js → csv-parser-CBbALsFU.js} +0 -0
- /package/dist/web/assets/{cue-rzM1ztqU.js → cue-Dz73VksN.js} +0 -0
- /package/dist/web/assets/{cypher-DGaTQ8m0.js → cypher-CkVkDywZ.js} +0 -0
- /package/dist/web/assets/{d-DbkZGuhB.js → d-oU51Pbpf.js} +0 -0
- /package/dist/web/assets/{dark-plus-BO2bzZcA.js → dark-plus-DcwvjjfO.js} +0 -0
- /package/dist/web/assets/{dart-BDhCoqVg.js → dart-DGvu8mcX.js} +0 -0
- /package/dist/web/assets/{data-grid-types-CdAg-4W1.js → data-grid-types-B6kUrF-M.js} +0 -0
- /package/dist/web/assets/{dax-Bh03stWh.js → dax-BmbjKQ90.js} +0 -0
- /package/dist/web/assets/{desktop-BOdr_fwq.js → desktop-IRBSiFfh.js} +0 -0
- /package/dist/web/assets/{diff-Bb_gTsS2.js → diff-Bdik2JR8.js} +0 -0
- /package/dist/web/assets/{dist-DonmFWG8.js → dist-Bv4zQpS1.js} +0 -0
- /package/dist/web/assets/{dist-BUMDu0av.js → dist-C8YPBIOb.js} +0 -0
- /package/dist/web/assets/{docker-BDsTF5ce.js → docker-Bgdl0H8I.js} +0 -0
- /package/dist/web/assets/{docx-preview-CWIDVNZn.js → docx-preview-Bgw838ry.js} +0 -0
- /package/dist/web/assets/{dotenv-CbCWp9Ti.js → dotenv-COe5NdnA.js} +0 -0
- /package/dist/web/assets/{dracula-Cd1fxvoX.js → dracula-DjURaSAa.js} +0 -0
- /package/dist/web/assets/{dracula-soft-B7eXkfXG.js → dracula-soft-Do7d0bo-.js} +0 -0
- /package/dist/web/assets/{dream-maker-XlzuS21R.js → dream-maker-DYwQvJIj.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CXV1Ki_7.js → emacs-lisp-BXjlHyDW.js} +0 -0
- /package/dist/web/assets/{everforest-dark-DuqR60Dg.js → everforest-dark-h8Q2loiX.js} +0 -0
- /package/dist/web/assets/{everforest-light-q4BPnenD.js → everforest-light-CdsJiL-9.js} +0 -0
- /package/dist/web/assets/{fennel-B-e0TX2Q.js → fennel-D0CBtOvY.js} +0 -0
- /package/dist/web/assets/{fish-Bzb6-TtF.js → fish-DzayfrMj.js} +0 -0
- /package/dist/web/assets/{fluent-B-szH2-f.js → fluent-CatjkUfx.js} +0 -0
- /package/dist/web/assets/{format-bytes-CKXk9k2d.js → format-bytes-BulRSULX.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-OS6SGYC0.js → fortran-free-form-DM04ud0b.js} +0 -0
- /package/dist/web/assets/{gdscript-FYq4OP2d.js → gdscript-BLN5iZwf.js} +0 -0
- /package/dist/web/assets/{gdshader-BpG6P8rw.js → gdshader-BK-1iZQs.js} +0 -0
- /package/dist/web/assets/{genie-BS9RLAna.js → genie-BGPOFWDN.js} +0 -0
- /package/dist/web/assets/{gherkin-B_9FdtGs.js → gherkin-CdVOJ_JY.js} +0 -0
- /package/dist/web/assets/{github-dark-cfaIlnBV.js → github-dark-B_xW8TaY.js} +0 -0
- /package/dist/web/assets/{github-dark-default-B2Wv65He.js → github-dark-default-h_iKq7CX.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-CtM9X76s.js → github-dark-dimmed-nKDYE62T.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-DLHyk0tG.js → github-dark-high-contrast-l8I771QT.js} +0 -0
- /package/dist/web/assets/{github-light-DWEI10iG.js → github-light-DNhjkg8Z.js} +0 -0
- /package/dist/web/assets/{github-light-default-DcJkK1YN.js → github-light-default-DQ06uS3g.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-Bcx9iKDt.js → github-light-high-contrast-qc2sZCVN.js} +0 -0
- /package/dist/web/assets/{gleam-DVpiM6b2.js → gleam-DPPatkNH.js} +0 -0
- /package/dist/web/assets/{gn-B80DNc0i.js → gn-BnzGQTy5.js} +0 -0
- /package/dist/web/assets/{gnuplot-D9i3MaT-.js → gnuplot-Ct1leoo3.js} +0 -0
- /package/dist/web/assets/{go-CwCBf_Pt.js → go-qysCdbrn.js} +0 -0
- /package/dist/web/assets/{groovy-D7mEfwmW.js → groovy-BkWIdrRQ.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-C4R4MOoH.js → gruvbox-dark-hard-L6Iiybbl.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-CZnFC0s8.js → gruvbox-dark-medium-DbD3yl0b.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-DFcJlEBl.js → gruvbox-dark-soft-Ban2cHK3.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-B6IF_1L-.js → gruvbox-light-hard-CK_SjS3e.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-C19AZJv2.js → gruvbox-light-medium-Bjgvhc2w.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-BAnpDm9B.js → gruvbox-light-soft-EWnyYGUu.js} +0 -0
- /package/dist/web/assets/{haskell-CsXSYXRG.js → haskell-rT1N9nYr.js} +0 -0
- /package/dist/web/assets/{haxe-B1uyiI9t.js → haxe-Bbc91axo.js} +0 -0
- /package/dist/web/assets/{hcl-DlYKn5q9.js → hcl-D-3qJA4v.js} +0 -0
- /package/dist/web/assets/{hjson-C_0VMGJJ.js → hjson-DWtewcyQ.js} +0 -0
- /package/dist/web/assets/{hlsl-zt2PEzbg.js → hlsl-C7t6hCrO.js} +0 -0
- /package/dist/web/assets/{horizon-bright-CqI2qTim.js → horizon-bright-CRNyrJy8.js} +0 -0
- /package/dist/web/assets/{horizon-6wQfyOK0.js → horizon-zJAGUQ3j.js} +0 -0
- /package/dist/web/assets/{houston-BljpHDoG.js → houston-BFKa4W1-.js} +0 -0
- /package/dist/web/assets/{hy-XzuL55dw.js → hy-W1hNjMBM.js} +0 -0
- /package/dist/web/assets/{image-gallery-Cj8nd4xW.js → image-gallery-BycaVWOu.js} +0 -0
- /package/dist/web/assets/{imba-CqhhjBrP.js → imba-CPphaV-V.js} +0 -0
- /package/dist/web/assets/{ini-CiFDi6cY.js → ini-CayaZ4vW.js} +0 -0
- /package/dist/web/assets/{java-OsQgTL5-.js → java-BPAE_9Ej.js} +0 -0
- /package/dist/web/assets/{javascript-qWAOScxl.js → javascript-C5SKIVqe.js} +0 -0
- /package/dist/web/assets/{json-RiAKsaD1.js → json-C-0EUYmu.js} +0 -0
- /package/dist/web/assets/{json5-BeCnS3H2.js → json5-BqVetEZL.js} +0 -0
- /package/dist/web/assets/{jsonc-CbTW1Mka.js → jsonc-DnjIzkUB.js} +0 -0
- /package/dist/web/assets/{jsonl-BLSi_669.js → jsonl-rbV-3EqO.js} +0 -0
- /package/dist/web/assets/{jsonnet-C3xAggou.js → jsonnet-9hvXw4qr.js} +0 -0
- /package/dist/web/assets/{jssm-CLdiagC9.js → jssm-1ifXyIhu.js} +0 -0
- /package/dist/web/assets/{jsx-lYE1lb50.js → jsx-hPumywTY.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-Cd1vcrpD.js → kanagawa-dragon-BCPjmoMO.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-Dw3QKtk9.js → kanagawa-lotus-DN2VNjy7.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-DIq5Zv5G.js → kanagawa-wave-B8RZEsgc.js} +0 -0
- /package/dist/web/assets/{kdl-BfDV0825.js → kdl-CkvjWQIa.js} +0 -0
- /package/dist/web/assets/{kotlin-DONxR4wD.js → kotlin-D8cnRi5o.js} +0 -0
- /package/dist/web/assets/{kusto-BDP63Fh5.js → kusto-CmeeBEJG.js} +0 -0
- /package/dist/web/assets/{laserwave-BeBrWApL.js → laserwave--rtV8Mv9.js} +0 -0
- /package/dist/web/assets/{lean-DOZc0N1A.js → lean-CS-Pyi42.js} +0 -0
- /package/dist/web/assets/{less-C3H9NlDv.js → less-Ddi_7qGm.js} +0 -0
- /package/dist/web/assets/{lib-xrSJ4EZX.js → lib-DIrxSyLb.js} +0 -0
- /package/dist/web/assets/{libesm-DLBE59ul.js → libesm-CYLrAeW3.js} +0 -0
- /package/dist/web/assets/{light-plus-C_kTL608.js → light-plus-CrEjpkkX.js} +0 -0
- /package/dist/web/assets/{llvm-Dsp27U3P.js → llvm-Cm7ZXmAO.js} +0 -0
- /package/dist/web/assets/{log-BywQaTCy.js → log-lW2sYxtp.js} +0 -0
- /package/dist/web/assets/{logo-BirJgciO.js → logo-B-PiRb53.js} +0 -0
- /package/dist/web/assets/{luau-Btrz5kJB.js → luau-8St0pC-R.js} +0 -0
- /package/dist/web/assets/{make-Kl7nFQrS.js → make-DbNdhH54.js} +0 -0
- /package/dist/web/assets/{markdown-qsC4P8S-.js → markdown-CYocYSGd.js} +0 -0
- /package/dist/web/assets/{material-theme-CC__ui3p.js → material-theme-CVBF1Cbi.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-D4FxG2FZ.js → material-theme-darker-HFrlNZD8.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-zGqiWcxn.js → material-theme-lighter-BM-uz2ft.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-CZIdTTB1.js → material-theme-ocean-PbvUez8m.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-CEIs0GcK.js → material-theme-palenight-B22Ck6qd.js} +0 -0
- /package/dist/web/assets/{matlab-Cf0aUjN9.js → matlab-GFFNzucw.js} +0 -0
- /package/dist/web/assets/{mdx-CIsXjH86.js → mdx-BVnJzMDx.js} +0 -0
- /package/dist/web/assets/{media-url-VzecHk9g.js → media-url-DBmHJRft.js} +0 -0
- /package/dist/web/assets/{mermaid-B06WO9Qc.js → mermaid-BlCmSTCM.js} +0 -0
- /package/dist/web/assets/{min-dark-z8fyp0FT.js → min-dark-B0PwlAfC.js} +0 -0
- /package/dist/web/assets/{min-light-Dr-qesbW.js → min-light-C_H2ABKu.js} +0 -0
- /package/dist/web/assets/{mipsasm-CWHzYLcE.js → mipsasm-C3rf2fo6.js} +0 -0
- /package/dist/web/assets/{mojo-D9zXrKmv.js → mojo-CDRuzM3o.js} +0 -0
- /package/dist/web/assets/{monokai-4b-AKOpX.js → monokai-KiebNy_Y.js} +0 -0
- /package/dist/web/assets/{moonbit-Dl4dhOZJ.js → moonbit-CdVUHoWl.js} +0 -0
- /package/dist/web/assets/{move-DTYKJmXy.js → move-Dq9iKZRY.js} +0 -0
- /package/dist/web/assets/{narrat-DnvXOS-o.js → narrat-7y5L5sGM.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-Di8QnEXg.js → nextflow-groovy-Cwcbkcrx.js} +0 -0
- /package/dist/web/assets/{night-owl-Czh0yq-H.js → night-owl-TBgLPzj4.js} +0 -0
- /package/dist/web/assets/{night-owl-light-D_OpZqOR.js → night-owl-light-Dehb9My2.js} +0 -0
- /package/dist/web/assets/{nix-2MvcjpK3.js → nix-BKj-gzoX.js} +0 -0
- /package/dist/web/assets/{nord-CG_r4cyk.js → nord-BF_r8PeX.js} +0 -0
- /package/dist/web/assets/{nushell-DINskMcU.js → nushell-CeAjk9_E.js} +0 -0
- /package/dist/web/assets/{objective-c-Dv7BIicR.js → objective-c-Xl1OMcDp.js} +0 -0
- /package/dist/web/assets/{objective-cpp-CpqsCxPb.js → objective-cpp-C4ZgzrRq.js} +0 -0
- /package/dist/web/assets/{ocaml-DwTsYSmW.js → ocaml-CGj8IYTq.js} +0 -0
- /package/dist/web/assets/{odin-G-4O4k4t.js → odin-C4veqvW2.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-13Pv5SjI.js → one-dark-pro-gAcWejsV.js} +0 -0
- /package/dist/web/assets/{one-light-Bi2e86mS.js → one-light-B7E-UUXy.js} +0 -0
- /package/dist/web/assets/{openscad-D0WsOTij.js → openscad-C-wN9BEv.js} +0 -0
- /package/dist/web/assets/{pascal-DmDStuXr.js → pascal-C8WBtxMs.js} +0 -0
- /package/dist/web/assets/{pkl-Bl6Qjtuo.js → pkl-BBfF4G2A.js} +0 -0
- /package/dist/web/assets/{plastic-UeSVSjTI.js → plastic-DFOAb89P.js} +0 -0
- /package/dist/web/assets/{plsql-DreFC689.js → plsql-BS2CEMMV.js} +0 -0
- /package/dist/web/assets/{po-ZIjccxsX.js → po-BKJDtPmy.js} +0 -0
- /package/dist/web/assets/{poimandres-CvQHJPrI.js → poimandres-Cg3hL13e.js} +0 -0
- /package/dist/web/assets/{polar-BrMB0Kgh.js → polar-B9ebiXUU.js} +0 -0
- /package/dist/web/assets/{postcss-pgUsil1T.js → postcss-B5REwNY_.js} +0 -0
- /package/dist/web/assets/{powerquery-CTsZkCg_.js → powerquery-stc0Gzkf.js} +0 -0
- /package/dist/web/assets/{powershell-CcwVuBAp.js → powershell-jgd0ahJN.js} +0 -0
- /package/dist/web/assets/{prisma-spjnAI5W.js → prisma-CWuZjRhI.js} +0 -0
- /package/dist/web/assets/{prolog-ChCkZpDO.js → prolog-D5zNFE63.js} +0 -0
- /package/dist/web/assets/{proto-wVGqK4gB.js → proto-B-6RrU7n.js} +0 -0
- /package/dist/web/assets/{puppet-CED7iwPQ.js → puppet-DONP8TDR.js} +0 -0
- /package/dist/web/assets/{purescript-u9lGiQKV.js → purescript-DDJITf-A.js} +0 -0
- /package/dist/web/assets/{python-DeqTx6ef.js → python-bmWy9j1-.js} +0 -0
- /package/dist/web/assets/{qmldir-BH1uoPrX.js → qmldir-CKDwMt7X.js} +0 -0
- /package/dist/web/assets/{qss-CUVKA_13.js → qss-DptQQzBn.js} +0 -0
- /package/dist/web/assets/{r-BqdPzqYH.js → r-BorKpJ8r.js} +0 -0
- /package/dist/web/assets/{racket-C2eTgPN3.js → racket-BaHpYVsZ.js} +0 -0
- /package/dist/web/assets/{raku-uAay1sWx.js → raku-DFJIV4k_.js} +0 -0
- /package/dist/web/assets/{red-DTZP1ZfC.js → red-70oJGrkb.js} +0 -0
- /package/dist/web/assets/{reg-Cdk3YsxY.js → reg-C4g235Dv.js} +0 -0
- /package/dist/web/assets/{regexp-Bpa2aS7K.js → regexp-Cw1UVmti.js} +0 -0
- /package/dist/web/assets/{rel-bNsb1-3L.js → rel-DeLhIz5L.js} +0 -0
- /package/dist/web/assets/{resolve-theme-DQk_YcsT.js → resolve-theme-b_yGlUFQ.js} +0 -0
- /package/dist/web/assets/{riscv-DSaubByW.js → riscv-ChnTiBRK.js} +0 -0
- /package/dist/web/assets/{ron-DbQzYM6i.js → ron-C5IWeqDn.js} +0 -0
- /package/dist/web/assets/{rose-pine-C7RsprTu.js → rose-pine-DCR0ohYW.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-VP976YzL.js → rose-pine-dawn-DvGZs1PR.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-XHZNhOqd.js → rose-pine-moon-BWACHjeS.js} +0 -0
- /package/dist/web/assets/{rosmsg-BVQlx0Lj.js → rosmsg-CQlIVazE.js} +0 -0
- /package/dist/web/assets/{run-in-terminal-bKRwuO2z.js → run-in-terminal-DHAvC1AG.js} +0 -0
- /package/dist/web/assets/{rust-VHaQ3rh3.js → rust-DGGVzWI8.js} +0 -0
- /package/dist/web/assets/{sass-CO-kMkwD.js → sass-bj1C0rFI.js} +0 -0
- /package/dist/web/assets/{scala-cY0GXkiz.js → scala-MU1tLKDi.js} +0 -0
- /package/dist/web/assets/{scheme-D4LNZE0X.js → scheme-CeGXtv7t.js} +0 -0
- /package/dist/web/assets/{sdbl-Bh2Fd2cn.js → sdbl-D0HLSGKp.js} +0 -0
- /package/dist/web/assets/{send-to-chat-S8LCNX7V.js → send-to-chat-BOyUWNKw.js} +0 -0
- /package/dist/web/assets/{separator-DqGg3f9c.js → separator-BzGoTlR7.js} +0 -0
- /package/dist/web/assets/{shellscript-KKclmCnt.js → shellscript-DkYiDvh1.js} +0 -0
- /package/dist/web/assets/{slack-dark-D6YQ-fqf.js → slack-dark-YqeHiGWH.js} +0 -0
- /package/dist/web/assets/{slack-ochin-CDf66CDj.js → slack-ochin-9Oe0DljJ.js} +0 -0
- /package/dist/web/assets/{smalltalk-D2OH_QIl.js → smalltalk-CaaxedR7.js} +0 -0
- /package/dist/web/assets/{snazzy-light-CQeF8G1K.js → snazzy-light-C8s2FHNC.js} +0 -0
- /package/dist/web/assets/{solarized-dark-LTPf1iLZ.js → solarized-dark-0ryY6oN3.js} +0 -0
- /package/dist/web/assets/{solarized-light-Ose1n88k.js → solarized-light-bltgZeNh.js} +0 -0
- /package/dist/web/assets/{solidity-lFuOMHki.js → solidity-DOf5HmLZ.js} +0 -0
- /package/dist/web/assets/{splunk-Bov-sB5S.js → splunk-D1u4WHDW.js} +0 -0
- /package/dist/web/assets/{sql-BKyZ6wmk.js → sql-G8uQZljX.js} +0 -0
- /package/dist/web/assets/{ssh-config-CqJoMGMb.js → ssh-config-rbXvly7Q.js} +0 -0
- /package/dist/web/assets/{stylus-Bf5pWRLI.js → stylus-Cii1iADy.js} +0 -0
- /package/dist/web/assets/{swift-D5d1hn_u.js → swift-DpIgonN4.js} +0 -0
- /package/dist/web/assets/{synthwave-84-B4c6YAgO.js → synthwave-84-DjGLzU2b.js} +0 -0
- /package/dist/web/assets/{system-verilog-D7fXyDsI.js → system-verilog-_Z0M0Hs1.js} +0 -0
- /package/dist/web/assets/{systemd-oNagzlBK.js → systemd-BhyDCh9P.js} +0 -0
- /package/dist/web/assets/{talonscript-C6Nqm9Dm.js → talonscript-CNchgCRD.js} +0 -0
- /package/dist/web/assets/{tasl-CaWy-cBX.js → tasl-m--W7Pyr.js} +0 -0
- /package/dist/web/assets/{tcl-C435P5Mq.js → tcl-gY-M_2BC.js} +0 -0
- /package/dist/web/assets/{terraform-CVDxqdPf.js → terraform-CB6CzMwo.js} +0 -0
- /package/dist/web/assets/{tokyo-night-Uhs17tQ3.js → tokyo-night-COh9oRYi.js} +0 -0
- /package/dist/web/assets/{toml-j6fPOJ6P.js → toml-Bg2bsY-v.js} +0 -0
- /package/dist/web/assets/{tsv-h78O6xrL.js → tsv-DceGDiJC.js} +0 -0
- /package/dist/web/assets/{tsx-Bol-vCrQ.js → tsx-EccDYa7i.js} +0 -0
- /package/dist/web/assets/{turtle-Dw8eFf04.js → turtle-C_l2JhvX.js} +0 -0
- /package/dist/web/assets/{typescript-Dtz7DPci.js → typescript-C1ytmMcr.js} +0 -0
- /package/dist/web/assets/{typespec-BIOQ7dMP.js → typespec-De2ztzG5.js} +0 -0
- /package/dist/web/assets/{typst-CoaGMjzu.js → typst-DNcS7gSr.js} +0 -0
- /package/dist/web/assets/{use-blob-url-Gfi69PtP.js → use-blob-url-De-ZtcpX.js} +0 -0
- /package/dist/web/assets/{use-open-team-member-CruUTqzD.js → use-open-team-member-DWhhWdmJ.js} +0 -0
- /package/dist/web/assets/{use-visual-viewport-rnvuooQZ.js → use-visual-viewport-D9O48HQt.js} +0 -0
- /package/dist/web/assets/{v-BoqFdpJ7.js → v-DSMUsdMO.js} +0 -0
- /package/dist/web/assets/{vala-COBpNnCC.js → vala-BEazLpkO.js} +0 -0
- /package/dist/web/assets/{vb-DxI86znh.js → vb-CV9pEJzW.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-BaMOj65g.js → vendor-xterm-cuGQmUjN.js} +0 -0
- /package/dist/web/assets/{verilog-DcTAamuQ.js → verilog-DhXkLVMk.js} +0 -0
- /package/dist/web/assets/{vesper-DO298JSv.js → vesper-n4IltYq-.js} +0 -0
- /package/dist/web/assets/{vhdl-Dq-bDVSN.js → vhdl-CePjFbvs.js} +0 -0
- /package/dist/web/assets/{viml-zHTRWuQh.js → viml-ChndFsm5.js} +0 -0
- /package/dist/web/assets/{vitesse-black-jlYMJCBf.js → vitesse-black-BytVdvhC.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-DS0sUlSZ.js → vitesse-dark-83Wech0N.js} +0 -0
- /package/dist/web/assets/{vitesse-light-HSeZ2YhG.js → vitesse-light-Xg4wbeMO.js} +0 -0
- /package/dist/web/assets/{vyper-BQfKVO3M.js → vyper-eW1NC3FG.js} +0 -0
- /package/dist/web/assets/{wasm-B6mCuI8h.js → wasm-Bhucqu1z.js} +0 -0
- /package/dist/web/assets/{wasm-B1xp9bLp.js → wasm-BucxKwBZ.js} +0 -0
- /package/dist/web/assets/{wenyan-CfpS05sP.js → wenyan-BJFBuXuH.js} +0 -0
- /package/dist/web/assets/{wgsl-14GDsWRD.js → wgsl-6z4FUyMK.js} +0 -0
- /package/dist/web/assets/{wikitext-Ccbq5EVX.js → wikitext-BoDU6teJ.js} +0 -0
- /package/dist/web/assets/{window-pip-registry-BEN0QNSW.js → window-pip-registry-CSLhJfpL.js} +0 -0
- /package/dist/web/assets/{wit-C19hb3R5.js → wit-DerMPpgt.js} +0 -0
- /package/dist/web/assets/{wolfram-B-ZSwGwP.js → wolfram-D78v0Ap-.js} +0 -0
- /package/dist/web/assets/{ws-auth-Dawx17PM.js → ws-auth-ZSZkAT6p.js} +0 -0
- /package/dist/web/assets/{yaml-mw_JUeio.js → yaml-C4TIgIw4.js} +0 -0
- /package/dist/web/assets/{zenscript-WbzDRjvF.js → zenscript-BydW-dLC.js} +0 -0
- /package/dist/web/assets/{zig-F0vvImTJ.js → zig-b9lTqL5E.js} +0 -0
package/src/types/config.ts
CHANGED
|
@@ -111,6 +111,20 @@ export interface AIProviderConfig {
|
|
|
111
111
|
cli_command?: string;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Model a new codex session uses unless the picker says otherwise.
|
|
116
|
+
*
|
|
117
|
+
* Codex is registered at runtime rather than shipped in DEFAULT_CONFIG — it only
|
|
118
|
+
* exists once `@openai/codex` is installed — so its default lives here, beside
|
|
119
|
+
* Claude's, instead of being invisible inside the registration code.
|
|
120
|
+
*
|
|
121
|
+
* Deliberately not codex's own default, which is its most capable model and
|
|
122
|
+
* bills accordingly; codex describes this one as its balanced agentic coding
|
|
123
|
+
* model for everyday work, which is what a chat in an IDE mostly does. Changing
|
|
124
|
+
* it in Settings, or per session in the chat's model picker, overrides this.
|
|
125
|
+
*/
|
|
126
|
+
export const CODEX_DEFAULT_MODEL = "gpt-5.6-terra";
|
|
127
|
+
|
|
114
128
|
export const DEFAULT_CONFIG: PpmConfig = {
|
|
115
129
|
device_name: "",
|
|
116
130
|
port: 8080,
|
package/src/web/app.tsx
CHANGED
|
@@ -21,6 +21,8 @@ import { getAuthToken } from "@/lib/api-client";
|
|
|
21
21
|
import { useUrlSync, parseUrlState, autoOpenFromUrl } from "@/hooks/use-url-sync";
|
|
22
22
|
import { useGlobalKeybindings } from "@/hooks/use-global-keybindings";
|
|
23
23
|
import { useNotificationBadge } from "@/hooks/use-notification-badge";
|
|
24
|
+
import { useWakeLock } from "@/hooks/use-wake-lock";
|
|
25
|
+
import { WakeLockMobileBadge } from "@/components/layout/wake-lock-indicator";
|
|
24
26
|
import { useTabPrefetch } from "@/hooks/use-tab-prefetch";
|
|
25
27
|
import { useGlobalEvents } from "@/hooks/use-global-events";
|
|
26
28
|
import { useServerReload } from "@/hooks/use-server-reload";
|
|
@@ -125,6 +127,9 @@ export function App() {
|
|
|
125
127
|
// Notification badge — syncs document.title + favicon with unread count
|
|
126
128
|
useNotificationBadge();
|
|
127
129
|
|
|
130
|
+
// Screen wake lock — keeps a propped-up tablet lit while any turn is running
|
|
131
|
+
useWakeLock();
|
|
132
|
+
|
|
128
133
|
// Auto-reload when server restarts (clears SW cache first)
|
|
129
134
|
useServerReload();
|
|
130
135
|
|
|
@@ -289,6 +294,9 @@ export function App() {
|
|
|
289
294
|
</div>
|
|
290
295
|
)}
|
|
291
296
|
|
|
297
|
+
{/* Screen-awake pill — mobile only; the desktop equivalent lives in the status bar */}
|
|
298
|
+
<WakeLockMobileBadge />
|
|
299
|
+
|
|
292
300
|
{/* Main layout */}
|
|
293
301
|
<div className="flex flex-1 overflow-hidden">
|
|
294
302
|
{/* Desktop unified nav rail (wordmark + project switcher + section rail + panel) */}
|
|
@@ -8,6 +8,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip
|
|
|
8
8
|
import { ResourceStatusBar } from "@/components/system/resource-status-bar";
|
|
9
9
|
import { ThemePicker } from "@/components/settings/theme-picker";
|
|
10
10
|
import { UpgradeButton } from "@/components/layout/upgrade-button";
|
|
11
|
+
import { WakeLockStatusBarItem } from "@/components/layout/wake-lock-indicator";
|
|
11
12
|
import { countDockTabs } from "@/components/layout/dock-tabs";
|
|
12
13
|
import { DOCK_PANEL_ID } from "@/stores/panel-utils";
|
|
13
14
|
import { cn } from "@/lib/utils";
|
|
@@ -36,6 +37,8 @@ export const StatusBar = memo(function StatusBar() {
|
|
|
36
37
|
<DockToggle />
|
|
37
38
|
</div>
|
|
38
39
|
<div className="flex items-center gap-3 min-w-0">
|
|
40
|
+
{/* Screen-awake marker — only while a wake lock is actually held. */}
|
|
41
|
+
<WakeLockStatusBarItem />
|
|
39
42
|
{/* CPU/MEM moved here from the sidebar resource strip. */}
|
|
40
43
|
<ResourceStatusBar compact />
|
|
41
44
|
{right.map((item) => (
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Screen awake" indicator — shown only while a wake lock is actually held.
|
|
3
|
+
*
|
|
4
|
+
* Two mounts, because the two viewports have no shared chrome: the status bar is `hidden md:flex`
|
|
5
|
+
* and never renders on the phones and tablets this feature exists for, while a fixed badge would
|
|
6
|
+
* collide with the desktop status bar. Both read the same store, so they can never disagree.
|
|
7
|
+
*
|
|
8
|
+
* The state is reported by the browser, not assumed: `use-wake-lock.ts` only flips the store
|
|
9
|
+
* after a request resolves, so this chip disappearing means the platform really did take the
|
|
10
|
+
* lock back (battery saver, low battery) rather than the setting being off.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { memo } from "react";
|
|
14
|
+
import { Sun } from "lucide-react";
|
|
15
|
+
import { useWakeLockStore } from "@/stores/wake-lock-store";
|
|
16
|
+
|
|
17
|
+
const LABEL = "Screen awake";
|
|
18
|
+
const TITLE = "Screen is being kept on while this turn runs";
|
|
19
|
+
|
|
20
|
+
/** Desktop: a plain entry that inherits the status bar's own type scale. */
|
|
21
|
+
export const WakeLockStatusBarItem = memo(function WakeLockStatusBarItem() {
|
|
22
|
+
const active = useWakeLockStore((s) => s.active);
|
|
23
|
+
if (!active) return null;
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<span className="flex items-center gap-1 text-warning shrink-0" title={TITLE}>
|
|
27
|
+
<Sun className="size-3 shrink-0" />
|
|
28
|
+
<span>awake</span>
|
|
29
|
+
</span>
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Mobile: a pill at the top edge. Top-left and top-right are already taken by the device-name
|
|
35
|
+
* badge and the BETA ribbon, so this sits centred between them.
|
|
36
|
+
*/
|
|
37
|
+
export const WakeLockMobileBadge = memo(function WakeLockMobileBadge() {
|
|
38
|
+
const active = useWakeLockStore((s) => s.active);
|
|
39
|
+
if (!active) return null;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
className="md:hidden fixed left-1/2 -translate-x-1/2 top-0 z-50 flex items-center gap-1 px-2 py-0.5 rounded-b bg-warning/85 text-white text-[10px] font-medium pointer-events-none"
|
|
44
|
+
title={TITLE}
|
|
45
|
+
>
|
|
46
|
+
<Sun className="size-3 shrink-0" />
|
|
47
|
+
<span>{LABEL}</span>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
@@ -6,19 +6,30 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { useCallback, useRef, useState } from "react";
|
|
9
|
-
import { Check } from "lucide-react";
|
|
9
|
+
import { Check, Sun } from "lucide-react";
|
|
10
10
|
import { useShallow } from "zustand/react/shallow";
|
|
11
11
|
import { Button } from "@/components/ui/button";
|
|
12
12
|
import { Input } from "@/components/ui/input";
|
|
13
13
|
import { Label } from "@/components/ui/label";
|
|
14
14
|
import { Separator } from "@/components/ui/separator";
|
|
15
|
+
import { Switch } from "@/components/ui/switch";
|
|
15
16
|
import { useSettingsStore } from "@/stores/settings-store";
|
|
17
|
+
import { wakeLockSupport } from "@/hooks/use-wake-lock";
|
|
16
18
|
import { ChangePasswordSection } from "./change-password-section";
|
|
17
19
|
|
|
18
20
|
export function GeneralSettingsSection() {
|
|
19
|
-
const { deviceName, setDeviceName, version } = useSettingsStore(
|
|
20
|
-
useShallow((s) => ({
|
|
21
|
+
const { deviceName, setDeviceName, version, keepScreenAwake, setKeepScreenAwake } = useSettingsStore(
|
|
22
|
+
useShallow((s) => ({
|
|
23
|
+
deviceName: s.deviceName,
|
|
24
|
+
setDeviceName: s.setDeviceName,
|
|
25
|
+
version: s.version,
|
|
26
|
+
keepScreenAwake: s.keepScreenAwake,
|
|
27
|
+
setKeepScreenAwake: s.setKeepScreenAwake,
|
|
28
|
+
})),
|
|
21
29
|
);
|
|
30
|
+
// Computed once per mount: neither the browser nor the origin's secure-context status can
|
|
31
|
+
// change while the pane is open.
|
|
32
|
+
const [support] = useState(wakeLockSupport);
|
|
22
33
|
const [nameInput, setNameInput] = useState(deviceName ?? "");
|
|
23
34
|
const [nameSaving, setNameSaving] = useState(false);
|
|
24
35
|
const [nameSaved, setNameSaved] = useState(false);
|
|
@@ -68,6 +79,29 @@ export function GeneralSettingsSection() {
|
|
|
68
79
|
|
|
69
80
|
<Separator />
|
|
70
81
|
|
|
82
|
+
<section className="flex items-center justify-between gap-4">
|
|
83
|
+
<div className="flex items-center gap-3 min-w-0">
|
|
84
|
+
<Sun className="size-4 text-muted-foreground shrink-0" />
|
|
85
|
+
<div className="min-w-0">
|
|
86
|
+
<p className="text-sm font-medium">Keep Screen Awake</p>
|
|
87
|
+
<p className="text-xs text-muted-foreground">
|
|
88
|
+
{support === "insecure"
|
|
89
|
+
? "Unavailable over plain HTTP — reach PPM through its HTTPS tunnel address to use this."
|
|
90
|
+
: support === "unsupported"
|
|
91
|
+
? "This browser does not support screen wake locks."
|
|
92
|
+
: "Stop this device dimming while a chat turn is running."}
|
|
93
|
+
</p>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<Switch
|
|
97
|
+
checked={keepScreenAwake && support === "ok"}
|
|
98
|
+
disabled={support !== "ok"}
|
|
99
|
+
onCheckedChange={setKeepScreenAwake}
|
|
100
|
+
/>
|
|
101
|
+
</section>
|
|
102
|
+
|
|
103
|
+
<Separator />
|
|
104
|
+
|
|
71
105
|
<ChangePasswordSection />
|
|
72
106
|
|
|
73
107
|
<Separator />
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps the device screen lit while a chat turn is in flight.
|
|
3
|
+
*
|
|
4
|
+
* The whole point is a tablet or phone propped up next to you: a long turn produces no touch
|
|
5
|
+
* input, so the OS dims and locks the screen mid-answer and you lose the thread. The browser's
|
|
6
|
+
* Screen Wake Lock API asks the OS not to do that, and this hook holds the lock exactly for as
|
|
7
|
+
* long as something is running.
|
|
8
|
+
*
|
|
9
|
+
* Scoped to the *device*, not the project. Favicon and title are per-project because a window
|
|
10
|
+
* shows one project, but there is one screen — scoping the lock to the active project would
|
|
11
|
+
* dim the display while another project's turn is still running.
|
|
12
|
+
*
|
|
13
|
+
* "Running" is `phase !== "idle"`, which is what `streaming-store` records. That deliberately
|
|
14
|
+
* includes the wait on an approval or an AskUserQuestion card: the server leaves the phase at
|
|
15
|
+
* `thinking` while the SDK blocks on the answer, and a screen that dies right as the agent asks
|
|
16
|
+
* you something is the worst moment to lose it.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { useEffect } from "react";
|
|
20
|
+
import { useStreamingStore } from "@/stores/streaming-store";
|
|
21
|
+
import { useSettingsStore } from "@/stores/settings-store";
|
|
22
|
+
import { useWakeLockStore } from "@/stores/wake-lock-store";
|
|
23
|
+
|
|
24
|
+
/** The slice of `WakeLockSentinel` this code touches. Declared structurally so the file does
|
|
25
|
+
* not depend on the DOM lib shipping the type. */
|
|
26
|
+
export interface WakeLockSentinelLike {
|
|
27
|
+
release: () => Promise<void>;
|
|
28
|
+
addEventListener: (type: "release", listener: () => void) => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Why the feature is or is not available here — the Settings switch explains itself with this. */
|
|
32
|
+
export type WakeLockSupport = "ok" | "insecure" | "unsupported";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The API is gated on a secure context, so PPM reached over plain HTTP — the usual
|
|
36
|
+
* `http://192.168.x.x:3211` LAN address — has no `navigator.wakeLock` at all. That is by far the
|
|
37
|
+
* likeliest reason this does nothing on someone's tablet, and it deserves a distinct answer
|
|
38
|
+
* from "your browser is too old".
|
|
39
|
+
*/
|
|
40
|
+
export function wakeLockSupport(): WakeLockSupport {
|
|
41
|
+
if (typeof navigator !== "undefined" && "wakeLock" in navigator) return "ok";
|
|
42
|
+
if (typeof window !== "undefined" && window.isSecureContext === false) return "insecure";
|
|
43
|
+
return "unsupported";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface WakeLockSessionDeps {
|
|
47
|
+
/** Acquire a lock. Rejects when the platform refuses (battery saver, low battery, hidden tab). */
|
|
48
|
+
request: () => Promise<WakeLockSentinelLike>;
|
|
49
|
+
isVisible: () => boolean;
|
|
50
|
+
/** Subscribe to visibility changes; returns an unsubscribe. */
|
|
51
|
+
onVisibilityChange: (listener: () => void) => () => void;
|
|
52
|
+
/** Reports whether a lock is actually held, for the indicator. */
|
|
53
|
+
onActive: (active: boolean) => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Holds a wake lock until the returned teardown runs.
|
|
58
|
+
*
|
|
59
|
+
* The re-acquire on `visibilitychange` is not optional. Browsers release the lock every time the
|
|
60
|
+
* document is hidden — switching tabs, switching apps, a manual screen lock — and never restore
|
|
61
|
+
* it. Without this listener the feature works once and then silently stops for the rest of the
|
|
62
|
+
* session, which is the classic way to get this wrong.
|
|
63
|
+
*
|
|
64
|
+
* A refusal is a normal outcome, not an error: the platform is allowed to say no when the
|
|
65
|
+
* battery is low or a power-saving mode is on. Retrying in a loop would only burn what little
|
|
66
|
+
* battery prompted the refusal, so a failed attempt just waits for the next visibility change.
|
|
67
|
+
*/
|
|
68
|
+
export function startWakeLockSession(deps: WakeLockSessionDeps): () => void {
|
|
69
|
+
let sentinel: WakeLockSentinelLike | null = null;
|
|
70
|
+
let stopped = false;
|
|
71
|
+
// `sentinel` is only assigned after the request resolves, so it cannot by itself stop a second
|
|
72
|
+
// attempt started while the first is still in flight — which is exactly what rapid tab
|
|
73
|
+
// flapping produces, and it would leak the lock the second attempt overwrites.
|
|
74
|
+
let acquiring = false;
|
|
75
|
+
|
|
76
|
+
const acquire = async (): Promise<void> => {
|
|
77
|
+
if (stopped || sentinel || acquiring || !deps.isVisible()) return;
|
|
78
|
+
acquiring = true;
|
|
79
|
+
try {
|
|
80
|
+
const next = await deps.request();
|
|
81
|
+
// Teardown may have run while the request was in flight; do not leak the lock.
|
|
82
|
+
if (stopped) {
|
|
83
|
+
void next.release().catch(() => {});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
sentinel = next;
|
|
87
|
+
next.addEventListener("release", () => {
|
|
88
|
+
// The platform took it back. Drop our handle so a later visibility change can re-acquire.
|
|
89
|
+
if (sentinel === next) sentinel = null;
|
|
90
|
+
if (!stopped) deps.onActive(false);
|
|
91
|
+
});
|
|
92
|
+
deps.onActive(true);
|
|
93
|
+
} catch {
|
|
94
|
+
deps.onActive(false);
|
|
95
|
+
} finally {
|
|
96
|
+
acquiring = false;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const unsubscribe = deps.onVisibilityChange(() => {
|
|
101
|
+
if (deps.isVisible()) {
|
|
102
|
+
void acquire();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Hidden: the browser always releases the lock here. Drop our handle now instead of waiting
|
|
106
|
+
// for the `release` event, because the two are separate tasks with no guaranteed order — if
|
|
107
|
+
// `visibilitychange` fires first on the way back, a stale handle would make `acquire` think
|
|
108
|
+
// a lock is still held and skip the re-acquire for the rest of the session.
|
|
109
|
+
sentinel = null;
|
|
110
|
+
deps.onActive(false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
void acquire();
|
|
114
|
+
|
|
115
|
+
return () => {
|
|
116
|
+
stopped = true;
|
|
117
|
+
unsubscribe();
|
|
118
|
+
deps.onActive(false);
|
|
119
|
+
const held = sentinel;
|
|
120
|
+
sentinel = null;
|
|
121
|
+
if (held) void held.release().catch(() => {});
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Mount once, app-wide. */
|
|
126
|
+
export function useWakeLock(): void {
|
|
127
|
+
const anyRunning = useStreamingStore((s) => s.sessions.size > 0);
|
|
128
|
+
const enabled = useSettingsStore((s) => s.keepScreenAwake);
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (!enabled || !anyRunning) return;
|
|
132
|
+
if (wakeLockSupport() !== "ok") return;
|
|
133
|
+
|
|
134
|
+
const wakeLock = (navigator as Navigator & {
|
|
135
|
+
wakeLock: { request: (type: "screen") => Promise<WakeLockSentinelLike> };
|
|
136
|
+
}).wakeLock;
|
|
137
|
+
|
|
138
|
+
return startWakeLockSession({
|
|
139
|
+
request: () => wakeLock.request("screen"),
|
|
140
|
+
isVisible: () => document.visibilityState === "visible",
|
|
141
|
+
onVisibilityChange: (listener) => {
|
|
142
|
+
document.addEventListener("visibilitychange", listener);
|
|
143
|
+
return () => document.removeEventListener("visibilitychange", listener);
|
|
144
|
+
},
|
|
145
|
+
onActive: (active) => useWakeLockStore.getState().setActive(active),
|
|
146
|
+
});
|
|
147
|
+
}, [enabled, anyRunning]);
|
|
148
|
+
}
|
|
@@ -47,6 +47,9 @@ interface SettingsState {
|
|
|
47
47
|
/** User ticked "don't show again" on the remote-desktop warning that precedes every open
|
|
48
48
|
* (`remote-desktop-warning-gate.tsx`); once true the viewer connects straight away. */
|
|
49
49
|
remoteDesktopWarningDismissed: boolean;
|
|
50
|
+
/** Hold a screen wake lock while any chat turn is running, so a propped-up tablet does not
|
|
51
|
+
* dim mid-answer. Defaults on; see `hooks/use-wake-lock.ts`. */
|
|
52
|
+
keepScreenAwake: boolean;
|
|
50
53
|
deviceName: string | null;
|
|
51
54
|
version: string | null;
|
|
52
55
|
tunnelActive: boolean;
|
|
@@ -73,6 +76,7 @@ interface SettingsState {
|
|
|
73
76
|
setExplorerSkin: (pref: ExplorerSkinPref) => void;
|
|
74
77
|
toggleRemoteDesktopStatsVisible: () => void;
|
|
75
78
|
setRemoteDesktopWarningDismissed: (dismissed: boolean) => void;
|
|
79
|
+
setKeepScreenAwake: (enabled: boolean) => void;
|
|
76
80
|
fetchServerInfo: () => Promise<void>;
|
|
77
81
|
/** Re-push the in-memory theme selection to the server (see the action for why). */
|
|
78
82
|
syncThemeToServer: () => Promise<void>;
|
|
@@ -98,6 +102,7 @@ interface PersistedSettings {
|
|
|
98
102
|
explorerSkin?: ExplorerSkinPref;
|
|
99
103
|
remoteDesktopStatsVisible?: boolean;
|
|
100
104
|
remoteDesktopWarningDismissed?: boolean;
|
|
105
|
+
keepScreenAwake?: boolean;
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
const VALID_STYLES: PpmThemeStyle[] = ["aurora", "slate", "precision", "custom"];
|
|
@@ -252,6 +257,7 @@ function applyServerUiPrefs(data: Record<string, unknown>) {
|
|
|
252
257
|
}
|
|
253
258
|
if (typeof data.remoteDesktopStatsVisible === "boolean") patch.remoteDesktopStatsVisible = data.remoteDesktopStatsVisible;
|
|
254
259
|
if (typeof data.remoteDesktopWarningDismissed === "boolean") patch.remoteDesktopWarningDismissed = data.remoteDesktopWarningDismissed;
|
|
260
|
+
if (typeof data.keepScreenAwake === "boolean") patch.keepScreenAwake = data.keepScreenAwake;
|
|
255
261
|
const dbExpanded = sanitizeDbExpanded(data.dbSidebarExpanded);
|
|
256
262
|
if (dbExpanded) patch.dbSidebarExpanded = dbExpanded;
|
|
257
263
|
if (Object.keys(patch).length === 0) return;
|
|
@@ -281,6 +287,7 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({
|
|
|
281
287
|
explorerSkin: (_initial.explorerSkin === "windows" || _initial.explorerSkin === "macos") ? _initial.explorerSkin : "auto",
|
|
282
288
|
remoteDesktopStatsVisible: _initial.remoteDesktopStatsVisible ?? false,
|
|
283
289
|
remoteDesktopWarningDismissed: _initial.remoteDesktopWarningDismissed ?? false,
|
|
290
|
+
keepScreenAwake: _initial.keepScreenAwake ?? true,
|
|
284
291
|
deviceName: null,
|
|
285
292
|
version: null,
|
|
286
293
|
tunnelActive: false,
|
|
@@ -405,6 +412,11 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({
|
|
|
405
412
|
set({ remoteDesktopWarningDismissed: dismissed });
|
|
406
413
|
},
|
|
407
414
|
|
|
415
|
+
setKeepScreenAwake: (enabled) => {
|
|
416
|
+
persistUiPref({ keepScreenAwake: enabled });
|
|
417
|
+
set({ keepScreenAwake: enabled });
|
|
418
|
+
},
|
|
419
|
+
|
|
408
420
|
setEditorTabStyle: (style) => {
|
|
409
421
|
persistUiPref({ editorTabStyle: style });
|
|
410
422
|
set({ editorTabStyle: style });
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whether a screen wake lock is being held right now.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately separate from "should we be holding one". The browser grants the lock on its
|
|
7
|
+
* own terms and takes it back without asking — battery saver, a low battery, or the tab
|
|
8
|
+
* being hidden all revoke it — so the indicator has to report what actually happened rather
|
|
9
|
+
* than what was requested. `use-wake-lock.ts` is the only writer.
|
|
10
|
+
*/
|
|
11
|
+
interface WakeLockStore {
|
|
12
|
+
active: boolean;
|
|
13
|
+
setActive: (active: boolean) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const useWakeLockStore = create<WakeLockStore>((set) => ({
|
|
17
|
+
active: false,
|
|
18
|
+
// Same-value writes are dropped so a re-acquire that changes nothing does not
|
|
19
|
+
// re-render the indicator.
|
|
20
|
+
setActive: (active) => set((s) => (s.active === active ? s : { active })),
|
|
21
|
+
}));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{S as t,x as n}from"./vendor-markdown-Ls5AcU91.js";import"./vendor-ui-CaeeFO0B.js";import{t as r}from"./copy-BewHj66E.js";import{t as i}from"./download-DG3_9xXy.js";import{t as a}from"./flask-conical-tp8gyZGh.js";import{t as o}from"./key-round-CQpDrDxg.js";import{t as s}from"./loader-circle-DPMrnLQ2.js";import{t as c}from"./x-YDu4m2Iq.js";import{n as l,r as u}from"./api-client-oY1tC3tM.js";import{n as d}from"./utils-C9OjCrou.js";import"./portal-container-context-a399Hd9F.js";import{n as f}from"./use-is-mobile-CYW3FJFE.js";import{n as p,t as m}from"./button-BZtEJcUv.js";import{t as h}from"./mobile-bottom-sheet-BD5b7KJF.js";import"./use-visual-viewport-rnvuooQZ.js";import{$t as g,B as _,Cr as v,H as y,J as b,Jn as x,Jt as S,Pn as C,Qt as w,U as T,V as E,Vn as D,W as O,Xt as k,Y as A,Yt as j,Zt as M,ar as N,er as P,j as F,jn as I,tn as ee,z as te}from"./index-LEL-8oU_.js";import{addAccount as ne,deleteAccount as re,exchangeOAuthCode as ie,getAISettings as ae,getAccountSettings as oe,getOAuthUrl as se,getUsageHistory as ce,importAccounts as le,patchAccount as ue,testAccountToken as de,testExport as fe,testRawToken as pe,updateAccountSettings as L}from"./api-settings-CTMdz_VF.js";import{a as R,c as z,i as B,l as me,n as he,o as V,r as H,t as ge,u as U}from"./use-accounts-data-B8ltBkBj.js";var W=e(t(),1),G=n(),K=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],q=Array.from({length:24},(e,t)=>t);function _e(e,t){let n=Array.from({length:7},()=>Array.from({length:24},()=>({sum:0,count:0,avg:0})));for(let r of e){let e=t===`5h`?r.five_hour_util:r.weekly_util;if(e==null)continue;let i=new Date(r.recorded_at+(r.recorded_at.endsWith(`Z`)?``:`Z`)),a=(i.getDay()+6)%7,o=i.getHours();n[a][o].sum+=e,n[a][o].count+=1}for(let e of n)for(let t of e)t.avg=t.count>0?t.sum/t.count:0;return n}function ve(e){return e.map(e=>{let t=e.reduce((e,t)=>e+t.sum,0),n=e.reduce((e,t)=>e+t.count,0);return n>0?t/n:0})}function ye(e){return q.map(t=>{let n=0,r=0;for(let i of e)n+=i[t].sum,r+=i[t].count;return r>0?n/r:0})}function J(e){return e===0?`bg-surface-elevated`:e<.3?`bg-success/30`:e<.5?`bg-success/60`:e<.7?`bg-warning/50`:e<.9?`bg-warning/80`:`bg-error/80`}function be(e){return e<.3?`bg-success`:e<.7?`bg-warning`:`bg-error`}function xe({accountId:e}){let[t,n]=(0,W.useState)(null),[r,i]=(0,W.useState)(!0),[a,o]=(0,W.useState)(`5h`);(0,W.useEffect)(()=>{i(!0),ce(e).then(n).catch(()=>n([])).finally(()=>i(!1))},[e]);let c=(0,W.useMemo)(()=>t?_e(t,a):null,[t,a]),l=(0,W.useMemo)(()=>c?ve(c):[],[c]),u=(0,W.useMemo)(()=>c?ye(c):[],[c]),d=Math.max(...l,.01);if(Math.max(...u,.01),r)return(0,G.jsx)(`div`,{className:`flex items-center justify-center py-3`,children:(0,G.jsx)(s,{className:`size-3 animate-spin text-text-subtle`})});if(!t||t.length===0)return(0,G.jsx)(`div`,{className:`text-[10px] text-text-subtle py-2 text-center`,children:`No usage history yet`});let f=t.length,p=new Set(t.map(e=>new Date(e.recorded_at+(e.recorded_at.endsWith(`Z`)?``:`Z`)).toDateString())).size;return(0,G.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`span`,{className:`text-[10px] font-medium text-text-subtle`,children:`Usage Pattern (7d)`}),(0,G.jsxs)(`div`,{className:`flex gap-0.5 text-[9px]`,children:[(0,G.jsx)(`button`,{onClick:()=>o(`5h`),className:`px-1.5 py-0.5 rounded cursor-pointer transition-colors ${a===`5h`?`bg-primary/15 text-primary`:`text-text-subtle hover:text-text-secondary`}`,title:`5-hour rolling window limit — resets every 5 hours`,children:`5h`}),(0,G.jsx)(`button`,{onClick:()=>o(`weekly`),className:`px-1.5 py-0.5 rounded cursor-pointer transition-colors ${a===`weekly`?`bg-primary/15 text-primary`:`text-text-subtle hover:text-text-secondary`}`,title:`Weekly limit — resets every 7 days`,children:`Wk`})]})]}),(0,G.jsxs)(`p`,{className:`text-[9px] text-text-subtle leading-tight`,children:[`Avg `,a===`5h`?`5-hour`:`weekly`,` limit usage over `,p,`d (`,f,` samples). Higher % = closer to rate limit. Hover cells for details.`]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by day of week`}),(0,G.jsx)(`div`,{className:`flex flex-col gap-[2px] mt-0.5`,children:K.map((e,t)=>{let n=l[t]??0;return(0,G.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,G.jsx)(`span`,{className:`text-[8px] text-text-subtle w-5 shrink-0 text-right tabular-nums`,children:e}),(0,G.jsx)(`div`,{className:`flex-1 h-2.5 bg-surface-elevated rounded-sm overflow-hidden`,children:(0,G.jsx)(`div`,{className:`h-full rounded-sm transition-all ${be(n)}`,style:{width:`${Math.round(n/d*100)}%`}})}),(0,G.jsxs)(`span`,{className:`text-[8px] text-text-subtle w-6 shrink-0 text-right tabular-nums`,children:[Math.round(n*100),`%`]})]},e)})})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by hour (0h-23h)`}),(0,G.jsx)(`div`,{className:`flex gap-[1px] mt-0.5`,children:q.map(e=>{let t=u[e]??0;return(0,G.jsxs)(`div`,{className:`flex-1 flex flex-col items-center gap-[1px]`,children:[(0,G.jsx)(`div`,{className:`w-full aspect-square rounded-[2px] ${J(t)}`,title:`${e}:00 — avg ${Math.round(t*100)}% usage`}),e%6==0&&(0,G.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})]},e)})})]}),c&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Day x Hour heatmap`}),(0,G.jsxs)(`div`,{className:`flex flex-col gap-[1px] mt-0.5`,children:[K.map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,G.jsx)(`span`,{className:`text-[7px] text-text-subtle w-4 shrink-0 text-right`,children:e.charAt(0)}),q.map(n=>{let r=c[t][n];return(0,G.jsx)(`div`,{className:`flex-1 aspect-square rounded-[1px] ${J(r.avg)}`,title:`${e} ${n}:00 — ${r.count>0?`avg ${Math.round(r.avg*100)}% (${r.count} samples)`:`no data`}`},n)})]},e)),(0,G.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,G.jsx)(`span`,{className:`w-4 shrink-0`}),q.map(e=>(0,G.jsx)(`div`,{className:`flex-1 text-center`,children:e%6==0&&(0,G.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})},e))]})]})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[8px] text-text-subtle`,children:[(0,G.jsx)(`span`,{children:`Low`}),(0,G.jsxs)(`div`,{className:`flex gap-[2px]`,children:[(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/30`}),(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/60`}),(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/50`}),(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/80`}),(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-error/80`})]}),(0,G.jsx)(`span`,{children:`High`}),(0,G.jsx)(`span`,{className:`ml-1`,children:`|`}),(0,G.jsx)(`div`,{className:`size-2 rounded-[1px] bg-surface-elevated border border-border/30`}),(0,G.jsx)(`span`,{children:`No data`})]})]})}function Se({profile:e,accountId:t,onClose:n}){let r=[[`Name`,e.account?.display_name],[`Email`,e.account?.email],[`Org`,e.organization?.name],[`Type`,e.organization?.organization_type],[`Tier`,e.organization?.rate_limit_tier],[`Status`,e.organization?.subscription_status]];return(0,G.jsxs)(`section`,{className:`space-y-2 border-t border-border pt-3`,"data-testid":`account-profile-panel`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium`,children:`Profile`}),(0,G.jsx)(`button`,{className:`p-2 text-muted-foreground hover:text-foreground cursor-pointer`,onClick:n,"aria-label":`Close profile`,children:(0,G.jsx)(c,{className:`size-4`})})]}),(0,G.jsx)(`div`,{className:`grid grid-cols-[80px_1fr] gap-x-3 gap-y-1 text-xs`,children:r.map(([e,t])=>t?(0,G.jsxs)(`span`,{className:`contents`,children:[(0,G.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,G.jsx)(`span`,{className:`break-all`,children:t})]},e):null)}),(0,G.jsx)(xe,{accountId:t})]})}function Ce({display:e,onConfirm:t,onCancel:n}){let r=f(),i=(0,G.jsxs)(`div`,{className:`space-y-4`,"data-testid":`account-delete-confirm`,children:[(0,G.jsxs)(`p`,{className:`text-sm`,children:[`Remove `,(0,G.jsx)(`span`,{className:`font-medium`,children:e}),`?`]}),(0,G.jsx)(`p`,{className:`text-xs text-text-subtle`,children:`The stored token is deleted from this machine. Any export you already made keeps working.`}),(0,G.jsxs)(`div`,{className:`flex flex-col-reverse md:flex-row gap-2 md:justify-end pt-2`,children:[(0,G.jsx)(m,{variant:`outline`,onClick:n,className:`min-h-11`,children:`Cancel`}),(0,G.jsx)(m,{variant:`destructive`,autoFocus:!1,onClick:t,className:`min-h-11`,children:`Remove account`})]})]});return r?(0,G.jsx)(h,{open:!0,onClose:n,children:(0,G.jsxs)(`div`,{className:`px-4 pb-4`,children:[(0,G.jsx)(`h2`,{className:`text-base font-semibold mb-3`,children:`Remove account`}),i]})}):(0,G.jsx)(S,{open:!0,onOpenChange:e=>{e||n()},children:(0,G.jsxs)(j,{className:`sm:max-w-sm`,children:[(0,G.jsx)(w,{children:(0,G.jsx)(g,{className:`text-sm`,children:`Remove account`})}),i]})})}function we({open:e,onOpenChange:t,onSuccess:n}){let[r,i]=(0,W.useState)(``),[a,o]=(0,W.useState)(``),[c,l]=(0,W.useState)(!1),[u,d]=(0,W.useState)(null),[f,p]=(0,W.useState)(null),[h,_]=(0,W.useState)(``),[v,y]=(0,W.useState)(!1),[x,C]=(0,W.useState)(`idle`);function T(){p(null),_(``),C(`idle`),d(null)}function E(){t(!1),T(),i(``),o(``),d(null)}async function D(){y(!0),d(null);try{let{url:e,state:t}=await se();p(t),C(`waiting`),window.open(e,`_blank`)}catch(e){d(e.message)}y(!1)}async function O(){if(!(!h.trim()||!f)){y(!0),d(null);try{let e=h.trim();e.includes(`#`)&&(e=e.split(`#`)[0]??e);let t=await ie(e,f);E(),n(t?.status===`disabled`?`Signed in. This account is still disabled — enable it to use it.`:`Account connected via OAuth!`)}catch(e){d(e.message)}y(!1)}}async function N(){if(r.trim()){l(!0),d(null);try{let e=await ne({apiKey:r.trim(),label:a.trim()||void 0});E(),n(e?.status===`disabled`?`Token updated. This account is still disabled — enable it to use it.`:`Account added!`)}catch(e){d(e.message)}l(!1)}}let P=r.trim()?r.trim().startsWith(`sk-ant-oat`)?`OAuth token (Claude Max/Pro)`:r.trim().startsWith(`sk-ant-api`)?`API key`:`Unknown format`:``;return(0,G.jsx)(S,{open:e,onOpenChange:e=>{e||E()},children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsx)(g,{className:`text-sm`,children:`Add Claude Account`}),(0,G.jsx)(k,{className:`text-xs leading-relaxed`,children:`Connect via OAuth (recommended) or paste a token manually.`})]}),(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`rounded-md border p-3 space-y-2`,children:[(0,G.jsx)(`p`,{className:`text-[11px] font-medium`,children:`Recommended: Login with Claude`}),x===`idle`?(0,G.jsx)(m,{size:`sm`,className:`w-full h-8 text-xs`,onClick:D,disabled:v,children:v?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Opening...`]}):`Login with Claude`}):(0,G.jsxs)(`div`,{className:`space-y-2`,children:[(0,G.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Authorize in the opened tab, then paste the code:`}),(0,G.jsx)(A,{placeholder:`Paste code here...`,value:h,onChange:e=>_(e.target.value),className:`text-xs h-8 font-mono`,autoFocus:!0}),(0,G.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,G.jsx)(m,{size:`sm`,className:`flex-1 h-7 text-xs`,onClick:O,disabled:!h.trim()||v,children:v?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Connecting...`]}):`Connect`}),(0,G.jsx)(m,{size:`sm`,variant:`ghost`,className:`h-7 text-xs`,onClick:T,children:`Cancel`})]})]})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`div`,{className:`flex-1 border-t`}),(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`or paste token`}),(0,G.jsx)(`div`,{className:`flex-1 border-t`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{htmlFor:`add-token`,className:`text-xs`,children:`Token`}),(0,G.jsx)(A,{id:`add-token`,type:`password`,placeholder:`sk-ant-...`,value:r,onChange:e=>i(e.target.value),className:`text-xs h-8 font-mono`}),P&&(0,G.jsxs)(`p`,{className:`text-[10px] text-muted-foreground`,children:[`Detected: `,P]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{htmlFor:`add-label`,className:`text-xs`,children:`Label (optional)`}),(0,G.jsx)(A,{id:`add-label`,placeholder:`e.g. Personal, Work`,value:a,onChange:e=>o(e.target.value),className:`text-xs h-8`})]})]}),u&&(0,G.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:u}),(0,G.jsxs)(M,{children:[(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7`,onClick:E,children:`Cancel`}),(0,G.jsx)(m,{size:`sm`,className:`text-xs h-7`,onClick:N,disabled:!r.trim()||c,children:c?`Adding...`:`Add Token`})]})]})})}function Te(e){let t=new Blob([e],{type:`application/json`}),n=document.createElement(`a`);n.href=URL.createObjectURL(t),n.download=`ppm-accounts-backup.json`,n.click(),URL.revokeObjectURL(n.href)}function Ee({open:e,onOpenChange:t,accounts:n,preselectId:a,onMessage:o}){let c=n.filter(e=>e.hasRefreshToken),[l,d]=(0,W.useState)(new Set),[f,p]=(0,W.useState)(``),[h,_]=(0,W.useState)(!1),[v,y]=(0,W.useState)(!1),[x,C]=(0,W.useState)(!1),[T,E]=(0,W.useState)(!1);e&&!T&&(d(a?new Set([a]):new Set(c.map(e=>e.id))),E(!0)),!e&&T&&E(!1);function D(){t(!1),p(``),_(!1),y(!1)}async function O(e){if(l.size===0)return;C(!0);let t=f.trim()||`ppm-hienlh`;try{let n={"Content-Type":`application/json`},r=u();r&&(n.Authorization=`Bearer ${r}`);let i=await fetch(`/api/accounts/export`,{method:`POST`,headers:n,body:JSON.stringify({password:t,accountIds:[...l],includeRefreshToken:h,refreshBeforeExport:v})});if(!i.ok){let e=await i.json();throw Error(e.error??`Export failed: ${i.status}`)}let a=await i.text();e&&await ee(a)?o?.(`Backup copied to clipboard!`):(Te(a),o?.(`Backup downloaded.`)),D()}catch{}C(!1)}let P=l.size>0&&!x;return(0,G.jsx)(S,{open:e,onOpenChange:e=>{e||D()},children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsxs)(g,{className:`text-sm flex items-center gap-1.5`,children:[(0,G.jsx)(N,{className:`size-3.5`}),` Export Accounts`]}),(0,G.jsx)(k,{className:`text-xs`,children:`Select accounts and set a password to protect the backup.`})]}),(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`space-y-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,G.jsx)(`p`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Accounts to export`}),(0,G.jsx)(`button`,{className:`text-[10px] text-primary hover:underline cursor-pointer`,onClick:()=>d(l.size===c.length?new Set:new Set(c.map(e=>e.id))),children:l.size===c.length?`Deselect all`:`Select all`})]}),c.length===0?(0,G.jsx)(`p`,{className:`text-[10px] text-muted-foreground p-2 border rounded`,children:`No exportable accounts.`}):(0,G.jsx)(`div`,{className:`max-h-36 overflow-y-auto space-y-1 border rounded p-2`,children:c.map(e=>(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`checkbox`,id:`exp-${e.id}`,checked:l.has(e.id),onChange:t=>{let n=new Set(l);t.target.checked?n.add(e.id):n.delete(e.id),d(n)},className:`size-3.5 accent-primary cursor-pointer`}),(0,G.jsx)(`label`,{htmlFor:`exp-${e.id}`,className:`text-xs cursor-pointer truncate`,children:e.label??e.email??e.id.slice(0,8)})]},e.id))})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(b,{className:`text-xs`,children:[`Password `,(0,G.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,G.jsx)(A,{type:`password`,placeholder:`Leave empty for default`,value:f,onChange:e=>p(e.target.value),className:`text-xs h-8`,autoComplete:`new-password`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`checkbox`,id:`exp-full`,checked:h,onChange:e=>_(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,G.jsx)(`label`,{htmlFor:`exp-full`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens (full transfer)`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`checkbox`,id:`exp-refresh`,checked:v,onChange:e=>y(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,G.jsx)(`label`,{htmlFor:`exp-refresh`,className:`text-[11px] cursor-pointer`,children:`Refresh tokens before export`})]}),h?(0,G.jsxs)(`div`,{className:`rounded-md border border-error/30 bg-error/5 p-2.5`,children:[(0,G.jsx)(`p`,{className:`text-[10px] font-medium text-error`,children:`Full transfer — source accounts will expire`}),(0,G.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Refresh tokens included. Source machine expires in ~1h after target refreshes.`})]}):v?(0,G.jsx)(`div`,{className:`rounded-md border border-warning/30 bg-warning/5 p-2.5`,children:(0,G.jsx)(`p`,{className:`text-[10px] font-medium text-warning`,children:`Refresh before export — invalidates previous shares`})}):(0,G.jsx)(`div`,{className:`rounded-md border border-success/30 bg-success/5 p-2.5`,children:(0,G.jsx)(`p`,{className:`text-[10px] font-medium text-success`,children:`Share current token (safe)`})}),(0,G.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Encrypted with AES-256-GCM + scrypt.`})]}),(0,G.jsxs)(M,{className:`gap-1.5 flex-col sm:flex-row`,children:[(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:D,children:`Cancel`}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,disabled:!P,onClick:()=>O(!0),children:[(0,G.jsx)(r,{className:`size-3 mr-1`}),` Copy`]}),(0,G.jsx)(m,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!P,onClick:()=>O(!1),children:x?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(i,{className:`size-3 mr-1`}),` Download`]})})]})]})})}function De({open:e,onOpenChange:t,onSuccess:n}){let[r,i]=(0,W.useState)(``),[a,o]=(0,W.useState)(``),[c,l]=(0,W.useState)(!1),[u,d]=(0,W.useState)(null);function f(){t(!1),i(``),o(``),d(null)}async function p(){if(r.trim()){l(!0),d(null);try{let e=await le({data:r.trim(),password:a.trim()||`ppm-hienlh`});f(),n(`Imported ${e.imported} account(s)`)}catch(e){d(e.message||`Import failed`)}l(!1)}}return(0,G.jsx)(S,{open:e,onOpenChange:e=>{e||f()},children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsxs)(g,{className:`text-sm flex items-center gap-1.5`,children:[(0,G.jsx)(N,{className:`size-3.5`}),` Import Accounts`]}),(0,G.jsx)(k,{className:`text-xs`,children:`Paste backup data and enter the export password. Imported accounts are temporary (~1h).`})]}),(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{className:`text-xs`,children:`Backup data`}),(0,G.jsx)(`textarea`,{value:r,onChange:e=>i(e.target.value),placeholder:`Paste backup JSON here...`,rows:4,className:`w-full text-xs p-2 rounded border border-border bg-background font-mono resize-none focus:outline-none focus:ring-1 focus:ring-primary`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(b,{className:`text-xs`,children:[`Password `,(0,G.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,G.jsx)(A,{type:`password`,placeholder:`Leave empty for default`,value:a,onChange:e=>o(e.target.value),className:`text-xs h-8`,autoComplete:`current-password`})]})]}),u&&(0,G.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:u}),(0,G.jsxs)(M,{children:[(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:f,children:`Cancel`}),(0,G.jsx)(m,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!r.trim()||c,onClick:p,children:c?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Importing...`]}):`Import`})]})]})})}var Y=typeof window<`u`?window.matchMedia(`(min-width: 768px)`):null;function Oe(e){return Y?.addEventListener(`change`,e),()=>Y?.removeEventListener(`change`,e)}function ke(){return Y?.matches??!0}function X(){let[e,t]=(0,W.useState)(null),[n,r]=(0,W.useState)(!0);return(0,W.useEffect)(()=>{r(!0),oe().then(t).finally(()=>r(!1))},[]),n?(0,G.jsx)(`p`,{className:`text-xs text-text-subtle py-4 text-center`,children:`Loading...`}):e?(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Rotation Strategy`}),(0,G.jsxs)(te,{value:e.strategy,onValueChange:async e=>{t(await L({strategy:e}))},children:[(0,G.jsx)(y,{className:`w-full h-9 text-xs`,children:(0,G.jsx)(T,{})}),(0,G.jsxs)(_,{children:[(0,G.jsx)(E,{value:`round-robin`,children:`Round-robin`}),(0,G.jsx)(E,{value:`fill-first`,children:`Fill-first`}),(0,G.jsx)(E,{value:`lowest-usage`,children:`Lowest usage`})]})]}),(0,G.jsxs)(`p`,{className:`text-[10px] text-text-subtle`,children:[e.strategy===`round-robin`&&`Cycles through accounts evenly`,e.strategy===`fill-first`&&`Uses one account until its limit, then moves on`,e.strategy===`lowest-usage`&&`Picks the account with the lowest current usage`]})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Max Retry`}),(0,G.jsx)(`input`,{type:`number`,min:0,value:e.maxRetry,className:`w-full h-9 text-xs border rounded-md px-3 bg-background`,onChange:async e=>{let n=parseInt(e.target.value,10);!isNaN(n)&&n>=0&&t(await L({maxRetry:n}))}}),(0,G.jsx)(`p`,{className:`text-[10px] text-text-subtle`,children:`How many accounts to try on failure. 0 = try all available accounts.`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5 border-t border-border pt-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Cooldown parking`}),(0,G.jsx)(O,{checked:e.cooldownEnabled,onCheckedChange:async e=>{t(await L({cooldownEnabled:e}))}})]}),(0,G.jsx)(`p`,{className:`text-[10px] text-text-subtle`,children:`Park a failing account (rate limit / usage limit / auth error) until it recovers. Off: accounts stay selectable — rotation still skips accounts already ≥95% on the 5-hour limit.`})]}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between text-xs border-t border-border pt-3`,children:[(0,G.jsx)(`span`,{className:`text-text-subtle`,children:`Active accounts`}),(0,G.jsx)(`span`,{className:`font-medium text-text-primary`,children:e.activeCount})]})]}):(0,G.jsx)(`p`,{className:`text-xs text-text-subtle py-4 text-center`,children:`Failed to load settings`})}function Ae({open:e,onOpenChange:t}){let n=(0,W.useSyncExternalStore)(Oe,ke);return e?n?(0,G.jsx)(S,{open:e,onOpenChange:t,children:(0,G.jsxs)(j,{className:`sm:max-w-sm`,children:[(0,G.jsx)(w,{children:(0,G.jsxs)(g,{className:`text-sm flex items-center gap-2`,children:[(0,G.jsx)(D,{className:`size-4`}),` Rotation & Retry`]})}),(0,G.jsx)(X,{})]})}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`fixed inset-0 z-50 transition-opacity duration-200 opacity-100`,onClick:()=>t(!1),style:{backgroundColor:`rgba(0,0,0,0.5)`}}),(0,G.jsxs)(`div`,{className:d(`fixed bottom-0 left-0 right-0 z-50 bg-background rounded-t-2xl border-t border-border shadow-2xl`,`transition-transform duration-300 ease-out max-h-[85vh] overflow-y-auto`,`translate-y-0`),children:[(0,G.jsx)(`div`,{className:`flex justify-center pt-3 pb-1`,children:(0,G.jsx)(`div`,{className:`w-10 h-1 rounded-full bg-border`})}),(0,G.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-2 border-b border-border`,children:[(0,G.jsxs)(`span`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,G.jsx)(D,{className:`size-4`}),` Rotation & Retry`]}),(0,G.jsx)(`button`,{onClick:()=>t(!1),className:`flex items-center justify-center size-7 rounded-md hover:bg-surface-elevated transition-colors`,children:(0,G.jsx)(c,{className:`size-4`})})]}),(0,G.jsx)(`div`,{className:`px-4 py-4 pb-8`,children:(0,G.jsx)(X,{})})]})]}):null}var je=p(`inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2`,{variants:{variant:{default:`border-transparent bg-primary text-primary-foreground shadow`,secondary:`border-transparent bg-secondary text-secondary-foreground`,destructive:`border-transparent bg-destructive text-destructive-foreground shadow`,outline:`text-foreground`}},defaultVariants:{variant:`default`}});function Z({className:e,variant:t,...n}){return(0,G.jsx)(`div`,{className:d(je({variant:t}),e),...n})}function Me(e){let t=Math.floor(Date.now()/1e3);return e>t?`${Math.floor((e-t)/60)}m`:`exp`}function Ne({accounts:e}){let[t,n]=(0,W.useState)([]),[r,i]=(0,W.useState)(!1),[a,o]=(0,W.useState)(!1),[c,l]=(0,W.useState)(new Map),u=e.filter(e=>e.hasRefreshToken);async function d(){if(u.length!==0){i(!0);try{let e=await fe(u.map(e=>e.id),a);n(t=>[...t,{round:t.length+1,time:new Date().toLocaleTimeString(),includeRefresh:a,items:e}])}catch{}i(!1)}}async function f(e,t){l(t=>new Map(t).set(e,{loading:!0}));try{let n=await pe(t);l(t=>new Map(t).set(e,{loading:!1,...n}))}catch(t){l(n=>new Map(n).set(e,{loading:!1,status:`error`,error:t.message}))}}function p(e,t){return[{key:`r${e.round}-pre-${t.id}`,label:`Pre-export`,token:t.preExportTokenFull,preview:t.preExportToken,expires:t.preExportExpires},{key:`r${e.round}-exp-${t.id}`,label:`Exported`,token:t.exportedTokenFull,preview:t.exportedToken,expires:t.exportedExpires},{key:`r${e.round}-post-${t.id}`,label:`Post-export`,token:t.postExportTokenFull,preview:t.postExportToken,expires:t.postExportExpires}]}function h(){for(let e of t)for(let t of e.items)for(let n of p(e,t))n.token&&f(n.key,n.token)}return(0,G.jsxs)(`section`,{className:`border-t pt-4 space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(`p`,{className:`text-xs font-medium`,children:`Simulate export`}),t.length>0&&(0,G.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[t.length,` round(s)`]})]}),(0,G.jsx)(`p`,{className:`text-[11px] text-muted-foreground`,children:`Every run appends a round. Earlier rounds are kept so tokens can be compared across runs.`}),u.length===0?(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No OAuth account with a refresh token to export.`}):(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(O,{id:`sim-include-refresh`,checked:a,onCheckedChange:o,className:`cursor-pointer`}),(0,G.jsx)(b,{htmlFor:`sim-include-refresh`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens`})]}),(0,G.jsx)(m,{size:`sm`,className:`h-7 text-xs cursor-pointer`,disabled:r,onClick:()=>void d(),children:r?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):`Run export #${t.length+1}`})]}),t.length>0&&(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`w-full h-7 text-[11px] cursor-pointer`,onClick:h,children:[`Test all tokens (`,t.reduce((e,t)=>e+t.items.length*3,0),`)`]}),t.map(e=>(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsxs)(`p`,{className:`text-xs font-medium text-primary`,children:[`Round #`,e.round]}),(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:e.time}),(0,G.jsx)(Z,{variant:e.includeRefresh?`destructive`:`secondary`,className:`text-[9px] px-1 py-0`,children:e.includeRefresh?`with refresh`:`access only`})]}),e.items.map(t=>(0,G.jsxs)(`div`,{className:`p-2 rounded-lg border bg-card space-y-1.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`text-[11px] font-medium`,children:t.label??t.email??t.id.slice(0,8)}),t.tokenChanged&&(0,G.jsx)(Z,{variant:`secondary`,className:`text-[9px] px-1 py-0`,children:`DB token changed`})]}),p(e,t).map(e=>{let t=c.get(e.key);return(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px]`,children:[(0,G.jsx)(`span`,{className:`w-20 shrink-0 text-muted-foreground text-[10px]`,children:e.label}),(0,G.jsx)(`code`,{className:`flex-1 truncate font-mono text-[10px] bg-muted px-1 rounded`,children:e.preview??`N/A`}),e.expires&&(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground shrink-0`,children:Me(e.expires)}),e.token?(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`h-6 text-[10px] px-1.5 cursor-pointer shrink-0`,disabled:t?.loading,onClick:()=>void f(e.key,e.token),children:t?.loading?(0,G.jsx)(s,{className:`size-3 animate-spin`}):`Test`}):(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`-`}),t&&!t.loading&&(0,G.jsx)(`span`,{className:`text-[10px] font-medium shrink-0 ${t.status?.startsWith(`valid`)?`text-success`:`text-error`}`,children:t.status})]},e.key)})]},`r${e.round}-${t.id}`))]},e.round))]})]})}function Pe(e){let t=Math.floor(Date.now()/1e3),n=Math.floor(Math.abs(e-t)/60);return e>t?`${n}m left`:`expired ${n}m ago`}function Fe({open:e,onOpenChange:t,accounts:n}){let[r,i]=(0,W.useState)(new Map),[o,c]=(0,W.useState)(!1);async function l(e){i(t=>new Map(t).set(e,{loading:!0}));try{let t=await de(e,o);i(n=>new Map(n).set(e,{loading:!1,result:t}))}catch(t){i(n=>new Map(n).set(e,{loading:!1,error:t.message}))}}function u(){for(let e of n.filter(e=>e.expiresAt!==null))l(e.id)}return(0,G.jsx)(S,{open:e,onOpenChange:t,children:(0,G.jsxs)(j,{className:`sm:max-w-xl max-h-[85vh] flex flex-col`,children:[(0,G.jsxs)(w,{children:[(0,G.jsxs)(g,{className:`text-sm flex items-center gap-1.5`,children:[(0,G.jsx)(a,{className:`size-4`}),` Token Test`]}),(0,G.jsx)(k,{className:`text-xs`,children:`Probe stored tokens for validity. Nothing is modified.`})]}),(0,G.jsxs)(`div`,{className:`space-y-4 overflow-y-auto flex-1 pr-1`,children:[(0,G.jsxs)(`section`,{className:`space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsx)(`p`,{className:`text-xs font-medium`,children:`Current tokens`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,G.jsx)(O,{id:`token-test-refresh`,checked:o,onCheckedChange:c,className:`cursor-pointer`}),(0,G.jsx)(b,{htmlFor:`token-test-refresh`,className:`text-[11px] cursor-pointer`,children:`Also test refresh`})]}),(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`h-7 text-xs cursor-pointer`,onClick:u,children:`Test all`})]})]}),n.length===0&&(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No accounts to test.`}),(0,G.jsx)(`div`,{className:`space-y-1.5`,children:n.map(e=>{let t=r.get(e.id),n=t?.result?.accessToken.status;return(0,G.jsxs)(`div`,{className:`p-2 rounded border bg-card space-y-1`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,G.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,G.jsx)(`span`,{className:`text-xs font-medium truncate block`,children:e.label??e.email??e.id.slice(0,8)}),e.expiresAt&&(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:Pe(e.expiresAt)})]}),(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`h-7 text-xs cursor-pointer shrink-0`,disabled:t?.loading,onClick:()=>void l(e.id),children:t?.loading?(0,G.jsx)(s,{className:`size-3 animate-spin`}):`Test`})]}),t&&!t.loading&&(0,G.jsxs)(`div`,{className:`text-[11px] pl-2 border-l-2 border-muted`,children:[t.error&&(0,G.jsx)(`p`,{className:`text-error`,children:t.error}),n&&(0,G.jsxs)(`span`,{className:n.startsWith(`valid`)?`text-success`:`text-error`,children:[n,t.result?.accessToken.code?` (${t.result.accessToken.code})`:``]})]})]},e.id)})})]}),(0,G.jsx)(Ne,{accounts:n})]}),(0,G.jsx)(M,{children:(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Close`})})]})})}function Q(){let{usages:e,accounts:t,activeAccountId:n,initialLoading:r,refreshing:c,flashIds:l,reload:u}=ge(),[d,f]=(0,W.useState)(null),[p,h]=(0,W.useState)(null),[g,_]=(0,W.useState)(null),[v,y]=(0,W.useState)(null),[b,S]=(0,W.useState)(null),[C,w]=(0,W.useState)(null);function T(e){u(),e&&f(e)}async function E(e,t){h(e);try{await ue(e,{status:t===`disabled`?`active`:`disabled`})}catch(e){f(e.message)}h(null),u()}async function O(){if(g){try{await re(g.id),f(`Account "${g.display}" removed.`),u()}catch(e){f(`Failed to remove: ${e.message}`)}_(null)}}let k=new Map(t.map(e=>[e.id,e])),A=e[0]?.usage.lastFetchedAt;return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(R,{description:`Connect multiple Claude accounts. PPM rotates between them automatically to avoid rate limits.`,onRefresh:()=>void u(),refreshing:c,disabled:r,actions:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(m,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`add`),children:[(0,G.jsx)(x,{className:`size-4`}),` Add account`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>{S(null),w(`export`)},children:[(0,G.jsx)(i,{className:`size-4`}),` Export`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`import`),children:[(0,G.jsx)(I,{className:`size-4`}),` Import`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`rotation`),children:[(0,G.jsx)(D,{className:`size-4`}),` Rotation`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`token-test`),children:[(0,G.jsx)(a,{className:`size-4`}),` Token test`]})]})}),(0,G.jsx)(V,{message:d,onDismiss:()=>f(null)}),(0,G.jsxs)(`section`,{className:`space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium`,children:`Accounts`}),A&&(0,G.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`usage `,me(new Date(A).getTime())]})]}),r?(0,G.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,G.jsx)(s,{className:`size-4 animate-spin`}),` Loading accounts...`]}):e.length===0?(0,G.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,G.jsx)(o,{className:`size-5 text-muted-foreground`}),(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No accounts connected yet.`}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Add one to start using PPM.`})]}):(0,G.jsx)(H,{children:e.map(e=>(0,G.jsx)(he,{layout:`strip`,entry:e,isActive:e.accountId===n,accountInfo:k.get(e.accountId),onToggle:E,toggling:p===e.accountId,onDelete:(e,t)=>_({id:e,display:t}),onExport:e=>{S(e),w(`export`)},onViewProfile:(e,t)=>y({profile:e,accountId:t}),flash:l.has(e.accountId)},e.accountId))})]}),v&&(0,G.jsx)(Se,{profile:v.profile,accountId:v.accountId,onClose:()=>y(null)}),g&&(0,G.jsx)(Ce,{display:g.display,onConfirm:()=>void O(),onCancel:()=>_(null)}),(0,G.jsx)(we,{open:C===`add`,onOpenChange:e=>w(e?`add`:null),onSuccess:T}),(0,G.jsx)(Ee,{open:C===`export`,onOpenChange:e=>{w(e?`export`:null),e||S(null)},accounts:t,preselectId:b,onMessage:f}),(0,G.jsx)(De,{open:C===`import`,onOpenChange:e=>w(e?`import`:null),onSuccess:T}),(0,G.jsx)(Ae,{open:C===`rotation`,onOpenChange:e=>w(e?`rotation`:null)}),(0,G.jsx)(Fe,{open:C===`token-test`,onOpenChange:e=>w(e?`token-test`:null),accounts:t})]})}function Ie({open:e,onOpenChange:t,label:n,onLabelChange:r,apiKey:i,onApiKeyChange:a,adding:c,onAddApiKey:l,deviceWaiting:u,onStartDevice:d,device:f,error:p}){return(0,G.jsx)(S,{open:e,onOpenChange:t,children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsx)(g,{className:`text-sm`,children:`Add Codex Account`}),(0,G.jsxs)(k,{className:`text-xs leading-relaxed`,children:[`Each account keeps its own login (its own `,(0,G.jsx)(`code`,{children:`CODEX_HOME`}),`).`]})]}),(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`rounded-md border p-3 space-y-2`,children:[(0,G.jsx)(`p`,{className:`text-[11px] font-medium`,children:`Recommended: sign in with ChatGPT`}),(0,G.jsx)(m,{size:`sm`,className:`w-full cursor-pointer gap-1.5`,onClick:d,disabled:u,children:u?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(s,{className:`size-4 animate-spin`}),` Waiting for authorization...`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(P,{className:`size-4`}),` Sign in with ChatGPT`]})}),f&&(0,G.jsxs)(`div`,{className:`rounded-md border border-primary/40 bg-primary/10 p-2.5 space-y-1.5`,children:[(0,G.jsx)(`p`,{className:`text-[11px]`,children:`Enter this code to authorize:`}),(0,G.jsx)(`div`,{className:`font-mono text-lg tracking-widest`,children:f.userCode}),(0,G.jsxs)(`a`,{href:f.verificationUrl,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-primary hover:underline text-[11px]`,children:[(0,G.jsx)(v,{className:`size-3`}),` `,f.verificationUrl]})]})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`div`,{className:`flex-1 border-t`}),(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`or paste an API key`}),(0,G.jsx)(`div`,{className:`flex-1 border-t`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{htmlFor:`codex-api-key`,className:`text-xs`,children:`OpenAI API key`}),(0,G.jsx)(A,{id:`codex-api-key`,type:`password`,placeholder:`sk-...`,value:i,onChange:e=>a(e.target.value),className:`text-xs font-mono`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{htmlFor:`codex-label`,className:`text-xs`,children:`Label (optional)`}),(0,G.jsx)(A,{id:`codex-label`,placeholder:`e.g. Personal, Work`,value:n,onChange:e=>r(e.target.value),className:`text-xs`})]})]}),p&&(0,G.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:p}),(0,G.jsxs)(M,{children:[(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Cancel`}),(0,G.jsxs)(m,{size:`sm`,className:`text-xs cursor-pointer gap-1.5`,onClick:l,disabled:!i.trim()||c,children:[c?(0,G.jsx)(s,{className:`size-3.5 animate-spin`}):(0,G.jsx)(o,{className:`size-3.5`}),`Add key`]})]})]})})}function Le({mode:e,onOpenChange:t,password:n,onPasswordChange:r,busy:a,onExport:o,onImport:c,error:l}){let u=(0,W.useRef)(null),d=e===`export`;return(0,G.jsx)(S,{open:e!==null,onOpenChange:t,children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsxs)(g,{className:`text-sm flex items-center gap-1.5`,children:[(0,G.jsx)(N,{className:`size-4`}),` `,d?`Export Codex Accounts`:`Import Codex Accounts`]}),(0,G.jsx)(k,{className:`text-xs leading-relaxed`,children:d?`Writes a password-encrypted file containing each account's login.`:`Reads a backup file. The password must be the one it was exported with.`})]}),(0,G.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,G.jsx)(b,{htmlFor:`codex-backup-password`,className:`text-xs`,children:`Password`}),(0,G.jsx)(A,{id:`codex-backup-password`,type:`password`,placeholder:d?`Choose a password`:`Password used for the export`,value:n,onChange:e=>r(e.target.value),className:`text-xs`,autoComplete:d?`new-password`:`current-password`}),(0,G.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`A backup holds full logins — keep the file and its password together.`})]}),l&&(0,G.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:l}),(0,G.jsx)(`input`,{ref:u,type:`file`,accept:`application/json,.json`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&c(t)}}),(0,G.jsxs)(M,{children:[(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Cancel`}),(0,G.jsxs)(m,{size:`sm`,className:`text-xs cursor-pointer gap-1.5`,disabled:!n.trim()||a,onClick:()=>d?o():u.current?.click(),children:[a?(0,G.jsx)(s,{className:`size-3.5 animate-spin`}):d?(0,G.jsx)(i,{className:`size-3.5`}):(0,G.jsx)(I,{className:`size-3.5`}),d?`Download backup`:`Choose file`]})]})]})})}var Re=[{value:`round-robin`,label:`Round-robin`,hint:`Take the next account each time.`},{value:`fill-first`,label:`Fill-first`,hint:`Stay on one account until it runs out.`},{value:`lowest-usage`,label:`Lowest usage`,hint:`Pick whichever has the most left.`}];function ze({open:e,onOpenChange:t,strategy:n,onChange:r}){return(0,G.jsx)(S,{open:e,onOpenChange:t,children:(0,G.jsxs)(j,{className:`sm:max-w-md`,children:[(0,G.jsxs)(w,{children:[(0,G.jsx)(g,{className:`text-sm`,children:`Codex Rotation`}),(0,G.jsx)(k,{className:`text-xs leading-relaxed`,children:`How a new chat chooses among your Codex accounts.`})]}),(0,G.jsx)(`div`,{className:`space-y-2`,children:Re.map(e=>(0,G.jsxs)(`button`,{type:`button`,onClick:()=>r(e.value),"aria-current":n===e.value?`true`:void 0,className:d(`w-full text-left rounded-md border px-3 py-2.5 min-h-11 cursor-pointer transition-colors`,n===e.value?`border-primary bg-primary/10`:`border-border hover:bg-accent/50 active:bg-accent`),children:[(0,G.jsx)(`p`,{className:`text-sm font-medium`,children:e.label}),(0,G.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.hint})]},e.value))}),(0,G.jsx)(M,{children:(0,G.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Done`})})]})})}function $(e){return e==null?null:Math.round(e*100)}function Be({usage:e}){return(0,G.jsxs)(`div`,{className:`space-y-2`,children:[(0,G.jsx)(z,{label:`5-Hour Session`,pct:$(e.fiveHour),reset:U(e.session)}),(0,G.jsx)(z,{label:`Weekly`,pct:$(e.sevenDay),reset:U(e.weekly)})]})}var Ve=2e3,He=21e4;function Ue(e){let[t,n]=(0,W.useState)([]),[r,i]=(0,W.useState)(`round-robin`),[a,o]=(0,W.useState)({}),[s,c]=(0,W.useState)(!1),[d,f]=(0,W.useState)(``),[p,m]=(0,W.useState)(``),[h,g]=(0,W.useState)(!1),[_,v]=(0,W.useState)(null),[y,b]=(0,W.useState)(null),[x,S]=(0,W.useState)(!1),[C,w]=(0,W.useState)(``),[T,E]=(0,W.useState)(!1),[D,O]=(0,W.useState)(!1),[k,A]=(0,W.useState)(null),j=(0,W.useRef)(null),M=(0,W.useRef)(null),N=(0,W.useCallback)(async()=>{c(!0);try{let e=await l.get(`/api/codex-accounts`);n(e.accounts),i(e.strategy),l.get(`/api/codex-accounts/usage`).then(o).catch(()=>{})}finally{c(!1)}},[]);(0,W.useEffect)(()=>{N()},[N]);let P=async()=>{if(d.trim()){g(!0),v(null);try{await l.post(`/api/codex-accounts/api-key`,{apiKey:d.trim(),label:p.trim()||void 0}),f(``),m(``),e(),await N()}catch(e){v(e.message)}finally{g(!1)}}},F=(0,W.useCallback)(t=>{let n=Date.now()+He,r=!1;j.current=()=>{r=!0};let i=e=>{r=!0,j.current=null,M.current=null,e&&v(e),b(null),S(!1)},a=async()=>{if(r)return;let o=null;try{o=await l.get(`/api/codex-accounts/device-login/${t}/status`)}catch{}if(!r){if(o?.state===`done`){i(),m(``),e(),await N();return}if(o?.state===`error`){i(o.error);return}if(Date.now()>n){i(`Device login timed out.`);return}setTimeout(a,Ve)}};a()},[N]);return(0,W.useEffect)(()=>()=>{j.current?.();let e=M.current;e&&l.del(`/api/codex-accounts/device-login/${e}`).catch(()=>{})},[]),{accounts:t,strategy:r,usages:a,loading:s,apiKey:d,setApiKey:f,label:p,setLabel:m,adding:h,err:_,setErr:v,device:y,deviceWaiting:x,backupPassword:C,setBackupPassword:w,exporting:T,importing:D,msg:k,setMsg:A,load:N,addApiKey:P,startDevice:async()=>{v(null);try{let e=await l.post(`/api/codex-accounts/device-login`,{label:p.trim()||void 0});b(e),S(!0),M.current=e.id,F(e.id)}catch(e){v(e.message)}},remove:async e=>{await l.del(`/api/codex-accounts/${e}`),await N()},changeStrategy:async e=>{i(e);try{await l.put(`/api/codex-accounts/strategy`,{strategy:e})}catch{}},doExport:async()=>{if(!C.trim()){v(`Set a backup password first.`);return}E(!0),v(null),A(null);try{let t={"Content-Type":`application/json`},n=u();n&&(t.Authorization=`Bearer ${n}`);let r=await fetch(`/api/codex-accounts/export`,{method:`POST`,headers:t,body:JSON.stringify({password:C})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error??`Export failed: ${r.status}`)}let i=await r.text(),a=new Blob([i],{type:`application/json`}),o=document.createElement(`a`);o.href=URL.createObjectURL(a),o.download=`ppm-codex-accounts-backup.json`,o.click(),URL.revokeObjectURL(o.href),A(`Backup downloaded.`),e()}catch(e){v(e.message)}finally{E(!1)}},doImport:async t=>{if(!C.trim()){v(`Enter the backup password first.`);return}O(!0),v(null),A(null);try{let n=await t.text(),r=await l.post(`/api/codex-accounts/import`,{data:n,password:C});A(`Imported ${r.imported}${r.skipped?`, skipped ${r.skipped}`:``}.`),e(),await N()}catch(e){v(e.message)}finally{O(!1)}}}}function We(){let[e,t]=(0,W.useState)(null),n=Ue(()=>t(null));return(0,G.jsxs)(`div`,{className:`space-y-4`,children:[(0,G.jsx)(R,{description:(0,G.jsxs)(G.Fragment,{children:[`Each Codex account keeps its own login (`,(0,G.jsx)(`code`,{children:`CODEX_HOME`}),`). One is picked per chat by the rotation setting.`]}),onRefresh:()=>void n.load(),refreshing:n.loading,actions:(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(m,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`add`),children:[(0,G.jsx)(x,{className:`size-4`}),` Add account`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`export`),children:[(0,G.jsx)(i,{className:`size-4`}),` Export`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`import`),children:[(0,G.jsx)(I,{className:`size-4`}),` Import`]}),(0,G.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`rotation`),children:[(0,G.jsx)(D,{className:`size-4`}),` Rotation`]})]})}),(0,G.jsx)(V,{message:n.msg??n.err,onDismiss:()=>{n.setMsg(null),n.setErr(null)}}),(0,G.jsxs)(`section`,{className:`space-y-2`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`h3`,{className:`text-sm font-medium`,children:`Codex Accounts`}),(0,G.jsx)(`span`,{className:`text-[10px] text-muted-foreground capitalize`,children:n.strategy.replace(`-`,` `)})]}),n.loading&&n.accounts.length===0?(0,G.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,G.jsx)(s,{className:`size-4 animate-spin`}),` Loading accounts...`]}):n.accounts.length===0?(0,G.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,G.jsx)(o,{className:`size-5 text-muted-foreground`}),(0,G.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No Codex accounts yet.`}),(0,G.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Chats use your default `,(0,G.jsx)(`code`,{children:`~/.codex`}),` login until you add one.`]})]}):(0,G.jsx)(H,{children:n.accounts.map(e=>{let t=n.usages[e.id]??{};return(0,G.jsxs)(B,{dense:!0,className:`min-w-[300px] shrink-0 snap-start`,"data-testid":`account-card`,"data-account-id":e.id,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`text-sm font-medium truncate flex-1 min-w-0`,children:e.label}),(0,G.jsx)(`span`,{className:`text-[10px] uppercase tracking-wide text-text-subtle border border-border rounded px-1 shrink-0`,children:e.type}),e.planType&&(0,G.jsx)(`span`,{className:`text-[10px] text-text-subtle shrink-0`,children:e.planType}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>void n.remove(e.id),title:`Remove account`,"aria-label":`Remove account`,className:`p-2 rounded cursor-pointer text-text-subtle hover:text-error hover:bg-surface-elevated transition-colors shrink-0`,children:(0,G.jsx)(C,{className:`size-4`})})]}),(0,G.jsx)(Be,{usage:t})]},e.id)})})]}),(0,G.jsx)(Ie,{open:e===`add`,onOpenChange:e=>t(e?`add`:null),label:n.label,onLabelChange:n.setLabel,apiKey:n.apiKey,onApiKeyChange:n.setApiKey,adding:n.adding,onAddApiKey:()=>void n.addApiKey(),deviceWaiting:n.deviceWaiting,onStartDevice:()=>void n.startDevice(),device:n.device,error:n.err}),(0,G.jsx)(Le,{mode:e===`export`?`export`:e===`import`?`import`:null,onOpenChange:e=>{e||t(null)},password:n.backupPassword,onPasswordChange:n.setBackupPassword,busy:n.exporting||n.importing,onExport:()=>void n.doExport(),onImport:e=>void n.doImport(e),error:n.err}),(0,G.jsx)(ze,{open:e===`rotation`,onOpenChange:e=>t(e?`rotation`:null),strategy:n.strategy,onChange:e=>void n.changeStrategy(e)})]})}var Ge=[{id:`claude`,label:`Claude`},{id:`codex`,label:`Codex`}];function Ke(){let[e,t]=(0,W.useState)(null),[n,r]=(0,W.useState)(`claude`);(0,W.useEffect)(()=>{let e=!1;return ae().then(n=>{e||t(new Set(Object.keys(n.providers??{})))}).catch(()=>{e||t(new Set([`claude`]))}),()=>{e=!0}},[]);let i=Ge.filter(t=>t.id===`claude`||e?.has(t.id)),a=i.length>1;return(0,G.jsxs)(`div`,{className:`space-y-4`,"data-testid":`accounts-pane`,"data-provider":n,children:[a&&(0,G.jsx)(`div`,{className:`flex gap-1 border-b border-border/50`,children:i.map(e=>(0,G.jsxs)(`button`,{onClick:()=>r(e.id),"data-testid":`accounts-tab-${e.id}`,"aria-current":n===e.id?`page`:void 0,className:`flex items-center gap-1.5 px-3 py-2 text-xs rounded-t transition-colors cursor-pointer ${n===e.id?`text-primary border-b-2 border-primary font-medium`:`text-text-subtle hover:text-text-secondary`}`,children:[(0,G.jsx)(F,{providerId:e.id}),e.label]},e.id))}),e===null&&!a&&(0,G.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,G.jsx)(s,{className:`size-3 animate-spin`}),` Checking configured providers...`]}),n===`claude`?(0,G.jsx)(Q,{}):(0,G.jsx)(We,{})]})}export{Ke as AccountsSettingsSection};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{K as e}from"./vendor-mermaid-BKWscKt0.js";export{e as createArchitectureServices};
|