@hienlh/ppm 0.20.8 → 0.20.10
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 +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-DC2A6FhQ.js +1 -0
- package/dist/web/assets/{ai-resource-editor-CMQfhxXp.js → ai-resource-editor-DDhuy_AR.js} +1 -1
- package/dist/web/assets/ai-settings-section-J9Rbs26g.js +1 -0
- package/dist/web/assets/{ai-settings-section-M07DCjAI.js → ai-settings-section-OrhLykA2.js} +1 -1
- package/dist/web/assets/{angular-html-BtJLNcMw.js → angular-html-D4qjt-75.js} +1 -1
- package/dist/web/assets/{angular-ts-CQiu5F_W.js → angular-ts-DvLn04T8.js} +1 -1
- package/dist/web/assets/{api-client-DwXlVfXP.js → api-client-DCzgxFNY.js} +1 -1
- package/dist/web/assets/api-client-PMwZQ4iC.js +1 -0
- package/dist/web/assets/{api-settings-BQIwZoLm.js → api-settings-t5xLrBkQ.js} +1 -1
- package/dist/web/assets/{api-themes-CmJZLEY1.js → api-themes-CJmyQeMk.js} +1 -1
- package/dist/web/assets/{apl-CKZvgs-w.js → apl-DQOoPzqd.js} +1 -1
- package/dist/web/assets/{appearance-settings-section-BBlJtEm5.js → appearance-settings-section-BQ1dH29t.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-D55g5j-p.js +1 -0
- package/dist/web/assets/arrow-left-y44wEZrw.js +1 -0
- package/dist/web/assets/arrow-right-SQ8KJIvE.js +1 -0
- package/dist/web/assets/{astro-D0b8ssLD.js → astro-C2zFJ1Er.js} +1 -1
- package/dist/web/assets/{audio-preview-DPMXOZ55.js → audio-preview-CAVqEwDi.js} +1 -1
- package/dist/web/assets/{blade-DOIpINLw.js → blade-CBD8sEa1.js} +1 -1
- package/dist/web/assets/{bot-D3-n2i31.js → bot-BNu2OM_S.js} +1 -1
- package/dist/web/assets/{brain-CuAQMSBE.js → brain-BsjvCk4k.js} +1 -1
- package/dist/web/assets/{bsl-CJ7_JlQ8.js → bsl-bs2JpeTQ.js} +1 -1
- package/dist/web/assets/{button-zgoXa9r7.js → button-DHI8IY_N.js} +1 -1
- package/dist/web/assets/{cairo-5CpV2T1P.js → cairo-DT2g4i_6.js} +1 -1
- package/dist/web/assets/{calendar-clock-CDP7AVjA.js → calendar-clock-Zydwzvp7.js} +1 -1
- package/dist/web/assets/chat-tab-D2le8LxY.js +15 -0
- package/dist/web/assets/check-DczxQ5UD.js +1 -0
- package/dist/web/assets/{chevron-down-B9puixxZ.js → chevron-down-BCt_kn-R.js} +1 -1
- package/dist/web/assets/chevron-right-Lt-y9H_e.js +1 -0
- package/dist/web/assets/{chevron-up-BPAINgoK.js → chevron-up-CRl1AF4q.js} +1 -1
- package/dist/web/assets/circle-D4vp8Yky.js +1 -0
- package/dist/web/assets/circle-question-mark-BGbDcz7E.js +1 -0
- package/dist/web/assets/clock-BBIE-uf3.js +1 -0
- package/dist/web/assets/{cobol-BreMVrtc.js → cobol-B2rp6LA1.js} +1 -1
- package/dist/web/assets/code-CvgQViOi.js +1 -0
- package/dist/web/assets/code-editor-D-8oqMBM.js +7 -0
- package/dist/web/assets/codex-daily-guard-h4ZpEemV.js +1 -0
- package/dist/web/assets/{coffee-D7DoKh5b.js → coffee-D5ShQC08.js} +1 -1
- package/dist/web/assets/{conflict-editor-C-Nv8YYj.js → conflict-editor-B0Mj8pYR.js} +1 -1
- package/dist/web/assets/{context-menu-DM9CgxGh.js → context-menu-I07Ld1Yr.js} +1 -1
- package/dist/web/assets/{copy-CXuIH4VC.js → copy-Bqr2VxN5.js} +1 -1
- package/dist/web/assets/{cpp-BnWeWAoE.js → cpp-BmKOH-E0.js} +1 -1
- package/dist/web/assets/{createLucideIcon-D6fVXe3s.js → createLucideIcon-CLMdC3Kl.js} +1 -1
- package/dist/web/assets/{crystal-D2pJbFUn.js → crystal-B7u_ZTpu.js} +1 -1
- package/dist/web/assets/{csv-preview-ou3KFzIH.js → csv-preview-Ds2oCW6U.js} +1 -1
- package/dist/web/assets/{data-grid-overlay-editor-dnWnblYo.js → data-grid-overlay-editor-DJWgclot.js} +1 -1
- package/dist/web/assets/{data-grid-types-BfGeMDy0.js → data-grid-types-Uu77aFvI.js} +1 -1
- package/dist/web/assets/{database-Dz0W7OH7.js → database-BHxcoKlT.js} +1 -1
- package/dist/web/assets/{database-viewer-Ckqg_-SS.js → database-viewer-CiwQ6spt.js} +1 -1
- package/dist/web/assets/{diff-viewer-CMzFnBCD.js → diff-viewer-BomFSnpH.js} +1 -1
- package/dist/web/assets/{dist-CWMPvPem.js → dist-BTdRgQig.js} +1 -1
- package/dist/web/assets/{docx-preview-B7Aospmh.js → docx-preview-PsyMM8SN.js} +1 -1
- package/dist/web/assets/{download-D70Q4Ba6.js → download-hiDsGuxx.js} +1 -1
- package/dist/web/assets/{edge-aqGMtbY3.js → edge--MpXROh5.js} +1 -1
- package/dist/web/assets/{edit-diff-preview-BvgPvuhH.js → edit-diff-preview-ESj6hMoD.js} +3 -3
- package/dist/web/assets/{elixir-CsYMBLc5.js → elixir-DL8mOfzH.js} +1 -1
- package/dist/web/assets/{elm-BU8C2gFp.js → elm-eVlzIFEZ.js} +1 -1
- package/dist/web/assets/{erb-Z_E49ab8.js → erb-BgvaH9l0.js} +1 -1
- package/dist/web/assets/{erlang-BRqOjXH9.js → erlang-CEf8Sfhs.js} +1 -1
- package/dist/web/assets/{esm-BHyWbWKE.js → esm-C5xqy163.js} +2 -2
- package/dist/web/assets/{explorer-body-CVx4qaIF.js → explorer-body-CExMoOiW.js} +2 -2
- package/dist/web/assets/explorer-window-content-Hy9kB6Q7.js +1 -0
- package/dist/web/assets/{extension-manager-section-CtcpVMWs.js → extension-manager-section-DMb56aut.js} +1 -1
- package/dist/web/assets/{extension-webview-DZ_QRZSM.js → extension-webview-CQB0Uvdo.js} +1 -1
- package/dist/web/assets/{eye-dfZn7evX.js → eye-DYS5JBeU.js} +1 -1
- package/dist/web/assets/{eye-off-CmtfyRUD.js → eye-off-YWCuob9F.js} +1 -1
- package/dist/web/assets/{file-exclamation-point-D5K2aaLi.js → file-exclamation-point-DpdJqj9-.js} +1 -1
- package/dist/web/assets/{files-settings-section-D7v-6nTa.js → files-settings-section-CVHPO3N9.js} +1 -1
- package/dist/web/assets/{flask-conical-Dix4qNDj.js → flask-conical-BUxpYe-g.js} +1 -1
- package/dist/web/assets/{folder-symlink-BavsIzoj.js → folder-symlink-DKTEop0L.js} +1 -1
- package/dist/web/assets/{fortran-fixed-form-CWbxmDGR.js → fortran-fixed-form-yAUsSjab.js} +1 -1
- package/dist/web/assets/{fsharp-DKMYbq6I.js → fsharp-BEWvY_ZR.js} +1 -1
- package/dist/web/assets/{gdresource-B3yFau4V.js → gdresource-CYZFZ057.js} +1 -1
- package/dist/web/assets/{general-settings-section-BW_h8pdA.js → general-settings-section-CWYR9F5y.js} +1 -1
- package/dist/web/assets/{git-commit-BW0p3Ekk.js → git-commit-DedchUJ6.js} +1 -1
- package/dist/web/assets/{git-log-panel-BQZkJDu0.js → git-log-panel-DYLF-XSq.js} +1 -1
- package/dist/web/assets/{git-rebase-DrvmQCS7.js → git-rebase-DPvHNzQr.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-At-P8hlA.js +1 -0
- package/dist/web/assets/{glide-data-grid-JKEslqGe.js → glide-data-grid-BxFN-Z6F.js} +8 -8
- package/dist/web/assets/{glimmer-js-BY1XApJJ.js → glimmer-js-B4hPYBMX.js} +1 -1
- package/dist/web/assets/{glimmer-ts-DPZtxF8N.js → glimmer-ts-C0WfcQnO.js} +1 -1
- package/dist/web/assets/{glsl-DZ8G_Hvf.js → glsl-DHW88hTv.js} +1 -1
- package/dist/web/assets/{graphql-Ck06uCZy.js → graphql-CEvXbo6e.js} +1 -1
- package/dist/web/assets/group-chat-tab-Ch6OGMKj.js +1 -0
- package/dist/web/assets/{hack-pLogDwAs.js → hack-lKfhn1vw.js} +1 -1
- package/dist/web/assets/{haml-CBqeCQ2A.js → haml-AjKlANaB.js} +1 -1
- package/dist/web/assets/{hand-CIPALZsE.js → hand-BomFk_WG.js} +1 -1
- package/dist/web/assets/{handlebars-B66JmVtp.js → handlebars-B8fZzj2G.js} +1 -1
- package/dist/web/assets/{html-Dk4wmfwC.js → html-H_S3FJMj.js} +1 -1
- package/dist/web/assets/{html-derivative-CJWqfN51.js → html-derivative-VZmoMdQD.js} +1 -1
- package/dist/web/assets/{http-CexhotTh.js → http-DBxROFKc.js} +1 -1
- package/dist/web/assets/{hurl-BScKFk3Z.js → hurl-Hf7XWQHN.js} +1 -1
- package/dist/web/assets/{hxml-DAle7vtu.js → hxml-BRhRKwSo.js} +1 -1
- package/dist/web/assets/{image-preview-V5SglTWk.js → image-preview-DjT5Xb2L.js} +1 -1
- package/dist/web/assets/index-BfDJvjH9.js +52 -0
- package/dist/web/assets/index-Di9nVG3y.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-btSsuixb.js +1 -0
- package/dist/web/assets/{jinja-yHpyD80t.js → jinja-D3jMH0jG.js} +1 -1
- package/dist/web/assets/{jira-watcher-section-VyzVbAnw.js → jira-watcher-section-DZvWeUAW.js} +1 -1
- package/dist/web/assets/{jison-BY6WLJVu.js → jison-CZtpkLiY.js} +1 -1
- package/dist/web/assets/{julia-Dd_iYQDT.js → julia-DwFjOpos.js} +1 -1
- package/dist/web/assets/{just-BTuUKpxF.js → just-BEfj8dHN.js} +1 -1
- package/dist/web/assets/{key-round-oIll4vo-.js → key-round-BhkPzOjZ.js} +1 -1
- package/dist/web/assets/keybindings-store-CNqxSJxv.js +1 -0
- package/dist/web/assets/{keyboard-BLwfiRkT.js → keyboard-IQMXPNIE.js} +1 -1
- package/dist/web/assets/{keyboard-shortcuts-section-DOJi75mV.js → keyboard-shortcuts-section-DAFNxA49.js} +1 -1
- package/dist/web/assets/{latex-Dt3OUlMZ.js → latex-C6Rb_zGG.js} +1 -1
- package/dist/web/assets/{lib-BAsciSLw.js → lib-CFTK00ux.js} +1 -1
- package/dist/web/assets/{liquid-BxPJU2ix.js → liquid-DTVs9cD3.js} +1 -1
- package/dist/web/assets/loader-circle-Bm-Dq_wA.js +1 -0
- package/dist/web/assets/{lua-DEGIvn7d.js → lua-C1zfiqhG.js} +1 -1
- package/dist/web/assets/markdown-renderer-BSiaxWjE.js +1 -0
- package/dist/web/assets/markdown-renderer-CMNnYOPG.js +3 -0
- package/dist/web/assets/{marko-BDxwBJur.js → marko-_hrXozl2.js} +1 -1
- package/dist/web/assets/{mdc-B8aXPTg7.js → mdc-AX9XWu8K.js} +1 -1
- package/dist/web/assets/{media-url-TYMlO0M5.js → media-url-D43IHXnP.js} +1 -1
- package/dist/web/assets/{mobile-bottom-sheet-Ch1e_JBq.js → mobile-bottom-sheet-GSto0_0m.js} +1 -1
- package/dist/web/assets/mobile-explorer-sheet-BMg4Q9Bm.js +1 -0
- package/dist/web/assets/{monitor-CG69bSMW.js → monitor-DEoVYSPl.js} +1 -1
- package/dist/web/assets/{nextflow-DBVZnnT_.js → nextflow-xJ5dkaQ2.js} +1 -1
- package/dist/web/assets/{nginx-Crpyd-Do.js → nginx-BfbjvmIV.js} +1 -1
- package/dist/web/assets/{nim-BSqTBYDj.js → nim-KrUnNSwZ.js} +1 -1
- package/dist/web/assets/notification-store-CRlOB9I9.js +1 -0
- package/dist/web/assets/{notifications-settings-section-CeRvkXOM.js → notifications-settings-section-Cci_OOHx.js} +1 -1
- package/dist/web/assets/{number-overlay-editor-DldrUNs4.js → number-overlay-editor-CGZ1ObrN.js} +1 -1
- package/dist/web/assets/{overview-panel-DA0QB1-5.js → overview-panel-Ni1Wqr3E.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-B20_sIFd.js +1 -0
- package/dist/web/assets/{panel-store-D42k25jy.js → panel-store-BcgZsiXU.js} +1 -1
- package/dist/web/assets/{pdf-preview-Cq33D5ej.js → pdf-preview-C28MEOND.js} +1 -1
- package/dist/web/assets/{perl-BU0kbB-K.js → perl-DAexWIeo.js} +1 -1
- package/dist/web/assets/{php-D9n1ikHN.js → php-DXc7GdU9.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-nzfJdXCC.js +1 -0
- package/dist/web/assets/portal-container-context-DO44JpXO.js +1 -0
- package/dist/web/assets/{postgres-viewer-C__Z0C0s.js → postgres-viewer-DmbVhmJ8.js} +3 -3
- package/dist/web/assets/power-BMdSjXYW.js +1 -0
- package/dist/web/assets/{ppmbot-settings-section-Cma4VU7p.js → ppmbot-settings-section-Cef8FSS6.js} +1 -1
- package/dist/web/assets/{process-table-DH_HXtGc.js → process-table-BfixzY3r.js} +1 -1
- package/dist/web/assets/{project-store-C83MMnlt.js → project-store-DCDLF-x3.js} +1 -1
- package/dist/web/assets/{proxy-settings-section-xrTsFlTF.js → proxy-settings-section-BlLWfinY.js} +1 -1
- package/dist/web/assets/{pug-BOpaczDr.js → pug-CHds8FDl.js} +1 -1
- package/dist/web/assets/{qml-B-cQXhrg.js → qml-DBt6oNnU.js} +1 -1
- package/dist/web/assets/{query-audit-section-Drk97gb8.js → query-audit-section-qnSL15x8.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-CS4sHKD5.js +1 -0
- package/dist/web/assets/{razor-DFB0pNCh.js → razor-DVDe2z8Z.js} +1 -1
- package/dist/web/assets/{react-DqIU0LFM.js → react-Bf5xrFLG.js} +1 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-CG6h4OL2.js +2 -0
- package/dist/web/assets/{remote-desktop-mobile-view-Gk8UCVIx.js → remote-desktop-mobile-view-D__2WLV5.js} +1 -1
- package/dist/web/assets/{remote-desktop-readiness-gate-6reSZvad.js → remote-desktop-readiness-gate-rL48PCUH.js} +1 -1
- package/dist/web/assets/{remote-desktop-window-content-BW2KqONI.js → remote-desktop-window-content-DlGUCbxq.js} +1 -1
- package/dist/web/assets/{rst-DAXedsgm.js → rst-s3rP0H8p.js} +1 -1
- package/dist/web/assets/{ruby-BCO4polC.js → ruby-sRcfbjlr.js} +1 -1
- package/dist/web/assets/{run-in-terminal-DoTOtgQS.js → run-in-terminal-Yt_lq4T9.js} +1 -1
- package/dist/web/assets/{sas-DfB5dcFC.js → sas-CuyZeQJw.js} +1 -1
- package/dist/web/assets/{save-B1y4KIK9.js → save-CIuK3QI4.js} +1 -1
- package/dist/web/assets/{schedules-settings-section-DcKEz-S7.js → schedules-settings-section-BUqf3KTd.js} +1 -1
- package/dist/web/assets/{scss-BknIVgn7.js → scss-B9m4FneT.js} +1 -1
- package/dist/web/assets/{send-B9VUQlEK.js → send-DQz3yIWM.js} +1 -1
- package/dist/web/assets/{send-to-chat-Kl-0dNwN.js → send-to-chat-01eMNs3j.js} +1 -1
- package/dist/web/assets/separator-CE0YEyaB.js +1 -0
- package/dist/web/assets/settings-body-Baw2komX.js +2 -0
- package/dist/web/assets/{settings-store-_s4xFcFq.js → settings-store-CuQlVCIe.js} +2 -2
- package/dist/web/assets/settings-tab-DCW-3C38.js +1 -0
- package/dist/web/assets/settings-window-content-CVxOGqPV.js +1 -0
- package/dist/web/assets/{shaderlab-CPu31TpY.js → shaderlab-BuCltaXx.js} +1 -1
- package/dist/web/assets/{shellsession-CFX4c_TM.js → shellsession-DG_WIFRW.js} +1 -1
- package/dist/web/assets/{shield-check-BJSX7cAS.js → shield-check-46EViZ6-.js} +1 -1
- package/dist/web/assets/{shield-off-E1cQwXdc.js → shield-off-Dx5mw3le.js} +1 -1
- package/dist/web/assets/{soy-rz9hilgm.js → soy-CKNCwmqR.js} +1 -1
- package/dist/web/assets/{sparkles-blTKn0vi.js → sparkles-Bay_CedB.js} +1 -1
- package/dist/web/assets/{sparql-Bo8ZDeqE.js → sparql-BEH92-9e.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BoYxc5vd.js → sql-query-editor-BTMEy88p.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-O5lF3MMj.js → sqlite-viewer-BWLSC3VJ.js} +1 -1
- package/dist/web/assets/{stata-B5J-QMyE.js → stata-Bt5IUWCl.js} +1 -1
- package/dist/web/assets/{streaming-store-QQvg1cS-.js → streaming-store-Dw3ZR1E4.js} +1 -1
- package/dist/web/assets/{surrealql-Caw1ADnG.js → surrealql-B5M94PT2.js} +1 -1
- package/dist/web/assets/{svelte-D3oMVcxz.js → svelte-BqLoF5fB.js} +1 -1
- package/dist/web/assets/{system-monitor-body-C2mVJ7PV.js → system-monitor-body-BqPyB0CY.js} +2 -2
- package/dist/web/assets/system-monitor-tab-BXRvCThe.js +1 -0
- package/dist/web/assets/system-monitor-window-content-CvvwXkmW.js +1 -0
- package/dist/web/assets/{tab-host-window-content-C7F6D8hJ.js → tab-host-window-content-23IR3qzu.js} +1 -1
- package/dist/web/assets/{tab-store-B2ip0-Mv.js → tab-store-Dsk4jnlN.js} +1 -1
- package/dist/web/assets/{table-8HT8BG30.js → table-BbD_HNPU.js} +1 -1
- package/dist/web/assets/team-member-sheet-BXJtrQAB.js +2 -0
- package/dist/web/assets/{team-member-window-content-BwOTsc9r.js → team-member-window-content-CBWnzwZ1.js} +1 -1
- package/dist/web/assets/{templ-BAdNyIOL.js → templ-BxGWIwYz.js} +1 -1
- package/dist/web/assets/{terminal-tab-DlZW3MCn.js → terminal-tab-uNw7Yvwg.js} +3 -3
- package/dist/web/assets/{tex-IQ8mELOR.js → tex-B9CPrNBA.js} +1 -1
- package/dist/web/assets/{text-wrap-DafY0-Pa.js → text-wrap-97GXZlav.js} +1 -1
- package/dist/web/assets/{tool-cards-yiwO861p.js → tool-cards-CjirOQfx.js} +6 -6
- package/dist/web/assets/treemap-KZPCXAKY-BBrhTPZk.js +1 -0
- package/dist/web/assets/{ts-tags-D1DDO2jl.js → ts-tags-CObhnP_s.js} +1 -1
- package/dist/web/assets/{twig-C8Fd5RvV.js → twig-ZcDaz0E8.js} +1 -1
- package/dist/web/assets/{use-blob-url-D358Rpyp.js → use-blob-url-D-NnFGAr.js} +1 -1
- package/dist/web/assets/{use-coarse-long-press-BsBpxWup.js → use-coarse-long-press-CynaAB7m.js} +1 -1
- package/dist/web/assets/{use-inline-blame-D2pZjDoA.js → use-inline-blame-BLPCADZ8.js} +1 -1
- package/dist/web/assets/{use-is-mobile-Bi42QhIi.js → use-is-mobile-BsqeOLv4.js} +1 -1
- package/dist/web/assets/use-monaco-theme-D2ETCHji.js +1 -0
- package/dist/web/assets/use-open-team-member-BlUqTp-l.js +1 -0
- package/dist/web/assets/{use-remote-desktop-display-choice-BnVT4dhX.js → use-remote-desktop-display-choice-B4O11KIj.js} +1 -1
- package/dist/web/assets/{use-visual-viewport-CNdG4QHH.js → use-visual-viewport-hdC_hRtB.js} +1 -1
- package/dist/web/assets/{use-websocket-DQg9BQcq.js → use-websocket-CUKjQFAl.js} +1 -1
- package/dist/web/assets/vendor-markdown-3-bej77C.js +291 -0
- package/dist/web/assets/{vendor-mermaid-CfY1-PkA.js → vendor-mermaid-BoRFiriK.js} +1 -1
- package/dist/web/assets/{vendor-ui-BBdkypKW.js → vendor-ui-D1NQnrtd.js} +1 -1
- package/dist/web/assets/{video-preview-Dc4YbBqm.js → video-preview-BlD1DNP8.js} +1 -1
- package/dist/web/assets/{vue-EvccXlkP.js → vue-TgfQfAF8.js} +1 -1
- package/dist/web/assets/{vue-html-Dg0xUJCh.js → vue-html-DbAh9aHW.js} +1 -1
- package/dist/web/assets/{vue-vine-BdrMg72k.js → vue-vine-DQ8US6vO.js} +1 -1
- package/dist/web/assets/{window-pip-registry-BWxaVLj5.js → window-pip-registry-DfPfSFQg.js} +1 -1
- package/dist/web/assets/{window-store-CfxP5yor.js → window-store-BSXqIkwB.js} +1 -1
- package/dist/web/assets/ws-auth-ZB8jvzhM.js +1 -0
- package/dist/web/assets/x-TEI-uJYo.js +1 -0
- package/dist/web/assets/{xml-MmDclzxK.js → xml-CXzUNYMl.js} +1 -1
- package/dist/web/assets/{xsl-DQEFs6Dd.js → xsl-CdnFww1s.js} +1 -1
- package/dist/web/index.html +43 -43
- package/dist/web/monacoeditorwork/css.worker.bundle.js +122 -122
- package/dist/web/monacoeditorwork/editor.worker.bundle.js +78 -78
- package/dist/web/monacoeditorwork/html.worker.bundle.js +110 -110
- package/dist/web/monacoeditorwork/json.worker.bundle.js +108 -108
- package/dist/web/monacoeditorwork/ts.worker.bundle.js +81 -81
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/scripts/check-ppm-dir-usage.sh +0 -0
- package/scripts/install.sh +0 -0
- package/scripts/release.sh +0 -0
- package/src/providers/codex-app-server/codex-event-mapper.ts +28 -1
- package/src/providers/codex-app-server/codex-provider.ts +38 -5
- package/src/providers/codex-app-server/codex-usage-parser.ts +3 -1
- package/src/server/routes/codex-accounts.ts +9 -5
- package/src/services/codex-account-login.ts +33 -5
- package/src/services/codex-account-portability.ts +3 -2
- package/src/services/codex-account.service.ts +48 -7
- package/src/services/codex-login-callback.ts +18 -0
- package/src/services/db.service.ts +14 -0
- package/src/services/edge-forwarder.ts +191 -191
- package/src/services/windows-process-tree.ts +351 -351
- package/src/shared/codex-daily-guard.ts +27 -0
- package/src/shared/codex-plan-label.ts +17 -0
- package/src/web/components/chat/codex-usage-panel.tsx +22 -2
- package/src/web/components/settings/accounts/account-card.tsx +43 -2
- package/src/web/components/settings/accounts/codex-accounts-section.tsx +43 -2
- package/src/web/components/settings/accounts/use-codex-accounts.ts +14 -2
- package/src/web/components/tunnels/named-tunnel/named-tunnel-copy.ts +1 -0
- package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +8 -2
- package/src/web/components/tunnels/named-tunnel/named-tunnel-step-reducer.ts +14 -2
- package/dist/web/assets/accounts-settings-section-CRXY4Bsc.js +0 -1
- package/dist/web/assets/ai-settings-section-446NZWhI.js +0 -1
- package/dist/web/assets/api-client-CYZ79uUS.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-DfR8k8Bc.js +0 -1
- package/dist/web/assets/arrow-left-DpXaakMC.js +0 -1
- package/dist/web/assets/chat-tab-Dn45anqr.js +0 -15
- package/dist/web/assets/check-BQKbhtoA.js +0 -1
- package/dist/web/assets/chevron-right-DK_HbYZC.js +0 -1
- package/dist/web/assets/circle-OKk7s0DX.js +0 -1
- package/dist/web/assets/circle-question-mark-qcWYO1P_.js +0 -1
- package/dist/web/assets/clock-BmPiGrSF.js +0 -1
- package/dist/web/assets/code-CRiIHSiv.js +0 -1
- package/dist/web/assets/code-editor-CKASeDbu.js +0 -7
- package/dist/web/assets/explorer-window-content-CqKVMkgW.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-CPd78aaT.js +0 -1
- package/dist/web/assets/group-chat-tab-CTAhtVCr.js +0 -1
- package/dist/web/assets/index-B9Wbjl0o.css +0 -2
- package/dist/web/assets/index-DVNJ2W5R.js +0 -52
- package/dist/web/assets/info-3K5VOQVL-BciNds6R.js +0 -1
- package/dist/web/assets/keybindings-store-B5dEz0n1.js +0 -1
- package/dist/web/assets/loader-circle-DxI3O9_f.js +0 -1
- package/dist/web/assets/markdown-renderer-BGPo364Y.js +0 -1
- package/dist/web/assets/markdown-renderer-DtQIHtLs.js +0 -3
- package/dist/web/assets/mobile-explorer-sheet-C1q_DhrI.js +0 -1
- package/dist/web/assets/notification-store-DvUtkAXs.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-ClD3l2Bs.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-PU6kD0rW.js +0 -1
- package/dist/web/assets/portal-container-context-DeLx1cOI.js +0 -1
- package/dist/web/assets/power-CvtnQHU4.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-4LzjL0Zt.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-sheet-6JdUr0Bj.js +0 -2
- package/dist/web/assets/separator-DvCsdlws.js +0 -1
- package/dist/web/assets/settings-body-CcKls51a.js +0 -2
- package/dist/web/assets/settings-tab-ChAk8nh2.js +0 -1
- package/dist/web/assets/settings-window-content-sA1K0cPW.js +0 -1
- package/dist/web/assets/system-monitor-tab-tXkg3jpV.js +0 -1
- package/dist/web/assets/system-monitor-window-content-BaKoFDEz.js +0 -1
- package/dist/web/assets/team-member-sheet-BA70_jmM.js +0 -2
- package/dist/web/assets/treemap-KZPCXAKY-DiumLNMg.js +0 -1
- package/dist/web/assets/use-accounts-data-B9t4BQaI.js +0 -1
- package/dist/web/assets/use-monaco-theme-DTPfPPvF.js +0 -1
- package/dist/web/assets/use-open-team-member-DGEx9xB0.js +0 -1
- package/dist/web/assets/vendor-markdown-CuWCHIVb.js +0 -291
- package/dist/web/assets/ws-auth-FRzMmfQx.js +0 -1
- package/dist/web/assets/x-Bdaog6Az.js +0 -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/dist/web/assets/{abap-D-o-bvtI.js → abap-Dbc91hEB.js} +0 -0
- /package/dist/web/assets/{actionscript-3-D2tIzAm8.js → actionscript-3-C14d4O5M.js} +0 -0
- /package/dist/web/assets/{ada-DxatBcxS.js → ada-n8mPGtZF.js} +0 -0
- /package/dist/web/assets/{andromeeda-D0LK9YJ3.js → andromeeda-DAKL0TFq.js} +0 -0
- /package/dist/web/assets/{apache-B7uMPNiW.js → apache-BDCV8YqE.js} +0 -0
- /package/dist/web/assets/{apex-B7GiXrAr.js → apex-BphlFNA_.js} +0 -0
- /package/dist/web/assets/{applescript-D_SIFkKe.js → applescript-F2pJar76.js} +0 -0
- /package/dist/web/assets/{apply-theme-BVXAUYoN.js → apply-theme-Abd1TNqE.js} +0 -0
- /package/dist/web/assets/{ara-C3iECgdg.js → ara-B32t5JRb.js} +0 -0
- /package/dist/web/assets/{asciidoc-gc8z_MMY.js → asciidoc-DenFyKu-.js} +0 -0
- /package/dist/web/assets/{asm-27qeoPOI.js → asm-D5mJz41u.js} +0 -0
- /package/dist/web/assets/{aurora-x-C5J9fWe1.js → aurora-x-CUyAXiXM.js} +0 -0
- /package/dist/web/assets/{awk-B7GBzF92.js → awk-CUwaf-l-.js} +0 -0
- /package/dist/web/assets/{ayu-dark-XlnQhuLL.js → ayu-dark-Cgg8W7cK.js} +0 -0
- /package/dist/web/assets/{ayu-light-DKLLilkU.js → ayu-light-B1c04Bhg.js} +0 -0
- /package/dist/web/assets/{ayu-mirage-Dv-XOprJ.js → ayu-mirage-CdWbuzp5.js} +0 -0
- /package/dist/web/assets/{ballerina-DACRT-sT.js → ballerina-B2-GPRG0.js} +0 -0
- /package/dist/web/assets/{bat-BlQCq2XE.js → bat-Nss7Yr-0.js} +0 -0
- /package/dist/web/assets/{beancount-DYDztRI0.js → beancount-CgaWuvpQ.js} +0 -0
- /package/dist/web/assets/{berry-BE5YKqvx.js → berry-DCFF4Zj1.js} +0 -0
- /package/dist/web/assets/{bibtex-CAm7mgEm.js → bibtex-BPNI-Gig.js} +0 -0
- /package/dist/web/assets/{bicep-BKgAbfVa.js → bicep-qCj6DX1x.js} +0 -0
- /package/dist/web/assets/{bird2-yrBNbW1G.js → bird2-DYDjG-B_.js} +0 -0
- /package/dist/web/assets/{c-txZFr4RM.js → c-CZV8SiOL.js} +0 -0
- /package/dist/web/assets/{c3-D_DrzBUd.js → c3-BG7R2A4x.js} +0 -0
- /package/dist/web/assets/{cadence-CUFCEgG9.js → cadence-BuiQVST4.js} +0 -0
- /package/dist/web/assets/{can-open-in-ppm-_yqa69dV.js → can-open-in-ppm-DU5MH6XF.js} +0 -0
- /package/dist/web/assets/{catppuccin-frappe-Dn32MuhA.js → catppuccin-frappe-C-nwrEbb.js} +0 -0
- /package/dist/web/assets/{catppuccin-latte-Dewo7yDf.js → catppuccin-latte-nRLBO6vg.js} +0 -0
- /package/dist/web/assets/{catppuccin-macchiato-D8WOWZeo.js → catppuccin-macchiato-42eAAqCw.js} +0 -0
- /package/dist/web/assets/{catppuccin-mocha-b0md48XM.js → catppuccin-mocha-4lH0_4tX.js} +0 -0
- /package/dist/web/assets/{clarity-Ct3UqLBj.js → clarity-BCPLN5zJ.js} +0 -0
- /package/dist/web/assets/{clojure-CwP5aPEo.js → clojure-Btb509Z6.js} +0 -0
- /package/dist/web/assets/{cmake-D5RF49e5.js → cmake-CGLZgJL3.js} +0 -0
- /package/dist/web/assets/{codeowners-Cl5897L_.js → codeowners-Dgqmdm5J.js} +0 -0
- /package/dist/web/assets/{codeql-BKh1RCg0.js → codeql-DDUO6ZHS.js} +0 -0
- /package/dist/web/assets/{common-lisp-BhHuD6t0.js → common-lisp-DlhZ-mM8.js} +0 -0
- /package/dist/web/assets/{coq-Dco3qwD8.js → coq-CVz-5qYC.js} +0 -0
- /package/dist/web/assets/{csharp-Dpjw9ZA9.js → csharp-CXL6GcvM.js} +0 -0
- /package/dist/web/assets/{css-CPe4cabH.js → css-CthwUm0E.js} +0 -0
- /package/dist/web/assets/{csv-BAcTN8Kt.js → csv-Bsal3rDr.js} +0 -0
- /package/dist/web/assets/{csv-parser-DbxGKdMG.js → csv-parser-iow1WWML.js} +0 -0
- /package/dist/web/assets/{cue-Cr6y60TA.js → cue-D2bSqa4C.js} +0 -0
- /package/dist/web/assets/{cypher-DWtqXXFP.js → cypher-u-EM8HmU.js} +0 -0
- /package/dist/web/assets/{d-BASiTZk4.js → d-BFVkgfjO.js} +0 -0
- /package/dist/web/assets/{dark-plus-56kmnrcl.js → dark-plus-BXlM9uFB.js} +0 -0
- /package/dist/web/assets/{dart-C5mZnjoE.js → dart-Hxx4mUdp.js} +0 -0
- /package/dist/web/assets/{dax-B4I2e7d8.js → dax-DQwsaFe_.js} +0 -0
- /package/dist/web/assets/{desktop-DekGg0BT.js → desktop-CAHGHZLk.js} +0 -0
- /package/dist/web/assets/{diff-CWnJBd73.js → diff-CAbIXu6l.js} +0 -0
- /package/dist/web/assets/{dist-BKOM_AoT.js → dist-C_bG2Tku.js} +0 -0
- /package/dist/web/assets/{docker-DevchDxK.js → docker-51FhFKmM.js} +0 -0
- /package/dist/web/assets/{dotenv-DCvtdaGJ.js → dotenv-C4fc3fLK.js} +0 -0
- /package/dist/web/assets/{dracula-8U6Vkk3l.js → dracula-CTtuacPO.js} +0 -0
- /package/dist/web/assets/{dracula-soft-Bfeew5Wg.js → dracula-soft-B-95hu1J.js} +0 -0
- /package/dist/web/assets/{dream-maker-DDTJVuoy.js → dream-maker-Di3hAOzX.js} +0 -0
- /package/dist/web/assets/{emacs-lisp-CEHJqI4m.js → emacs-lisp-C6btr6QV.js} +0 -0
- /package/dist/web/assets/{everforest-dark-CHHLt7cq.js → everforest-dark-CDQGzEiq.js} +0 -0
- /package/dist/web/assets/{everforest-light-TcTbK1sM.js → everforest-light-DRZC8v3w.js} +0 -0
- /package/dist/web/assets/{fennel-Bh4vsA1A.js → fennel-BZz92X8f.js} +0 -0
- /package/dist/web/assets/{fish-D0T0fILG.js → fish-qpLXUfGf.js} +0 -0
- /package/dist/web/assets/{fluent-CgXDXdyy.js → fluent-B3F6P-xc.js} +0 -0
- /package/dist/web/assets/{format-bytes-Bc6SqF7M.js → format-bytes-B9Dbme9a.js} +0 -0
- /package/dist/web/assets/{fortran-free-form-CUg3Xhz4.js → fortran-free-form-DjGQrmKa.js} +0 -0
- /package/dist/web/assets/{gdscript-Cx056p_k.js → gdscript-DToF1duE.js} +0 -0
- /package/dist/web/assets/{gdshader-Dj1qP4I5.js → gdshader-FZCS76-j.js} +0 -0
- /package/dist/web/assets/{genie-SBt15wn7.js → genie-CN3-FS9S.js} +0 -0
- /package/dist/web/assets/{gherkin-bTJiHIrB.js → gherkin-DT66zHzt.js} +0 -0
- /package/dist/web/assets/{github-dark-BOPhyugs.js → github-dark-5S2AJM2m.js} +0 -0
- /package/dist/web/assets/{github-dark-default-Cktqe6NF.js → github-dark-default-DNEUWmc8.js} +0 -0
- /package/dist/web/assets/{github-dark-dimmed-CeWfII_B.js → github-dark-dimmed-BVgm_raB.js} +0 -0
- /package/dist/web/assets/{github-dark-high-contrast-CTx8LpdV.js → github-dark-high-contrast-Dai8qNkr.js} +0 -0
- /package/dist/web/assets/{github-light-DVsO5Un1.js → github-light-C49nlhDa.js} +0 -0
- /package/dist/web/assets/{github-light-default-BiyPxicr.js → github-light-default-BLQcyxQl.js} +0 -0
- /package/dist/web/assets/{github-light-high-contrast-BPlnke0a.js → github-light-high-contrast-BH3u_hMd.js} +0 -0
- /package/dist/web/assets/{gleam-CWSxvD0C.js → gleam-G2907CEQ.js} +0 -0
- /package/dist/web/assets/{gn-D7NUVJuv.js → gn-fxgN7J9Q.js} +0 -0
- /package/dist/web/assets/{gnuplot-c5uXmJKc.js → gnuplot-a1TK_67n.js} +0 -0
- /package/dist/web/assets/{go-CRsHi4Cw.js → go-DLqnNJpz.js} +0 -0
- /package/dist/web/assets/{groovy-DpV0RA5r.js → groovy-D8U-plxc.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-hard-DD9fguUN.js → gruvbox-dark-hard-DRYdA7rg.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-medium-BvcwpYJ-.js → gruvbox-dark-medium-CJgayBQH.js} +0 -0
- /package/dist/web/assets/{gruvbox-dark-soft-48dCxX9M.js → gruvbox-dark-soft-spQNOlQ2.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-hard-CjJ994Ip.js → gruvbox-light-hard-FoElS0Wo.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-medium-DQJQZ_rV.js → gruvbox-light-medium-9E1Brisc.js} +0 -0
- /package/dist/web/assets/{gruvbox-light-soft-AqsC9mKw.js → gruvbox-light-soft-Coyp7RRB.js} +0 -0
- /package/dist/web/assets/{haskell-B5V7yvmh.js → haskell-D1twJpgj.js} +0 -0
- /package/dist/web/assets/{haxe-LWTKfPKr.js → haxe-CppquubK.js} +0 -0
- /package/dist/web/assets/{hcl-QmNZdAtI.js → hcl-BWfTkyhR.js} +0 -0
- /package/dist/web/assets/{hjson-CboJsAzK.js → hjson-fgd7F6t5.js} +0 -0
- /package/dist/web/assets/{hlsl-Bd-DO_WL.js → hlsl-Ua1j-4aZ.js} +0 -0
- /package/dist/web/assets/{horizon-CU8Bi_ss.js → horizon-CTFgrxGb.js} +0 -0
- /package/dist/web/assets/{horizon-bright-iSQ3_3jP.js → horizon-bright-C4eTVZPB.js} +0 -0
- /package/dist/web/assets/{houston-CTXv3Puz.js → houston-BeYbWPdk.js} +0 -0
- /package/dist/web/assets/{hy-Cd4hTidD.js → hy-BposFX9Q.js} +0 -0
- /package/dist/web/assets/{image-gallery-J8h8IY0c.js → image-gallery-COea0nSk.js} +0 -0
- /package/dist/web/assets/{imba-BipCHEY2.js → imba-D11-b73t.js} +0 -0
- /package/dist/web/assets/{ini-Dd1KkMrB.js → ini-BCYCXf0w.js} +0 -0
- /package/dist/web/assets/{java-rGr0OQD8.js → java-BqKIPPzY.js} +0 -0
- /package/dist/web/assets/{javascript-DHhCH2TN.js → javascript-CxvTx_wu.js} +0 -0
- /package/dist/web/assets/{json-CMMLBCUf.js → json-DiknJGdj.js} +0 -0
- /package/dist/web/assets/{json5-mPOwTOsB.js → json5--8nFeehk.js} +0 -0
- /package/dist/web/assets/{jsonc-Bie0E6D3.js → jsonc-BFcq-Nx-.js} +0 -0
- /package/dist/web/assets/{jsonl-CpqHmtC1.js → jsonl-DKItgfTA.js} +0 -0
- /package/dist/web/assets/{jsonnet-D21Ms51e.js → jsonnet-sNz5wf7H.js} +0 -0
- /package/dist/web/assets/{jssm-BXnl1nur.js → jssm-BALAIF_E.js} +0 -0
- /package/dist/web/assets/{jsx-Chnii_vB.js → jsx-fXHHDCVl.js} +0 -0
- /package/dist/web/assets/{kanagawa-dragon-DhxR0UjL.js → kanagawa-dragon-nywk9qzg.js} +0 -0
- /package/dist/web/assets/{kanagawa-lotus-fupRg5wp.js → kanagawa-lotus-BmYPLC4f.js} +0 -0
- /package/dist/web/assets/{kanagawa-wave-DSWbRS9M.js → kanagawa-wave-624mOWgc.js} +0 -0
- /package/dist/web/assets/{kdl-DirGHqUy.js → kdl-DT8Argim.js} +0 -0
- /package/dist/web/assets/{kotlin-DkhUVMDC.js → kotlin-BvUjvPz2.js} +0 -0
- /package/dist/web/assets/{kusto-DU7OpovF.js → kusto-B0PONVdx.js} +0 -0
- /package/dist/web/assets/{laserwave-iLKb1ZCT.js → laserwave-ByV7LuzT.js} +0 -0
- /package/dist/web/assets/{lean-Cuvh_QAP.js → lean-DQtq2qQC.js} +0 -0
- /package/dist/web/assets/{less-B5tQZOdI.js → less-DZeD4ccP.js} +0 -0
- /package/dist/web/assets/{libesm-CdttTIAd.js → libesm-CcPYXCKp.js} +0 -0
- /package/dist/web/assets/{light-plus-DiHU2KL5.js → light-plus-BCaKDxvd.js} +0 -0
- /package/dist/web/assets/{llvm-sCBTKCKN.js → llvm-Dzok661y.js} +0 -0
- /package/dist/web/assets/{log-DtyR34Ie.js → log-C32HpwgI.js} +0 -0
- /package/dist/web/assets/{logo-CP91aQyG.js → logo-Dtjk3XHO.js} +0 -0
- /package/dist/web/assets/{luau-nfGo2ulP.js → luau-BMbN7IqN.js} +0 -0
- /package/dist/web/assets/{make-XbDn9GHe.js → make-DIVSnx7D.js} +0 -0
- /package/dist/web/assets/{markdown-BB1_3xLr.js → markdown-B1JzcsJb.js} +0 -0
- /package/dist/web/assets/{material-theme-CIx_sxAy.js → material-theme-XMfEph9O.js} +0 -0
- /package/dist/web/assets/{material-theme-darker-DsQeueDD.js → material-theme-darker-CRGzh4Ox.js} +0 -0
- /package/dist/web/assets/{material-theme-lighter-x_lMi74j.js → material-theme-lighter-D6esgP3h.js} +0 -0
- /package/dist/web/assets/{material-theme-ocean-Bkgh25P8.js → material-theme-ocean-CGbfRrFG.js} +0 -0
- /package/dist/web/assets/{material-theme-palenight-CoOjdbti.js → material-theme-palenight-DFW4xdPI.js} +0 -0
- /package/dist/web/assets/{matlab-D6xZas_8.js → matlab-Zpc8hvmI.js} +0 -0
- /package/dist/web/assets/{mdx-Cl5_YNoz.js → mdx-DLlDpnjI.js} +0 -0
- /package/dist/web/assets/{mermaid-8Eow4jz_.js → mermaid-q_sEDHYr.js} +0 -0
- /package/dist/web/assets/{min-dark-D4DhjgRE.js → min-dark-DUklXai3.js} +0 -0
- /package/dist/web/assets/{min-light-DzAckd0t.js → min-light-Ps7CV3R0.js} +0 -0
- /package/dist/web/assets/{mipsasm-zI_zu0tj.js → mipsasm-anKs0TGD.js} +0 -0
- /package/dist/web/assets/{mojo-DQnGGPHf.js → mojo-CWTvit9D.js} +0 -0
- /package/dist/web/assets/{monokai-CrFoD2VD.js → monokai-DOSMe3B9.js} +0 -0
- /package/dist/web/assets/{moonbit-DdphIGs6.js → moonbit-zOAryA05.js} +0 -0
- /package/dist/web/assets/{move-BUlkn0xW.js → move-CA6YZdSC.js} +0 -0
- /package/dist/web/assets/{narrat-CbOBdtCn.js → narrat-CyMxkfZJ.js} +0 -0
- /package/dist/web/assets/{nextflow-groovy-CeVLUTuQ.js → nextflow-groovy-D5beSS3L.js} +0 -0
- /package/dist/web/assets/{night-owl-Bm4LhUR1.js → night-owl-3ALu1K6e.js} +0 -0
- /package/dist/web/assets/{night-owl-light-DtcBiMEf.js → night-owl-light-_NLbQQrl.js} +0 -0
- /package/dist/web/assets/{nix-DrdwQ70g.js → nix-C_KqthNc.js} +0 -0
- /package/dist/web/assets/{nord-B0Head1v.js → nord-VG8J_Wfy.js} +0 -0
- /package/dist/web/assets/{nushell-CmUdltKn.js → nushell-Dx7K7YNI.js} +0 -0
- /package/dist/web/assets/{objective-c-BGDR33XN.js → objective-c-DrEbGERB.js} +0 -0
- /package/dist/web/assets/{objective-cpp-Buc1Zhd0.js → objective-cpp-DpiXqKhj.js} +0 -0
- /package/dist/web/assets/{ocaml-xdzl9rRD.js → ocaml-G6x51MAm.js} +0 -0
- /package/dist/web/assets/{odin-DiUFngnd.js → odin-tK6CU-OU.js} +0 -0
- /package/dist/web/assets/{one-dark-pro-BURxmIp3.js → one-dark-pro-581te-yF.js} +0 -0
- /package/dist/web/assets/{one-light-BMRMInAj.js → one-light-DpYva-U1.js} +0 -0
- /package/dist/web/assets/{openscad-DAgLA5J3.js → openscad-C7LYrrI4.js} +0 -0
- /package/dist/web/assets/{pascal-CoDZxcRB.js → pascal-ChqM3eJD.js} +0 -0
- /package/dist/web/assets/{pkl-DzKM6BuM.js → pkl-BlIRJsyQ.js} +0 -0
- /package/dist/web/assets/{plastic-vF15LmNS.js → plastic-DxceXlOD.js} +0 -0
- /package/dist/web/assets/{plsql-C1v07teA.js → plsql-CVikvjWK.js} +0 -0
- /package/dist/web/assets/{po-CLLC8BuA.js → po-BN9bpeJD.js} +0 -0
- /package/dist/web/assets/{poimandres-Uq0xysxM.js → poimandres-NeQA7ZSh.js} +0 -0
- /package/dist/web/assets/{polar-2-luY1Pc.js → polar-DtRx-uzO.js} +0 -0
- /package/dist/web/assets/{postcss-lbFhe0rz.js → postcss-EDnOs84S.js} +0 -0
- /package/dist/web/assets/{powerquery-RL8O9Wie.js → powerquery-mc-bbl3v.js} +0 -0
- /package/dist/web/assets/{powershell-upFWhb-b.js → powershell-ZqZF93a-.js} +0 -0
- /package/dist/web/assets/{prisma-DBtYaWFk.js → prisma-vhORN1Sx.js} +0 -0
- /package/dist/web/assets/{prolog-D8jSMykJ.js → prolog-DfIbN_m8.js} +0 -0
- /package/dist/web/assets/{proto-BM4eadF7.js → proto-BHcnh-Db.js} +0 -0
- /package/dist/web/assets/{puppet-BQDQ3Snu.js → puppet-oLpQOx2h.js} +0 -0
- /package/dist/web/assets/{purescript-Cj2aTX4s.js → purescript-HbM4Dt8M.js} +0 -0
- /package/dist/web/assets/{python-BYpqq6u4.js → python-Dlxo2z6Q.js} +0 -0
- /package/dist/web/assets/{qmldir-4uiTcwAu.js → qmldir-B5ox9idu.js} +0 -0
- /package/dist/web/assets/{qss-D5xB-Mqo.js → qss-CyegwBrl.js} +0 -0
- /package/dist/web/assets/{r-P6Ujy8rf.js → r-CxE2X3lg.js} +0 -0
- /package/dist/web/assets/{racket-COKgCFuM.js → racket-CpguQMOj.js} +0 -0
- /package/dist/web/assets/{raku-z14Q9i7K.js → raku-DDf8ASYE.js} +0 -0
- /package/dist/web/assets/{red-ObAvgvQ5.js → red-C634f6x3.js} +0 -0
- /package/dist/web/assets/{reg-Qv4f0JFA.js → reg-4gnm7BOP.js} +0 -0
- /package/dist/web/assets/{regexp-CEOVGIzy.js → regexp-Cs-hPAru.js} +0 -0
- /package/dist/web/assets/{rel-cWOyTUwd.js → rel-CrGcWbwM.js} +0 -0
- /package/dist/web/assets/{resolve-theme-CMp5xxCW.js → resolve-theme-Dm8ehbOv.js} +0 -0
- /package/dist/web/assets/{riscv-BZDwx-lv.js → riscv-B2P26ROS.js} +0 -0
- /package/dist/web/assets/{ron-BpjosPS0.js → ron-DDHGmvxW.js} +0 -0
- /package/dist/web/assets/{rose-pine-DhxfJWcm.js → rose-pine-CUYRoYal.js} +0 -0
- /package/dist/web/assets/{rose-pine-dawn-BbGt9Wy_.js → rose-pine-dawn-C9JfuUh8.js} +0 -0
- /package/dist/web/assets/{rose-pine-moon-dj4Zxgik.js → rose-pine-moon-CrYHzRJm.js} +0 -0
- /package/dist/web/assets/{rosmsg-EciOaHo2.js → rosmsg-iqzz1U38.js} +0 -0
- /package/dist/web/assets/{rust-C_eH59O_.js → rust-DVeWF3Is.js} +0 -0
- /package/dist/web/assets/{sass-Dos3R5lL.js → sass-CbVwBbUd.js} +0 -0
- /package/dist/web/assets/{scala-8lVKsTvf.js → scala-gZhcvPGv.js} +0 -0
- /package/dist/web/assets/{scheme-Bd3VdaZj.js → scheme-Z-DWgvmB.js} +0 -0
- /package/dist/web/assets/{sdbl-C4Yrjlgh.js → sdbl-wn_BtpSz.js} +0 -0
- /package/dist/web/assets/{shellscript-OFZbPKZH.js → shellscript-C09f889h.js} +0 -0
- /package/dist/web/assets/{slack-dark-aL6vlxZs.js → slack-dark-D63Fbr3l.js} +0 -0
- /package/dist/web/assets/{slack-ochin-BKt1E7sL.js → slack-ochin--Yu-v0r6.js} +0 -0
- /package/dist/web/assets/{smalltalk-D6qVBL1U.js → smalltalk-LQDcL_tW.js} +0 -0
- /package/dist/web/assets/{snazzy-light-BrWerT0t.js → snazzy-light-bo9fX83t.js} +0 -0
- /package/dist/web/assets/{solarized-dark-CzxTJgVQ.js → solarized-dark-zSs85XH6.js} +0 -0
- /package/dist/web/assets/{solarized-light-BecaDAnG.js → solarized-light-B6Q4CXBt.js} +0 -0
- /package/dist/web/assets/{solidity-C9t7pZ84.js → solidity-uUJPOjGx.js} +0 -0
- /package/dist/web/assets/{splunk-CtxfFKtF.js → splunk-C6oWgmrC.js} +0 -0
- /package/dist/web/assets/{sql-7FE_Duz0.js → sql-DyUvXbLi.js} +0 -0
- /package/dist/web/assets/{ssh-config-3Fr37ACC.js → ssh-config-62Vrd_7v.js} +0 -0
- /package/dist/web/assets/{stylus-BP4mE1sO.js → stylus-CmLQe7Fq.js} +0 -0
- /package/dist/web/assets/{swift-0uqTFouD.js → swift-DJwuT1eZ.js} +0 -0
- /package/dist/web/assets/{synthwave-84-DQaNM3DI.js → synthwave-84-CEeyTLD7.js} +0 -0
- /package/dist/web/assets/{system-verilog-DUIVrZHZ.js → system-verilog-DMqtAclw.js} +0 -0
- /package/dist/web/assets/{systemd-CtNo_WIh.js → systemd-XnScP_8M.js} +0 -0
- /package/dist/web/assets/{talonscript-B0HXaCVT.js → talonscript-CDoODzml.js} +0 -0
- /package/dist/web/assets/{tasl-Cb7RAl11.js → tasl-DycI0-Tf.js} +0 -0
- /package/dist/web/assets/{tcl-B79aC6l5.js → tcl-Dt8iP0sw.js} +0 -0
- /package/dist/web/assets/{terraform-75jJDjpW.js → terraform-DXzABgqQ.js} +0 -0
- /package/dist/web/assets/{tokyo-night-Cz9Uh9qb.js → tokyo-night-DHB1Yc-3.js} +0 -0
- /package/dist/web/assets/{toml-CD6y9A-z.js → toml-BkejsZF3.js} +0 -0
- /package/dist/web/assets/{tsv-CXJMbBrb.js → tsv-ClmhsiiR.js} +0 -0
- /package/dist/web/assets/{tsx-BuYN0I2t.js → tsx-Cp-c_JHF.js} +0 -0
- /package/dist/web/assets/{turtle-DWH-Rjse.js → turtle-BbwC417u.js} +0 -0
- /package/dist/web/assets/{typescript-BPd-hsrR.js → typescript-DbwnrRKJ.js} +0 -0
- /package/dist/web/assets/{typespec-B0wvVykx.js → typespec-DLL0LoZj.js} +0 -0
- /package/dist/web/assets/{typst-DWG2c48-.js → typst-BmEouVT1.js} +0 -0
- /package/dist/web/assets/{utils-IrnQujwR.js → utils-CwNUra6_.js} +0 -0
- /package/dist/web/assets/{v-Ch6E4Egd.js → v-C5rFgF81.js} +0 -0
- /package/dist/web/assets/{vala-CGVKwbPx.js → vala-rBXMujLw.js} +0 -0
- /package/dist/web/assets/{vb-BIEbSxyT.js → vb-mxG_YZv2.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-YQlzIWv2.js → vendor-xterm-BtjgHRUe.js} +0 -0
- /package/dist/web/assets/{verilog-A-3pYPad.js → verilog-uQ-oJRKp.js} +0 -0
- /package/dist/web/assets/{vesper-CK1naZAV.js → vesper-SO5Hw_2X.js} +0 -0
- /package/dist/web/assets/{vhdl-CVawmgMg.js → vhdl-8IeO85hx.js} +0 -0
- /package/dist/web/assets/{viml-CiWjaqBY.js → viml-De-Hm57y.js} +0 -0
- /package/dist/web/assets/{vitesse-black-PYXW4-BO.js → vitesse-black-BVm23GJE.js} +0 -0
- /package/dist/web/assets/{vitesse-dark-BU5s4AuG.js → vitesse-dark-CR0XeT-h.js} +0 -0
- /package/dist/web/assets/{vitesse-light-DgkIT-N7.js → vitesse-light-CXIFICUA.js} +0 -0
- /package/dist/web/assets/{vyper-D8cRDPp3.js → vyper-dUuvAUFJ.js} +0 -0
- /package/dist/web/assets/{wasm-ClFJgzmT.js → wasm-D5Vd7qV1.js} +0 -0
- /package/dist/web/assets/{wasm-C02wlRbP.js → wasm-DbLMmiW0.js} +0 -0
- /package/dist/web/assets/{wenyan-B8plxIr8.js → wenyan-BafBYCBu.js} +0 -0
- /package/dist/web/assets/{wgsl-CVujtm3V.js → wgsl-DY5sHamz.js} +0 -0
- /package/dist/web/assets/{wikitext-CmcG9B69.js → wikitext-QkQQVra5.js} +0 -0
- /package/dist/web/assets/{wit--gl2Jium.js → wit-BZjaDTy9.js} +0 -0
- /package/dist/web/assets/{wolfram-6T_1D-NS.js → wolfram-vrjPFD7R.js} +0 -0
- /package/dist/web/assets/{yaml-CIVV9uA1.js → yaml-D1as76NB.js} +0 -0
- /package/dist/web/assets/{zenscript-CoT4yNdA.js → zenscript-D31myxQh.js} +0 -0
- /package/dist/web/assets/{zig-BWs2Qo3G.js → zig-BbLb6ieN.js} +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LimitBucket } from "../types/chat.ts";
|
|
2
|
+
|
|
3
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
4
|
+
const WEEK_DAYS = 7;
|
|
5
|
+
|
|
6
|
+
export interface DailyGuardState {
|
|
7
|
+
day: number;
|
|
8
|
+
cap: number;
|
|
9
|
+
used: number;
|
|
10
|
+
blocked: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Split a weekly quota into seven daily envelopes. */
|
|
14
|
+
export function dailyGuardState(bucket: LimitBucket | undefined, now = Date.now()): DailyGuardState | null {
|
|
15
|
+
if (!bucket || bucket.windowHours !== 168) return null;
|
|
16
|
+
const resetsAt = new Date(bucket.resetsAt).getTime();
|
|
17
|
+
if (!Number.isFinite(resetsAt) || resetsAt <= now) return null;
|
|
18
|
+
|
|
19
|
+
const startedAt = resetsAt - WEEK_DAYS * DAY_MS;
|
|
20
|
+
const day = Math.min(WEEK_DAYS, Math.max(1, Math.ceil((now - startedAt) / DAY_MS)));
|
|
21
|
+
const cap = day / WEEK_DAYS;
|
|
22
|
+
return { day, cap, used: bucket.utilization, blocked: bucket.utilization >= cap };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function dailyGuardMessage(state: DailyGuardState): string {
|
|
26
|
+
return `Daily guard reached: ${Math.round(state.used * 100)}% used; day ${state.day}/7 allows ${Math.round(state.cap * 100)}%. Turn off Daily guard on this account to continue.`;
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Convert Codex's internal subscription enum to the plan name PPM shows people. */
|
|
2
|
+
export function codexPlanLabel(planType: string | null | undefined): string | null {
|
|
3
|
+
if (!planType?.trim()) return null;
|
|
4
|
+
const key = planType.trim().toLowerCase();
|
|
5
|
+
const known: Record<string, string> = {
|
|
6
|
+
free: "ChatGPT Free",
|
|
7
|
+
go: "ChatGPT Go",
|
|
8
|
+
plus: "ChatGPT Plus",
|
|
9
|
+
pro: "ChatGPT Pro",
|
|
10
|
+
team: "ChatGPT Team",
|
|
11
|
+
business: "ChatGPT Business",
|
|
12
|
+
self_serve_business_prolite: "ChatGPT Business",
|
|
13
|
+
enterprise: "ChatGPT Enterprise",
|
|
14
|
+
edu: "ChatGPT Edu",
|
|
15
|
+
};
|
|
16
|
+
return known[key] ?? planType;
|
|
17
|
+
}
|
|
@@ -21,9 +21,11 @@ import { AccountBucketRow } from "@/components/settings/accounts/account-bucket-
|
|
|
21
21
|
import { formatResetTime } from "@/components/settings/accounts/account-usage-format";
|
|
22
22
|
import type { AccountUsageEntry } from "@/lib/api-settings";
|
|
23
23
|
import type { UsageInfo } from "../../../types/chat";
|
|
24
|
+
import { codexPlanLabel } from "../../../shared/codex-plan-label.ts";
|
|
25
|
+
import { dailyGuardState } from "../../../shared/codex-daily-guard.ts";
|
|
24
26
|
import { UsagePanelShell } from "./usage-panel-shell";
|
|
25
27
|
|
|
26
|
-
interface CodexAccount { id: string; label: string; type: string; planType?: string | null; status?: "active" | "disabled" }
|
|
28
|
+
interface CodexAccount { id: string; label: string; type: string; planType?: string | null; status?: "active" | "disabled"; dailyGuardEnabled?: boolean }
|
|
27
29
|
type Usage = Pick<UsageInfo, "fiveHour" | "sevenDay" | "session" | "weekly">;
|
|
28
30
|
|
|
29
31
|
/** Matches the whole-percent figure the bars show, so a refusal agrees with the card. */
|
|
@@ -137,6 +139,20 @@ export function CodexUsagePanel({ onClose, usage, onReload, onSelectAccount, sel
|
|
|
137
139
|
}
|
|
138
140
|
}, []);
|
|
139
141
|
|
|
142
|
+
const handleDailyGuardToggle = useCallback(async (id: string, enabled: boolean) => {
|
|
143
|
+
setTogglingId(id);
|
|
144
|
+
setPanelError(null);
|
|
145
|
+
try {
|
|
146
|
+
await api.patch(`/api/codex-accounts/${id}`, { dailyGuardEnabled: !enabled });
|
|
147
|
+
const d = await api.get<{ accounts: CodexAccount[] }>("/api/codex-accounts");
|
|
148
|
+
setAccounts(d.accounts);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
setPanelError((e as Error).message || "Could not change Daily guard");
|
|
151
|
+
} finally {
|
|
152
|
+
setTogglingId(null);
|
|
153
|
+
}
|
|
154
|
+
}, []);
|
|
155
|
+
|
|
140
156
|
/* No managed accounts → chats run on the ambient ~/.codex login, whose usage arrives on
|
|
141
157
|
the session prop rather than from the accounts endpoint. */
|
|
142
158
|
const ambient = loading && accounts.length === 0 ? (
|
|
@@ -171,6 +187,7 @@ export function CodexUsagePanel({ onClose, usage, onReload, onSelectAccount, sel
|
|
|
171
187
|
>
|
|
172
188
|
{(layout) => accounts.map((a) => {
|
|
173
189
|
const u = usages[a.id] ?? {};
|
|
190
|
+
const guard = u.session == null ? dailyGuardState(u.weekly) : null;
|
|
174
191
|
return (
|
|
175
192
|
<AccountCard
|
|
176
193
|
key={a.id}
|
|
@@ -179,12 +196,15 @@ export function CodexUsagePanel({ onClose, usage, onReload, onSelectAccount, sel
|
|
|
179
196
|
// those differ the moment a session is bound to an account.
|
|
180
197
|
isActive={a.id === (selectedAccountId ?? usage.activeAccountId)}
|
|
181
198
|
layout={layout}
|
|
182
|
-
planLabel={a.planType}
|
|
199
|
+
planLabel={codexPlanLabel(a.planType)}
|
|
183
200
|
onSelect={onSelectAccount ? handleSelect : undefined}
|
|
184
201
|
unselectableReason={unselectableReason(a, u)}
|
|
185
202
|
selecting={selectingId === a.id}
|
|
186
203
|
onToggle={handleToggle}
|
|
187
204
|
toggling={togglingId === a.id}
|
|
205
|
+
dailyGuard={guard ? { enabled: !!a.dailyGuardEnabled, state: guard } : undefined}
|
|
206
|
+
onDailyGuardToggle={guard ? () => void handleDailyGuardToggle(a.id, !!a.dailyGuardEnabled) : undefined}
|
|
207
|
+
dailyGuardToggling={togglingId === a.id}
|
|
188
208
|
/>
|
|
189
209
|
);
|
|
190
210
|
})}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* while every turn on them failed. The sign-in deadline replaced it.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import { Download, Eye, KeyRound, RefreshCw, Trash2 } from "lucide-react";
|
|
21
|
+
import { CircleHelp, Download, Eye, KeyRound, RefreshCw, Trash2 } from "lucide-react";
|
|
22
22
|
import { Switch } from "@/components/ui/switch";
|
|
23
23
|
import type { AccountInfo, AccountUsageEntry, OAuthProfileData } from "../../../lib/api-settings";
|
|
24
24
|
import { AccountBucketRow } from "./account-bucket-row";
|
|
@@ -26,6 +26,7 @@ import { AccountHint } from "./account-hint";
|
|
|
26
26
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
|
27
27
|
import { AccountCardShell } from "./accounts-pane-header";
|
|
28
28
|
import { formatExpiry, formatLastUpdated, tokenStatus } from "./account-usage-format";
|
|
29
|
+
import type { DailyGuardState } from "../../../../shared/codex-daily-guard.ts";
|
|
29
30
|
|
|
30
31
|
export interface AccountCardProps {
|
|
31
32
|
entry: AccountUsageEntry;
|
|
@@ -55,6 +56,10 @@ export interface AccountCardProps {
|
|
|
55
56
|
* a plan ("plus", "team") and that decides which quota windows the account even has, so
|
|
56
57
|
* it belongs on the card; Claude reports none and the badge simply does not appear. */
|
|
57
58
|
planLabel?: string | null;
|
|
59
|
+
/** Optional pacing control for Codex accounts that expose only a weekly quota. */
|
|
60
|
+
dailyGuard?: { enabled: boolean; state: DailyGuardState };
|
|
61
|
+
onDailyGuardToggle?: () => void;
|
|
62
|
+
dailyGuardToggling?: boolean;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
// Fixed widths so a row scrolls instead of squeezing. Two of them: a read-only card holds a
|
|
@@ -64,7 +69,7 @@ const STRIP_WIDTH = { readOnly: "min-w-[220px]", withActions: "min-w-[300px]" }
|
|
|
64
69
|
|
|
65
70
|
export function AccountCard({
|
|
66
71
|
entry, isActive, accountInfo, onToggle, toggling, onDelete, onExport, onViewProfile, flash,
|
|
67
|
-
onSelect, unselectableReason, selecting, planLabel,
|
|
72
|
+
onSelect, unselectableReason, selecting, planLabel, dailyGuard, onDailyGuardToggle, dailyGuardToggling,
|
|
68
73
|
layout = "list",
|
|
69
74
|
}: AccountCardProps) {
|
|
70
75
|
const { usage } = entry;
|
|
@@ -259,6 +264,42 @@ export function AccountCard({
|
|
|
259
264
|
</p>
|
|
260
265
|
)}
|
|
261
266
|
|
|
267
|
+
{dailyGuard && (
|
|
268
|
+
<div className={`flex min-h-12 items-center justify-between gap-3 rounded-md border px-2.5 py-1.5 ${
|
|
269
|
+
dailyGuard.enabled && dailyGuard.state.blocked ? "border-error/40 bg-error/5" : "border-border/50 bg-surface/40"
|
|
270
|
+
}`}>
|
|
271
|
+
<div className="min-w-0 space-y-0.5">
|
|
272
|
+
<div className={`flex items-center gap-1.5 text-xs font-medium ${dailyGuard.enabled && dailyGuard.state.blocked ? "text-error" : "text-text-secondary"}`}>
|
|
273
|
+
<span>Daily guard</span>
|
|
274
|
+
<Tooltip>
|
|
275
|
+
<TooltipTrigger asChild>
|
|
276
|
+
<button type="button" aria-label="About Daily guard" className="text-text-subtle hover:text-text-primary cursor-help">
|
|
277
|
+
<CircleHelp className="size-3.5" />
|
|
278
|
+
</button>
|
|
279
|
+
</TooltipTrigger>
|
|
280
|
+
<TooltipContent side="top" className="max-w-64 text-xs leading-relaxed">
|
|
281
|
+
Keeps a weekly-only Codex account on pace to last until its reset. Each day adds one seventh of the weekly quota. When usage reaches that day's cap, PPM pauses new turns until the next day.
|
|
282
|
+
</TooltipContent>
|
|
283
|
+
</Tooltip>
|
|
284
|
+
</div>
|
|
285
|
+
<p className={`text-[10px] tabular-nums ${dailyGuard.enabled && dailyGuard.state.blocked ? "text-error" : "text-text-subtle"}`}>
|
|
286
|
+
{dailyGuard.enabled && dailyGuard.state.blocked
|
|
287
|
+
? `${Math.round(dailyGuard.state.used * 100)}% used / ${Math.round(dailyGuard.state.cap * 100)}% daily cap. New turns paused.`
|
|
288
|
+
: `Day ${dailyGuard.state.day}/7, ${Math.round(dailyGuard.state.cap * 100)}% daily cap`}
|
|
289
|
+
</p>
|
|
290
|
+
</div>
|
|
291
|
+
{onDailyGuardToggle && (
|
|
292
|
+
<Switch
|
|
293
|
+
checked={dailyGuard.enabled}
|
|
294
|
+
onCheckedChange={onDailyGuardToggle}
|
|
295
|
+
disabled={dailyGuardToggling}
|
|
296
|
+
aria-label={dailyGuard.enabled ? "Disable Daily guard" : "Enable Daily guard"}
|
|
297
|
+
className="cursor-pointer shrink-0"
|
|
298
|
+
/>
|
|
299
|
+
)}
|
|
300
|
+
</div>
|
|
301
|
+
)}
|
|
302
|
+
|
|
262
303
|
<div className="flex items-center gap-2 text-[10px] text-text-subtle flex-wrap">
|
|
263
304
|
{usage.lastFetchedAt && (
|
|
264
305
|
<AccountHint
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { useState } from "react";
|
|
10
|
-
import { Download, KeyRound, Loader2, Plus, Settings, Trash2, Upload } from "lucide-react";
|
|
10
|
+
import { CircleHelp, Download, KeyRound, Loader2, Plus, Settings, Trash2, Upload } from "lucide-react";
|
|
11
11
|
import { Button } from "@/components/ui/button";
|
|
12
12
|
import { Switch } from "@/components/ui/switch";
|
|
13
13
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
|
@@ -17,6 +17,8 @@ import { CodexBackupDialog } from "./codex-backup-dialog";
|
|
|
17
17
|
import { CodexRotationDialog } from "./codex-rotation-dialog";
|
|
18
18
|
import { CodexUsageRows } from "./codex-usage-rows";
|
|
19
19
|
import { useCodexAccounts } from "./use-codex-accounts";
|
|
20
|
+
import { codexPlanLabel } from "../../../../shared/codex-plan-label.ts";
|
|
21
|
+
import { dailyGuardState } from "../../../../shared/codex-daily-guard.ts";
|
|
20
22
|
|
|
21
23
|
/** Codex multi-account management, separate from Claude accounts because codex auth is owned
|
|
22
24
|
* by the app-server per CODEX_HOME. Added by API key, browser login, or ChatGPT device code. */
|
|
@@ -86,7 +88,7 @@ export function CodexAccountsSection() {
|
|
|
86
88
|
<span className="text-[10px] uppercase tracking-wide text-text-subtle border border-border rounded px-1 shrink-0">
|
|
87
89
|
{a.type}
|
|
88
90
|
</span>
|
|
89
|
-
{a.planType && <span className="text-[10px] text-text-subtle shrink-0">{a.planType}</span>}
|
|
91
|
+
{codexPlanLabel(a.planType) && <span className="text-[10px] text-text-subtle shrink-0">{codexPlanLabel(a.planType)}</span>}
|
|
90
92
|
{/* Same control the Claude card uses, in the same place, so the two
|
|
91
93
|
sub-tabs read as one screen rather than two designs. */}
|
|
92
94
|
<Switch
|
|
@@ -111,6 +113,45 @@ export function CodexAccountsSection() {
|
|
|
111
113
|
</Tooltip>
|
|
112
114
|
</div>
|
|
113
115
|
<CodexUsageRows usage={u} />
|
|
116
|
+
{u.session == null && (() => {
|
|
117
|
+
const guard = dailyGuardState(u.weekly);
|
|
118
|
+
return guard ? (
|
|
119
|
+
<div className={`flex min-h-12 items-center justify-between gap-3 rounded-md border px-2.5 py-1.5 ${
|
|
120
|
+
a.dailyGuardEnabled && guard.blocked ? "border-error/40 bg-error/5" : "border-border/50 bg-surface/40"
|
|
121
|
+
}`}>
|
|
122
|
+
<div className="min-w-0 space-y-0.5">
|
|
123
|
+
<div className={`flex items-center gap-1.5 text-xs font-medium ${a.dailyGuardEnabled && guard.blocked ? "text-error" : "text-text-secondary"}`}>
|
|
124
|
+
<span>Daily guard</span>
|
|
125
|
+
<Tooltip>
|
|
126
|
+
<TooltipTrigger asChild>
|
|
127
|
+
<button type="button" aria-label="About Daily guard" className="text-text-subtle hover:text-text-primary cursor-help">
|
|
128
|
+
<CircleHelp className="size-3.5" />
|
|
129
|
+
</button>
|
|
130
|
+
</TooltipTrigger>
|
|
131
|
+
<TooltipContent side="top" className="max-w-64 text-xs leading-relaxed">
|
|
132
|
+
Keeps a weekly-only Codex account on pace to last until its reset. Each day adds one seventh of the weekly quota. When usage reaches that day's cap, PPM pauses new turns until the next day. Turn it off any time to use the remaining quota freely.
|
|
133
|
+
</TooltipContent>
|
|
134
|
+
</Tooltip>
|
|
135
|
+
</div>
|
|
136
|
+
<p className={`text-[10px] tabular-nums ${a.dailyGuardEnabled && guard.blocked ? "text-error" : "text-text-subtle"}`}>
|
|
137
|
+
{a.dailyGuardEnabled && guard.blocked
|
|
138
|
+
? `${Math.round(guard.used * 100)}% used / ${Math.round(guard.cap * 100)}% daily cap. New turns paused.`
|
|
139
|
+
: `Day ${guard.day}/7, ${Math.round(guard.cap * 100)}% daily cap`}
|
|
140
|
+
</p>
|
|
141
|
+
</div>
|
|
142
|
+
<span className="hidden" title={`Day ${guard.day}/7: hold weekly usage at or below ${Math.round(guard.cap * 100)}% to last until reset.`}>
|
|
143
|
+
Daily guard {a.dailyGuardEnabled ? `· Day ${guard.day}/7 cap ${Math.round(guard.cap * 100)}%` : ""}
|
|
144
|
+
</span>
|
|
145
|
+
<Switch
|
|
146
|
+
checked={!!a.dailyGuardEnabled}
|
|
147
|
+
onCheckedChange={() => void c.toggleDailyGuard(a.id, !!a.dailyGuardEnabled)}
|
|
148
|
+
disabled={c.toggling.has(a.id)}
|
|
149
|
+
aria-label={a.dailyGuardEnabled ? "Disable Daily guard" : "Enable Daily guard"}
|
|
150
|
+
className="cursor-pointer shrink-0"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
) : null;
|
|
154
|
+
})()}
|
|
114
155
|
</AccountCardShell>
|
|
115
156
|
);
|
|
116
157
|
})}
|
|
@@ -6,7 +6,7 @@ import type { LimitBucket } from "../../../../types/chat";
|
|
|
6
6
|
import type { CodexStrategy } from "./codex-rotation-dialog";
|
|
7
7
|
|
|
8
8
|
export type Strategy = CodexStrategy;
|
|
9
|
-
export interface CodexAccount { id: string; label: string; type: string; planType?: string | null; status?: "active" | "disabled" }
|
|
9
|
+
export interface CodexAccount { id: string; label: string; type: string; planType?: string | null; status?: "active" | "disabled"; dailyGuardEnabled?: boolean }
|
|
10
10
|
/**
|
|
11
11
|
* One account's quota. The two percentages are what the bars read; the buckets carry the
|
|
12
12
|
* reset clock the server already sends, so the Codex card can show "resets in" the way the
|
|
@@ -183,6 +183,18 @@ export function useCodexAccounts(onDone: () => void) {
|
|
|
183
183
|
setToggling((prev) => { const n = new Set(prev); n.delete(id); return n; });
|
|
184
184
|
}
|
|
185
185
|
};
|
|
186
|
+
const toggleDailyGuard = async (id: string, enabled: boolean) => {
|
|
187
|
+
setToggling((prev) => new Set(prev).add(id));
|
|
188
|
+
setErr(null);
|
|
189
|
+
try {
|
|
190
|
+
await api.patch(`/api/codex-accounts/${id}`, { dailyGuardEnabled: !enabled });
|
|
191
|
+
await load();
|
|
192
|
+
} catch (e) {
|
|
193
|
+
setErr((e as Error).message || "Could not change Daily guard");
|
|
194
|
+
} finally {
|
|
195
|
+
setToggling((prev) => { const n = new Set(prev); n.delete(id); return n; });
|
|
196
|
+
}
|
|
197
|
+
};
|
|
186
198
|
const changeStrategy = async (s: Strategy) => { setStrategy(s); try { await api.put("/api/codex-accounts/strategy", { strategy: s }); } catch { /* revert on reload */ } };
|
|
187
199
|
|
|
188
200
|
const doExport = async () => {
|
|
@@ -225,6 +237,6 @@ export function useCodexAccounts(onDone: () => void) {
|
|
|
225
237
|
exporting, importing, msg, setMsg,
|
|
226
238
|
toggling,
|
|
227
239
|
load, addApiKey, startDevice: () => startLogin("device"), startBrowser: () => startLogin("browser"),
|
|
228
|
-
browser, loginStarting, callbackUrl, setCallbackUrl, submittingCallback, submitCallback, cancelLogin, remove, toggle, changeStrategy, doExport, doImport,
|
|
240
|
+
browser, loginStarting, callbackUrl, setCallbackUrl, submittingCallback, submitCallback, cancelLogin, remove, toggle, toggleDailyGuard, changeStrategy, doExport, doImport,
|
|
229
241
|
};
|
|
230
242
|
}
|
|
@@ -183,9 +183,15 @@ export function NamedTunnelSetupContent({ step, t }: Props) {
|
|
|
183
183
|
<p className="mt-1 text-sm text-text-secondary leading-relaxed">{step.message}</p>
|
|
184
184
|
</div>
|
|
185
185
|
</div>
|
|
186
|
-
|
|
186
|
+
{/* Retry reuses the existing cert, so it can only ever fix a transient
|
|
187
|
+
failure. When the credential itself is the problem — a cert whose
|
|
188
|
+
zone no longer resolves still verifies as a live token, so the
|
|
189
|
+
shortcut keeps reporting "already logged in" — retrying loops on
|
|
190
|
+
the same error forever, and a fresh sign-in is the only way out. */}
|
|
191
|
+
<div className="flex flex-wrap gap-2">
|
|
187
192
|
<button type="button" onClick={t.close} className={secondaryBtn}>{c.close}</button>
|
|
188
|
-
<button type="button" onClick={t.retryLogin} className={
|
|
193
|
+
<button type="button" onClick={t.retryLogin} className={secondaryBtn}>{c.retry}</button>
|
|
194
|
+
<button type="button" onClick={t.requestRelogin} className={primaryBtn}>{c.relogin}</button>
|
|
189
195
|
</div>
|
|
190
196
|
</div>
|
|
191
197
|
);
|
|
@@ -116,8 +116,20 @@ function stepFromLoginState(state: LoginState, url: string | null, message: stri
|
|
|
116
116
|
|
|
117
117
|
export function reduceStep(step: Step, action: Action): Step {
|
|
118
118
|
switch (action.type) {
|
|
119
|
-
case "status":
|
|
120
|
-
|
|
119
|
+
case "status": {
|
|
120
|
+
if (!STATUS_RESETTABLE.has(step.k)) return step;
|
|
121
|
+
// `dismissed` only means "do not open the first-run popup on its own".
|
|
122
|
+
// Once a card is on screen it must not close it again: the Tunnel
|
|
123
|
+
// Manager's "Set up" button puts the same login-wait step there on an
|
|
124
|
+
// install that dismissed the popup long ago, and the `/status` refetch
|
|
125
|
+
// that follows a cert-shortcut login ("already logged in", no browser
|
|
126
|
+
// round-trip) would otherwise collapse the flow straight back to the
|
|
127
|
+
// button one spinner later — no zone step, no error, nothing to show for
|
|
128
|
+
// the click. Everything else a refresh can say (auth turned off, mode
|
|
129
|
+
// already named elsewhere) still hides the card as before.
|
|
130
|
+
const snapshot = step.k === "hidden" ? action.status : { ...action.status, dismissed: false };
|
|
131
|
+
return initialStepFromStatus(snapshot);
|
|
132
|
+
}
|
|
121
133
|
|
|
122
134
|
case "answer-yes":
|
|
123
135
|
return { k: "login-wait", url: null, slow: false };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{C as t,S as n}from"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-BBdkypKW.js";import{t as r}from"./copy-CXuIH4VC.js";import{t as i}from"./download-D70Q4Ba6.js";import{t as a}from"./flask-conical-Dix4qNDj.js";import{t as o}from"./key-round-oIll4vo-.js";import{t as s}from"./loader-circle-DxI3O9_f.js";import{t as c}from"./x-Bdaog6Az.js";import{n as l,r as u}from"./api-client-DwXlVfXP.js";import{n as d}from"./utils-IrnQujwR.js";import"./portal-container-context-DeLx1cOI.js";import{n as f}from"./use-is-mobile-Bi42QhIi.js";import{n as p,t as m}from"./button-zgoXa9r7.js";import{t as h}from"./mobile-bottom-sheet-Ch1e_JBq.js";import"./use-visual-viewport-CNdG4QHH.js";import{$t as g,B as _,Dn as v,Dr as y,G as b,Gn as x,H as S,Ln as C,M as w,On as T,Pn as E,Qn as D,Qt as O,U as k,V as A,W as j,X as M,Xt as N,Y as P,Yt as F,Zt as I,en as L,ir as R,kn as ee,lr as z,nn as B}from"./index-DVNJ2W5R.js";import{addAccount as V,deleteAccount as H,exchangeOAuthCode as U,getAISettings as W,getAccountSettings as G,getOAuthUrl as K,getUsageHistory as q,importAccounts as te,patchAccount as J,testAccountToken as Y,testExport as ne,testRawToken as X,updateAccountSettings as re}from"./api-settings-BQIwZoLm.js";import{a as ie,c as ae,i as oe,l as se,n as ce,o as le,r as ue,t as de,u as fe}from"./use-accounts-data-B9t4BQaI.js";var Z=e(t(),1),Q=n(),pe=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],$=Array.from({length:24},(e,t)=>t);function me(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 he(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 ge(e){return $.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 _e(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 ve(e){return e<.3?`bg-success`:e<.7?`bg-warning`:`bg-error`}function ye({accountId:e}){let[t,n]=(0,Z.useState)(null),[r,i]=(0,Z.useState)(!0),[a,o]=(0,Z.useState)(`5h`);(0,Z.useEffect)(()=>{i(!0),q(e).then(n).catch(()=>n([])).finally(()=>i(!1))},[e]);let c=(0,Z.useMemo)(()=>t?me(t,a):null,[t,a]),l=(0,Z.useMemo)(()=>c?he(c):[],[c]),u=(0,Z.useMemo)(()=>c?ge(c):[],[c]),d=Math.max(...l,.01);if(Math.max(...u,.01),r)return(0,Q.jsx)(`div`,{className:`flex items-center justify-center py-3`,children:(0,Q.jsx)(s,{className:`size-3 animate-spin text-text-subtle`})});if(!t||t.length===0)return(0,Q.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,Q.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Q.jsx)(`span`,{className:`text-[10px] font-medium text-text-subtle`,children:`Usage Pattern (7d)`}),(0,Q.jsxs)(`div`,{className:`flex gap-0.5 text-[9px]`,children:[(0,Q.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,Q.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,Q.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,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by day of week`}),(0,Q.jsx)(`div`,{className:`flex flex-col gap-[2px] mt-0.5`,children:pe.map((e,t)=>{let n=l[t]??0;return(0,Q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,Q.jsx)(`span`,{className:`text-[8px] text-text-subtle w-5 shrink-0 text-right tabular-nums`,children:e}),(0,Q.jsx)(`div`,{className:`flex-1 h-2.5 bg-surface-elevated rounded-sm overflow-hidden`,children:(0,Q.jsx)(`div`,{className:`h-full rounded-sm transition-all ${ve(n)}`,style:{width:`${Math.round(n/d*100)}%`}})}),(0,Q.jsxs)(`span`,{className:`text-[8px] text-text-subtle w-6 shrink-0 text-right tabular-nums`,children:[Math.round(n*100),`%`]})]},e)})})]}),(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by hour (0h-23h)`}),(0,Q.jsx)(`div`,{className:`flex gap-[1px] mt-0.5`,children:$.map(e=>{let t=u[e]??0;return(0,Q.jsxs)(`div`,{className:`flex-1 flex flex-col items-center gap-[1px]`,children:[(0,Q.jsx)(`div`,{className:`w-full aspect-square rounded-[2px] ${_e(t)}`,title:`${e}:00 — avg ${Math.round(t*100)}% usage`}),e%6==0&&(0,Q.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})]},e)})})]}),c&&(0,Q.jsxs)(`div`,{children:[(0,Q.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Day x Hour heatmap`}),(0,Q.jsxs)(`div`,{className:`flex flex-col gap-[1px] mt-0.5`,children:[pe.map((e,t)=>(0,Q.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,Q.jsx)(`span`,{className:`text-[7px] text-text-subtle w-4 shrink-0 text-right`,children:e.charAt(0)}),$.map(n=>{let r=c[t][n];return(0,Q.jsx)(`div`,{className:`flex-1 aspect-square rounded-[1px] ${_e(r.avg)}`,title:`${e} ${n}:00 — ${r.count>0?`avg ${Math.round(r.avg*100)}% (${r.count} samples)`:`no data`}`},n)})]},e)),(0,Q.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,Q.jsx)(`span`,{className:`w-4 shrink-0`}),$.map(e=>(0,Q.jsx)(`div`,{className:`flex-1 text-center`,children:e%6==0&&(0,Q.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})},e))]})]})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[8px] text-text-subtle`,children:[(0,Q.jsx)(`span`,{children:`Low`}),(0,Q.jsxs)(`div`,{className:`flex gap-[2px]`,children:[(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/30`}),(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/60`}),(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/50`}),(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/80`}),(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-error/80`})]}),(0,Q.jsx)(`span`,{children:`High`}),(0,Q.jsx)(`span`,{className:`ml-1`,children:`|`}),(0,Q.jsx)(`div`,{className:`size-2 rounded-[1px] bg-surface-elevated border border-border/30`}),(0,Q.jsx)(`span`,{children:`No data`})]})]})}function be({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,Q.jsxs)(`section`,{className:`space-y-2 border-t border-border pt-3`,"data-testid":`account-profile-panel`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Q.jsx)(`h3`,{className:`text-sm font-medium`,children:`Profile`}),(0,Q.jsx)(`button`,{className:`p-2 text-muted-foreground hover:text-foreground cursor-pointer`,onClick:n,"aria-label":`Close profile`,children:(0,Q.jsx)(c,{className:`size-4`})})]}),(0,Q.jsx)(`div`,{className:`grid grid-cols-[80px_1fr] gap-x-3 gap-y-1 text-xs`,children:r.map(([e,t])=>t?(0,Q.jsxs)(`span`,{className:`contents`,children:[(0,Q.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,Q.jsx)(`span`,{className:`break-all`,children:t})]},e):null)}),(0,Q.jsx)(ye,{accountId:t})]})}function xe({display:e,onConfirm:t,onCancel:n}){let r=f(),i=(0,Q.jsxs)(`div`,{className:`space-y-4`,"data-testid":`account-delete-confirm`,children:[(0,Q.jsxs)(`p`,{className:`text-sm`,children:[`Remove `,(0,Q.jsx)(`span`,{className:`font-medium`,children:e}),`?`]}),(0,Q.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,Q.jsxs)(`div`,{className:`flex flex-col-reverse md:flex-row gap-2 md:justify-end pt-2`,children:[(0,Q.jsx)(m,{variant:`outline`,onClick:n,className:`min-h-11`,children:`Cancel`}),(0,Q.jsx)(m,{variant:`destructive`,autoFocus:!1,onClick:t,className:`min-h-11`,children:`Remove account`})]})]});return r?(0,Q.jsx)(h,{open:!0,onClose:n,children:(0,Q.jsxs)(`div`,{className:`px-4 pb-4`,children:[(0,Q.jsx)(`h2`,{className:`text-base font-semibold mb-3`,children:`Remove account`}),i]})}):(0,Q.jsx)(F,{open:!0,onOpenChange:e=>{e||n()},children:(0,Q.jsxs)(N,{className:`sm:max-w-sm`,children:[(0,Q.jsx)(g,{children:(0,Q.jsx)(L,{className:`text-sm`,children:`Remove account`})}),i]})})}function Se({open:e,onOpenChange:t,onSuccess:n}){let[r,i]=(0,Z.useState)(``),[a,o]=(0,Z.useState)(``),[c,l]=(0,Z.useState)(!1),[u,d]=(0,Z.useState)(null),[f,p]=(0,Z.useState)(null),[h,_]=(0,Z.useState)(``),[v,y]=(0,Z.useState)(!1),[b,x]=(0,Z.useState)(`idle`);function S(){p(null),_(``),x(`idle`),d(null)}function C(){t(!1),S(),i(``),o(``),d(null)}async function w(){y(!0),d(null);try{let{url:e,state:t}=await K();p(t),x(`waiting`),window.open(e,`_blank`)}catch(e){d(e.message)}y(!1)}async function T(){if(!(!h.trim()||!f)){y(!0),d(null);try{let e=h.trim();e.includes(`#`)&&(e=e.split(`#`)[0]??e);let t=await U(e,f);C(),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 E(){if(r.trim()){l(!0),d(null);try{let e=await V({apiKey:r.trim(),label:a.trim()||void 0});C(),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 D=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,Q.jsx)(F,{open:e,onOpenChange:e=>{e||C()},children:(0,Q.jsxs)(N,{className:`sm:max-w-md`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsx)(L,{className:`text-sm`,children:`Add Claude Account`}),(0,Q.jsx)(I,{className:`text-xs leading-relaxed`,children:`Connect via OAuth (recommended) or paste a token manually.`})]}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(`div`,{className:`rounded-md border p-3 space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] font-medium`,children:`Recommended: Login with Claude`}),b===`idle`?(0,Q.jsx)(m,{size:`sm`,className:`w-full h-8 text-xs`,onClick:w,disabled:v,children:v?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Opening...`]}):`Login with Claude`}):(0,Q.jsxs)(`div`,{className:`space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Authorize in the opened tab, then paste the code:`}),(0,Q.jsx)(M,{placeholder:`Paste code here...`,value:h,onChange:e=>_(e.target.value),className:`text-xs h-8 font-mono`,autoFocus:!0}),(0,Q.jsxs)(`div`,{className:`flex gap-1.5`,children:[(0,Q.jsx)(m,{size:`sm`,className:`flex-1 h-7 text-xs`,onClick:T,disabled:!h.trim()||v,children:v?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Connecting...`]}):`Connect`}),(0,Q.jsx)(m,{size:`sm`,variant:`ghost`,className:`h-7 text-xs`,onClick:S,children:`Cancel`})]})]})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`div`,{className:`flex-1 border-t`}),(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`or paste token`}),(0,Q.jsx)(`div`,{className:`flex-1 border-t`})]}),(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{htmlFor:`add-token`,className:`text-xs`,children:`Token`}),(0,Q.jsx)(M,{id:`add-token`,type:`password`,placeholder:`sk-ant-...`,value:r,onChange:e=>i(e.target.value),className:`text-xs h-8 font-mono`}),D&&(0,Q.jsxs)(`p`,{className:`text-[10px] text-muted-foreground`,children:[`Detected: `,D]})]}),(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{htmlFor:`add-label`,className:`text-xs`,children:`Label (optional)`}),(0,Q.jsx)(M,{id:`add-label`,placeholder:`e.g. Personal, Work`,value:a,onChange:e=>o(e.target.value),className:`text-xs h-8`})]})]}),u&&(0,Q.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:u}),(0,Q.jsxs)(O,{children:[(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7`,onClick:C,children:`Cancel`}),(0,Q.jsx)(m,{size:`sm`,className:`text-xs h-7`,onClick:E,disabled:!r.trim()||c,children:c?`Adding...`:`Add Token`})]})]})})}function Ce(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 we({open:e,onOpenChange:t,accounts:n,preselectId:a,onMessage:o}){let c=n.filter(e=>e.hasRefreshToken),[l,d]=(0,Z.useState)(new Set),[f,p]=(0,Z.useState)(``),[h,_]=(0,Z.useState)(!1),[v,y]=(0,Z.useState)(!1),[b,x]=(0,Z.useState)(!1),[S,C]=(0,Z.useState)(!1);e&&!S&&(d(a?new Set([a]):new Set(c.map(e=>e.id))),C(!0)),!e&&S&&C(!1);function w(){t(!1),p(``),_(!1),y(!1)}async function T(e){if(l.size===0)return;x(!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 B(a)?o?.(`Backup copied to clipboard!`):(Ce(a),o?.(`Backup downloaded.`)),w()}catch{}x(!1)}let E=l.size>0&&!b;return(0,Q.jsx)(F,{open:e,onOpenChange:e=>{e||w()},children:(0,Q.jsxs)(N,{className:`sm:max-w-md`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsxs)(L,{className:`text-sm flex items-center gap-1.5`,children:[(0,Q.jsx)(z,{className:`size-3.5`}),` Export Accounts`]}),(0,Q.jsx)(I,{className:`text-xs`,children:`Select accounts and set a password to protect the backup.`})]}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Accounts to export`}),(0,Q.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,Q.jsx)(`p`,{className:`text-[10px] text-muted-foreground p-2 border rounded`,children:`No exportable accounts.`}):(0,Q.jsx)(`div`,{className:`max-h-36 overflow-y-auto space-y-1 border rounded p-2`,children:c.map(e=>(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.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,Q.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,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsxs)(P,{className:`text-xs`,children:[`Password `,(0,Q.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,Q.jsx)(M,{type:`password`,placeholder:`Leave empty for default`,value:f,onChange:e=>p(e.target.value),className:`text-xs h-8`,autoComplete:`new-password`})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,id:`exp-full`,checked:h,onChange:e=>_(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,Q.jsx)(`label`,{htmlFor:`exp-full`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens (full transfer)`})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`input`,{type:`checkbox`,id:`exp-refresh`,checked:v,onChange:e=>y(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,Q.jsx)(`label`,{htmlFor:`exp-refresh`,className:`text-[11px] cursor-pointer`,children:`Refresh tokens before export`})]}),h?(0,Q.jsxs)(`div`,{className:`rounded-md border border-error/30 bg-error/5 p-2.5`,children:[(0,Q.jsx)(`p`,{className:`text-[10px] font-medium text-error`,children:`Full transfer — source accounts will expire`}),(0,Q.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Refresh tokens included. Source machine expires in ~1h after target refreshes.`})]}):v?(0,Q.jsx)(`div`,{className:`rounded-md border border-warning/30 bg-warning/5 p-2.5`,children:(0,Q.jsx)(`p`,{className:`text-[10px] font-medium text-warning`,children:`Refresh before export — invalidates previous shares`})}):(0,Q.jsx)(`div`,{className:`rounded-md border border-success/30 bg-success/5 p-2.5`,children:(0,Q.jsx)(`p`,{className:`text-[10px] font-medium text-success`,children:`Share current token (safe)`})}),(0,Q.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Encrypted with AES-256-GCM + scrypt.`})]}),(0,Q.jsxs)(O,{className:`gap-1.5 flex-col sm:flex-row`,children:[(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:w,children:`Cancel`}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,disabled:!E,onClick:()=>T(!0),children:[(0,Q.jsx)(r,{className:`size-3 mr-1`}),` Copy`]}),(0,Q.jsx)(m,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!E,onClick:()=>T(!1),children:b?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(i,{className:`size-3 mr-1`}),` Download`]})})]})]})})}function Te({open:e,onOpenChange:t,onSuccess:n}){let[r,i]=(0,Z.useState)(``),[a,o]=(0,Z.useState)(``),[c,l]=(0,Z.useState)(!1),[u,d]=(0,Z.useState)(null);function f(){t(!1),i(``),o(``),d(null)}async function p(){if(r.trim()){l(!0),d(null);try{let e=await te({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,Q.jsx)(F,{open:e,onOpenChange:e=>{e||f()},children:(0,Q.jsxs)(N,{className:`sm:max-w-md`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsxs)(L,{className:`text-sm flex items-center gap-1.5`,children:[(0,Q.jsx)(z,{className:`size-3.5`}),` Import Accounts`]}),(0,Q.jsx)(I,{className:`text-xs`,children:`Paste backup data and enter the export password. Imported accounts are temporary (~1h).`})]}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{className:`text-xs`,children:`Backup data`}),(0,Q.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,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsxs)(P,{className:`text-xs`,children:[`Password `,(0,Q.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,Q.jsx)(M,{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,Q.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:u}),(0,Q.jsxs)(O,{children:[(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:f,children:`Cancel`}),(0,Q.jsx)(m,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!r.trim()||c,onClick:p,children:c?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Importing...`]}):`Import`})]})]})})}var Ee=typeof window<`u`?window.matchMedia(`(min-width: 768px)`):null;function De(e){return Ee?.addEventListener(`change`,e),()=>Ee?.removeEventListener(`change`,e)}function Oe(){return Ee?.matches??!0}function ke(){let[e,t]=(0,Z.useState)(null),[n,r]=(0,Z.useState)(!0);return(0,Z.useEffect)(()=>{r(!0),G().then(t).finally(()=>r(!1))},[]),n?(0,Q.jsx)(`p`,{className:`text-xs text-text-subtle py-4 text-center`,children:`Loading...`}):e?(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Rotation Strategy`}),(0,Q.jsxs)(_,{value:e.strategy,onValueChange:async e=>{t(await re({strategy:e}))},children:[(0,Q.jsx)(k,{className:`w-full h-9 text-xs`,children:(0,Q.jsx)(j,{})}),(0,Q.jsxs)(A,{children:[(0,Q.jsx)(S,{value:`round-robin`,children:`Round-robin`}),(0,Q.jsx)(S,{value:`fill-first`,children:`Fill-first`}),(0,Q.jsx)(S,{value:`lowest-usage`,children:`Lowest usage`})]})]}),(0,Q.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,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Max Retry`}),(0,Q.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 re({maxRetry:n}))}}),(0,Q.jsx)(`p`,{className:`text-[10px] text-text-subtle`,children:`How many accounts to try on failure. 0 = try all available accounts.`})]}),(0,Q.jsxs)(`div`,{className:`space-y-1.5 border-t border-border pt-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Q.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Cooldown parking`}),(0,Q.jsx)(b,{checked:e.cooldownEnabled,onCheckedChange:async e=>{t(await re({cooldownEnabled:e}))}})]}),(0,Q.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,Q.jsxs)(`div`,{className:`flex items-center justify-between text-xs border-t border-border pt-3`,children:[(0,Q.jsx)(`span`,{className:`text-text-subtle`,children:`Active accounts`}),(0,Q.jsx)(`span`,{className:`font-medium text-text-primary`,children:e.activeCount})]})]}):(0,Q.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,Z.useSyncExternalStore)(De,Oe);return e?n?(0,Q.jsx)(F,{open:e,onOpenChange:t,children:(0,Q.jsxs)(N,{className:`sm:max-w-sm`,children:[(0,Q.jsx)(g,{children:(0,Q.jsxs)(L,{className:`text-sm flex items-center gap-2`,children:[(0,Q.jsx)(x,{className:`size-4`}),` Rotation & Retry`]})}),(0,Q.jsx)(ke,{})]})}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.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,Q.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,Q.jsx)(`div`,{className:`flex justify-center pt-3 pb-1`,children:(0,Q.jsx)(`div`,{className:`w-10 h-1 rounded-full bg-border`})}),(0,Q.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-2 border-b border-border`,children:[(0,Q.jsxs)(`span`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,Q.jsx)(x,{className:`size-4`}),` Rotation & Retry`]}),(0,Q.jsx)(`button`,{onClick:()=>t(!1),className:`flex items-center justify-center size-7 rounded-md hover:bg-surface-elevated transition-colors`,children:(0,Q.jsx)(c,{className:`size-4`})})]}),(0,Q.jsx)(`div`,{className:`px-4 py-4 pb-8`,children:(0,Q.jsx)(ke,{})})]})]}):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 Me({className:e,variant:t,...n}){return(0,Q.jsx)(`div`,{className:d(je({variant:t}),e),...n})}function Ne(e){let t=Math.floor(Date.now()/1e3);return e>t?`${Math.floor((e-t)/60)}m`:`exp`}function Pe({accounts:e}){let[t,n]=(0,Z.useState)([]),[r,i]=(0,Z.useState)(!1),[a,o]=(0,Z.useState)(!1),[c,l]=(0,Z.useState)(new Map),u=e.filter(e=>e.hasRefreshToken);async function d(){if(u.length!==0){i(!0);try{let e=await ne(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 X(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,Q.jsxs)(`section`,{className:`border-t pt-4 space-y-2`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Q.jsx)(`p`,{className:`text-xs font-medium`,children:`Simulate export`}),t.length>0&&(0,Q.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[t.length,` round(s)`]})]}),(0,Q.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,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No OAuth account with a refresh token to export.`}):(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,Q.jsx)(b,{id:`sim-include-refresh`,checked:a,onCheckedChange:o,className:`cursor-pointer`}),(0,Q.jsx)(P,{htmlFor:`sim-include-refresh`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens`})]}),(0,Q.jsx)(m,{size:`sm`,className:`h-7 text-xs cursor-pointer`,disabled:r,onClick:()=>void d(),children:r?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):`Run export #${t.length+1}`})]}),t.length>0&&(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.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,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsxs)(`p`,{className:`text-xs font-medium text-primary`,children:[`Round #`,e.round]}),(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:e.time}),(0,Q.jsx)(Me,{variant:e.includeRefresh?`destructive`:`secondary`,className:`text-[9px] px-1 py-0`,children:e.includeRefresh?`with refresh`:`access only`})]}),e.items.map(t=>(0,Q.jsxs)(`div`,{className:`p-2 rounded-lg border bg-card space-y-1.5`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`text-[11px] font-medium`,children:t.label??t.email??t.id.slice(0,8)}),t.tokenChanged&&(0,Q.jsx)(Me,{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,Q.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px]`,children:[(0,Q.jsx)(`span`,{className:`w-20 shrink-0 text-muted-foreground text-[10px]`,children:e.label}),(0,Q.jsx)(`code`,{className:`flex-1 truncate font-mono text-[10px] bg-muted px-1 rounded`,children:e.preview??`N/A`}),e.expires&&(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground shrink-0`,children:Ne(e.expires)}),e.token?(0,Q.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,Q.jsx)(s,{className:`size-3 animate-spin`}):`Test`}):(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`-`}),t&&!t.loading&&(0,Q.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 Fe(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 Ie({open:e,onOpenChange:t,accounts:n}){let[r,i]=(0,Z.useState)(new Map),[o,c]=(0,Z.useState)(!1);async function l(e){i(t=>new Map(t).set(e,{loading:!0}));try{let t=await Y(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,Q.jsx)(F,{open:e,onOpenChange:t,children:(0,Q.jsxs)(N,{className:`sm:max-w-xl max-h-[85vh] flex flex-col`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsxs)(L,{className:`text-sm flex items-center gap-1.5`,children:[(0,Q.jsx)(a,{className:`size-4`}),` Token Test`]}),(0,Q.jsx)(I,{className:`text-xs`,children:`Probe stored tokens for validity. Nothing is modified.`})]}),(0,Q.jsxs)(`div`,{className:`space-y-4 overflow-y-auto flex-1 pr-1`,children:[(0,Q.jsxs)(`section`,{className:`space-y-2`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Q.jsx)(`p`,{className:`text-xs font-medium`,children:`Current tokens`}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,Q.jsx)(b,{id:`token-test-refresh`,checked:o,onCheckedChange:c,className:`cursor-pointer`}),(0,Q.jsx)(P,{htmlFor:`token-test-refresh`,className:`text-[11px] cursor-pointer`,children:`Also test refresh`})]}),(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`h-7 text-xs cursor-pointer`,onClick:u,children:`Test all`})]})]}),n.length===0&&(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No accounts to test.`}),(0,Q.jsx)(`div`,{className:`space-y-1.5`,children:n.map(e=>{let t=r.get(e.id),n=t?.result?.accessToken.status;return(0,Q.jsxs)(`div`,{className:`p-2 rounded border bg-card space-y-1`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Q.jsx)(`span`,{className:`text-xs font-medium truncate block`,children:e.label??e.email??e.id.slice(0,8)}),e.expiresAt&&(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:Fe(e.expiresAt)})]}),(0,Q.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,Q.jsx)(s,{className:`size-3 animate-spin`}):`Test`})]}),t&&!t.loading&&(0,Q.jsxs)(`div`,{className:`text-[11px] pl-2 border-l-2 border-muted`,children:[t.error&&(0,Q.jsx)(`p`,{className:`text-error`,children:t.error}),n&&(0,Q.jsxs)(`span`,{className:n.startsWith(`valid`)?`text-success`:`text-error`,children:[n,t.result?.accessToken.code?` (${t.result.accessToken.code})`:``]})]})]},e.id)})})]}),(0,Q.jsx)(Pe,{accounts:n})]}),(0,Q.jsx)(O,{children:(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Close`})})]})})}function Le(){let{usages:e,accounts:t,activeAccountId:n,initialLoading:r,refreshing:c,flashIds:l,reload:u}=de(),[d,f]=(0,Z.useState)(null),[p,h]=(0,Z.useState)(null),[g,_]=(0,Z.useState)(null),[v,y]=(0,Z.useState)(null),[b,S]=(0,Z.useState)(null),[C,w]=(0,Z.useState)(null);function T(e){u(),e&&f(e)}async function O(e,t){h(e);try{await J(e,{status:t===`disabled`?`active`:`disabled`})}catch(e){f(e.message)}h(null),u()}async function k(){if(g){try{await H(g.id),f(`Account "${g.display}" removed.`),u()}catch(e){f(`Failed to remove: ${e.message}`)}_(null)}}let A=new Map(t.map(e=>[e.id,e])),j=e[0]?.usage.lastFetchedAt;return(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(ie,{description:`Connect multiple Claude accounts. PPM rotates between them automatically to avoid rate limits.`,onRefresh:()=>void u(),refreshing:c,disabled:r,actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(m,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`add`),children:[(0,Q.jsx)(D,{className:`size-4`}),` Add account`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>{S(null),w(`export`)},children:[(0,Q.jsx)(i,{className:`size-4`}),` Export`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`import`),children:[(0,Q.jsx)(E,{className:`size-4`}),` Import`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`rotation`),children:[(0,Q.jsx)(x,{className:`size-4`}),` Rotation`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>w(`token-test`),children:[(0,Q.jsx)(a,{className:`size-4`}),` Token test`]})]})}),(0,Q.jsx)(le,{message:d,onDismiss:()=>f(null)}),(0,Q.jsxs)(`section`,{className:`space-y-2`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Q.jsx)(`h3`,{className:`text-sm font-medium`,children:`Accounts`}),j&&(0,Q.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`usage `,se(new Date(j).getTime())]})]}),r?(0,Q.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,Q.jsx)(s,{className:`size-4 animate-spin`}),` Loading accounts...`]}):e.length===0?(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,Q.jsx)(o,{className:`size-5 text-muted-foreground`}),(0,Q.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No accounts connected yet.`}),(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Add one to start using PPM.`})]}):(0,Q.jsx)(ue,{children:e.map(e=>(0,Q.jsx)(ce,{layout:`strip`,entry:e,isActive:e.accountId===n,accountInfo:A.get(e.accountId),onToggle:O,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,Q.jsx)(be,{profile:v.profile,accountId:v.accountId,onClose:()=>y(null)}),g&&(0,Q.jsx)(xe,{display:g.display,onConfirm:()=>void k(),onCancel:()=>_(null)}),(0,Q.jsx)(Se,{open:C===`add`,onOpenChange:e=>w(e?`add`:null),onSuccess:T}),(0,Q.jsx)(we,{open:C===`export`,onOpenChange:e=>{w(e?`export`:null),e||S(null)},accounts:t,preselectId:b,onMessage:f}),(0,Q.jsx)(Te,{open:C===`import`,onOpenChange:e=>w(e?`import`:null),onSuccess:T}),(0,Q.jsx)(Ae,{open:C===`rotation`,onOpenChange:e=>w(e?`rotation`:null)}),(0,Q.jsx)(Ie,{open:C===`token-test`,onOpenChange:e=>w(e?`token-test`:null),accounts:t})]})}function Re({open:e,onOpenChange:t,label:n,onLabelChange:r,apiKey:i,onApiKeyChange:a,adding:c,onAddApiKey:l,deviceWaiting:u,onStartDevice:d,device:f,error:p,browser:h,onStartBrowser:_,loginStarting:v,callbackUrl:b,onCallbackUrlChange:x,submittingCallback:S,onSubmitCallback:C}){let w=v||u||!!h||c;return(0,Q.jsx)(F,{open:e,onOpenChange:t,children:(0,Q.jsxs)(N,{className:`sm:max-w-md max-h-[90dvh] overflow-y-auto`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsx)(L,{className:`text-sm`,children:`Add Codex Account`}),(0,Q.jsx)(I,{className:`text-xs leading-relaxed`,children:`Choose browser login, a device code, or an OpenAI API key.`})]}),(0,Q.jsxs)(`div`,{className:`space-y-3`,children:[(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{htmlFor:`codex-label`,className:`text-xs`,children:`Label (optional)`}),(0,Q.jsx)(M,{id:`codex-label`,placeholder:`e.g. Personal, Work`,value:n,onChange:e=>r(e.target.value),disabled:w,className:`text-xs`})]}),(0,Q.jsxs)(`div`,{className:`rounded-md border p-3 space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] font-medium`,children:`Browser login`}),(0,Q.jsxs)(m,{size:`sm`,className:`w-full cursor-pointer gap-1.5`,onClick:_,disabled:w,children:[(0,Q.jsx)(y,{className:`size-4`}),` Sign in with browser`]}),h&&(0,Q.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,Q.jsxs)(`a`,{href:h.authUrl,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-primary hover:underline`,children:[(0,Q.jsx)(y,{className:`size-3`}),` Open ChatGPT sign-in`]}),(0,Q.jsx)(`p`,{children:`Sign in, then copy the full localhost callback URL from the address bar and paste it below. On a phone, copy it even if the page fails to load.`}),(0,Q.jsx)(P,{htmlFor:`codex-callback-url`,children:`Callback URL`}),(0,Q.jsx)(M,{id:`codex-callback-url`,type:`password`,autoComplete:`off`,spellCheck:!1,placeholder:`http://localhost:.../auth/callback?...`,value:b,onChange:e=>x(e.target.value),disabled:S}),(0,Q.jsxs)(m,{size:`sm`,onClick:C,disabled:!b.trim()||S,children:[S&&(0,Q.jsx)(s,{className:`size-3 animate-spin`}),` Submit callback URL`]}),(0,Q.jsxs)(`p`,{role:`status`,className:`flex items-center gap-1.5 text-muted-foreground`,children:[(0,Q.jsx)(s,{className:`size-3 animate-spin`}),` Waiting for authorization. This may complete automatically on this computer.`]})]})]}),(0,Q.jsxs)(`div`,{className:`rounded-md border p-3 space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] font-medium`,children:`Device code`}),(0,Q.jsx)(m,{size:`sm`,className:`w-full cursor-pointer gap-1.5`,onClick:d,disabled:w,children:u?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(s,{className:`size-4 animate-spin`}),` Waiting for authorization...`]}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(R,{className:`size-4`}),` Sign in with device code`]})}),f&&(0,Q.jsxs)(`div`,{className:`rounded-md border border-primary/40 bg-primary/10 p-2.5 space-y-1.5`,children:[(0,Q.jsx)(`p`,{className:`text-[11px]`,children:`Enter this code to authorize:`}),(0,Q.jsx)(`div`,{className:`font-mono text-lg tracking-widest`,children:f.userCode}),(0,Q.jsxs)(`a`,{href:f.verificationUrl,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 text-primary hover:underline text-[11px]`,children:[(0,Q.jsx)(y,{className:`size-3`}),` `,f.verificationUrl]})]})]}),(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`div`,{className:`flex-1 border-t`}),(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`or paste an API key`}),(0,Q.jsx)(`div`,{className:`flex-1 border-t`})]}),(0,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{htmlFor:`codex-api-key`,className:`text-xs`,children:`OpenAI API key`}),(0,Q.jsx)(M,{id:`codex-api-key`,type:`password`,placeholder:`sk-...`,value:i,onChange:e=>a(e.target.value),className:`text-xs font-mono`})]})]}),v&&(0,Q.jsx)(`p`,{role:`status`,className:`text-xs`,children:`Starting login...`}),p&&(0,Q.jsx)(`div`,{role:`alert`,className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:p}),(0,Q.jsxs)(O,{children:[(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Cancel`}),(0,Q.jsxs)(m,{size:`sm`,className:`text-xs cursor-pointer gap-1.5`,onClick:l,disabled:!i.trim()||w,children:[c?(0,Q.jsx)(s,{className:`size-3.5 animate-spin`}):(0,Q.jsx)(o,{className:`size-3.5`}),`Add key`]})]})]})})}function ze({mode:e,onOpenChange:t,password:n,onPasswordChange:r,busy:a,onExport:o,onImport:c,error:l}){let u=(0,Z.useRef)(null),d=e===`export`;return(0,Q.jsx)(F,{open:e!==null,onOpenChange:t,children:(0,Q.jsxs)(N,{className:`sm:max-w-md`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsxs)(L,{className:`text-sm flex items-center gap-1.5`,children:[(0,Q.jsx)(z,{className:`size-4`}),` `,d?`Export Codex Accounts`:`Import Codex Accounts`]}),(0,Q.jsx)(I,{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,Q.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,Q.jsx)(P,{htmlFor:`codex-backup-password`,className:`text-xs`,children:`Password`}),(0,Q.jsx)(M,{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,Q.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`A backup holds full logins — keep the file and its password together.`})]}),l&&(0,Q.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:l}),(0,Q.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,Q.jsxs)(O,{children:[(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Cancel`}),(0,Q.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,Q.jsx)(s,{className:`size-3.5 animate-spin`}):d?(0,Q.jsx)(i,{className:`size-3.5`}):(0,Q.jsx)(E,{className:`size-3.5`}),d?`Download backup`:`Choose file`]})]})]})})}var Be=[{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 Ve({open:e,onOpenChange:t,strategy:n,onChange:r}){return(0,Q.jsx)(F,{open:e,onOpenChange:t,children:(0,Q.jsxs)(N,{className:`sm:max-w-md`,children:[(0,Q.jsxs)(g,{children:[(0,Q.jsx)(L,{className:`text-sm`,children:`Codex Rotation`}),(0,Q.jsx)(I,{className:`text-xs leading-relaxed`,children:`How a new chat chooses among your Codex accounts.`})]}),(0,Q.jsx)(`div`,{className:`space-y-2`,children:Be.map(e=>(0,Q.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,Q.jsx)(`p`,{className:`text-sm font-medium`,children:e.label}),(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.hint})]},e.value))}),(0,Q.jsx)(O,{children:(0,Q.jsx)(m,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Done`})})]})})}function He(e){return e==null?null:Math.round(e*100)}function Ue({usage:e}){let t=e.session==null&&e.weekly==null;return(0,Q.jsxs)(`div`,{className:`space-y-2`,children:[(t||e.session!=null)&&(0,Q.jsx)(ae,{label:`5-Hour Session`,pct:He(e.fiveHour),reset:fe(e.session),resetsAt:e.session?.resetsAt}),(t||e.weekly!=null)&&(0,Q.jsx)(ae,{label:`Weekly`,pct:He(e.sevenDay),reset:fe(e.weekly),resetsAt:e.weekly?.resetsAt})]})}var We=2e3,Ge=21e4;function Ke(e){let[t,n]=(0,Z.useState)([]),[r,i]=(0,Z.useState)(`round-robin`),[a,o]=(0,Z.useState)({}),[s,c]=(0,Z.useState)(!1),[d,f]=(0,Z.useState)(new Set),[p,m]=(0,Z.useState)(``),[h,g]=(0,Z.useState)(``),[_,v]=(0,Z.useState)(!1),[y,b]=(0,Z.useState)(null),[x,S]=(0,Z.useState)(null),[C,w]=(0,Z.useState)(!1),[T,E]=(0,Z.useState)(null),[D,O]=(0,Z.useState)(!1),[k,A]=(0,Z.useState)(``),[j,M]=(0,Z.useState)(!1),[N,P]=(0,Z.useState)(``),[F,I]=(0,Z.useState)(!1),[L,R]=(0,Z.useState)(!1),[ee,z]=(0,Z.useState)(null),B=(0,Z.useRef)(null),V=(0,Z.useRef)(null),H=(0,Z.useRef)(0),U=(0,Z.useRef)(!1),W=(0,Z.useRef)(!1),G=(0,Z.useRef)(!1),K=(0,Z.useRef)(e);K.current=e;let q=(0,Z.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,Z.useEffect)(()=>{q()},[q]);let te=async()=>{if(!(!p.trim()||W.current||U.current||V.current)){W.current=!0,v(!0),b(null);try{await l.post(`/api/codex-accounts/api-key`,{apiKey:p.trim(),label:h.trim()||void 0}),m(``),g(``),e(),await q()}catch(e){b(e.message)}finally{W.current=!1,v(!1)}}},J=(0,Z.useCallback)(()=>{H.current+=1,U.current=!1,G.current=!1,B.current?.(),B.current=null;let e=V.current;V.current=null,e&&l.del(`/api/codex-accounts/${e.method}-login/${e.id}`).catch(()=>{})},[]),Y=(0,Z.useCallback)(()=>{J(),S(null),w(!1),E(null),O(!1),A(``),M(!1)},[J]),ne=(0,Z.useCallback)((e,t)=>{let n=Date.now()+(t===`browser`?61e4:Ge),r=!1,i;B.current=()=>{r=!0,clearTimeout(i)};let a=async()=>{if(r)return;let o=null;try{o=await l.get(`/api/codex-accounts/${t}-login/${e}/status`)}catch{}if(!r){if(o?.state===`done`){Y(),g(``),K.current(),await q();return}if(o?.state===`error`||Date.now()>n){Y(),b(o?.state===`error`?o.error:`${t===`browser`?`Browser`:`Device`} login timed out.`);return}i=setTimeout(a,We)}};a()},[Y,q]);(0,Z.useEffect)(()=>J,[J]);let X=async e=>{if(U.current||V.current||W.current)return;U.current=!0;let t=++H.current;O(!0),b(null);try{let n=await l.post(`/api/codex-accounts/${e}-login`,{label:h.trim()||void 0});if(t!==H.current){l.del(`/api/codex-accounts/${e}-login/${n.id}`).catch(()=>{});return}V.current={id:n.id,method:e},e===`device`?(S(n),w(!0)):E(n),ne(n.id,e)}catch(e){t===H.current&&b(e.message)}finally{t===H.current&&(U.current=!1,O(!1))}};return{accounts:t,strategy:r,usages:a,loading:s,apiKey:p,setApiKey:m,label:h,setLabel:g,adding:_,err:y,setErr:b,device:x,deviceWaiting:C,backupPassword:N,setBackupPassword:P,exporting:F,importing:L,msg:ee,setMsg:z,toggling:d,load:q,addApiKey:te,startDevice:()=>X(`device`),startBrowser:()=>X(`browser`),browser:T,loginStarting:D,callbackUrl:k,setCallbackUrl:A,submittingCallback:j,submitCallback:async()=>{let e=V.current;if(e?.method!==`browser`||!k.trim()||G.current)return;let t=H.current;G.current=!0,M(!0),b(null);let n=k.trim();A(``);try{await l.post(`/api/codex-accounts/browser-login/${e.id}/callback`,{callbackUrl:n})}catch(e){t===H.current&&b(e.message)}finally{t===H.current&&(G.current=!1,M(!1))}},cancelLogin:Y,remove:async e=>{await l.del(`/api/codex-accounts/${e}`),await q()},toggle:async(e,t)=>{let n=t===`disabled`?`active`:`disabled`;f(t=>new Set(t).add(e)),b(null);try{await l.patch(`/api/codex-accounts/${e}`,{status:n}),await q()}catch(e){b(e.message||`Could not change the account`)}finally{f(t=>{let n=new Set(t);return n.delete(e),n})}},changeStrategy:async e=>{i(e);try{await l.put(`/api/codex-accounts/strategy`,{strategy:e})}catch{}},doExport:async()=>{if(!N.trim()){b(`Set a backup password first.`);return}I(!0),b(null),z(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:N})});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),z(`Backup downloaded.`),e()}catch(e){b(e.message)}finally{I(!1)}},doImport:async t=>{if(!N.trim()){b(`Enter the backup password first.`);return}R(!0),b(null),z(null);try{let n=await t.text(),r=await l.post(`/api/codex-accounts/import`,{data:n,password:N});z(`Imported ${r.imported}${r.skipped?`, skipped ${r.skipped}`:``}.`),e(),await q()}catch(e){b(e.message)}finally{R(!1)}}}}function qe(){let[e,t]=(0,Z.useState)(null),n=Ke(()=>t(null));return(0,Q.jsxs)(`div`,{className:`space-y-4`,children:[(0,Q.jsx)(ie,{description:(0,Q.jsxs)(Q.Fragment,{children:[`Each Codex account keeps its own login (`,(0,Q.jsx)(`code`,{children:`CODEX_HOME`}),`). One is picked per chat by the rotation setting.`]}),onRefresh:()=>void n.load(),refreshing:n.loading,actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(m,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`add`),children:[(0,Q.jsx)(D,{className:`size-4`}),` Add account`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`export`),children:[(0,Q.jsx)(i,{className:`size-4`}),` Export`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`import`),children:[(0,Q.jsx)(E,{className:`size-4`}),` Import`]}),(0,Q.jsxs)(m,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`rotation`),children:[(0,Q.jsx)(x,{className:`size-4`}),` Rotation`]})]})}),(0,Q.jsx)(le,{message:n.msg??n.err,onDismiss:()=>{n.setMsg(null),n.setErr(null)}}),(0,Q.jsxs)(`section`,{className:`space-y-2`,children:[(0,Q.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Q.jsx)(`h3`,{className:`text-sm font-medium`,children:`Codex Accounts`}),(0,Q.jsx)(`span`,{className:`text-[10px] text-muted-foreground capitalize`,children:n.strategy.replace(`-`,` `)})]}),n.loading&&n.accounts.length===0?(0,Q.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,Q.jsx)(s,{className:`size-4 animate-spin`}),` Loading accounts...`]}):n.accounts.length===0?(0,Q.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,Q.jsx)(o,{className:`size-5 text-muted-foreground`}),(0,Q.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No Codex accounts yet.`}),(0,Q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Chats use your default `,(0,Q.jsx)(`code`,{children:`~/.codex`}),` login until you add one.`]})]}):(0,Q.jsx)(ue,{children:n.accounts.map(e=>{let t=n.usages[e.id]??{};return(0,Q.jsxs)(oe,{dense:!0,className:`min-w-[300px] shrink-0 snap-start`,"data-testid":`account-card`,"data-account-id":e.id,children:[(0,Q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`text-sm font-medium truncate flex-1 min-w-0`,children:e.label}),(0,Q.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,Q.jsx)(`span`,{className:`text-[10px] text-text-subtle shrink-0`,children:e.planType}),(0,Q.jsx)(b,{checked:e.status!==`disabled`,onCheckedChange:()=>void n.toggle(e.id,e.status??`active`),disabled:n.toggling.has(e.id),"aria-label":e.status===`disabled`?`Enable account`:`Disable account`,className:`cursor-pointer shrink-0`}),(0,Q.jsxs)(v,{children:[(0,Q.jsx)(ee,{asChild:!0,children:(0,Q.jsx)(`button`,{type:`button`,onClick:()=>void n.remove(e.id),"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,Q.jsx)(C,{className:`size-4`})})}),(0,Q.jsx)(T,{side:`top`,children:`Remove account`})]})]}),(0,Q.jsx)(Ue,{usage:t})]},e.id)})})]}),(0,Q.jsx)(Re,{open:e===`add`,onOpenChange:e=>{e||n.cancelLogin(),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,browser:n.browser,onStartBrowser:()=>void n.startBrowser(),loginStarting:n.loginStarting,callbackUrl:n.callbackUrl,onCallbackUrlChange:n.setCallbackUrl,submittingCallback:n.submittingCallback,onSubmitCallback:()=>void n.submitCallback(),error:n.err}),(0,Q.jsx)(ze,{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,Q.jsx)(Ve,{open:e===`rotation`,onOpenChange:e=>t(e?`rotation`:null),strategy:n.strategy,onChange:e=>void n.changeStrategy(e)})]})}var Je=[{id:`claude`,label:`Claude`},{id:`codex`,label:`Codex`}];function Ye(){let[e,t]=(0,Z.useState)(null),[n,r]=(0,Z.useState)(`claude`);(0,Z.useEffect)(()=>{let e=!1;return W().then(n=>{e||t(new Set(Object.keys(n.providers??{})))}).catch(()=>{e||t(new Set([`claude`]))}),()=>{e=!0}},[]);let i=Je.filter(t=>t.id===`claude`||e?.has(t.id)),a=i.length>1;return(0,Q.jsxs)(`div`,{className:`space-y-4`,"data-testid":`accounts-pane`,"data-provider":n,children:[a&&(0,Q.jsx)(`div`,{className:`flex gap-1 border-b border-border/50`,children:i.map(e=>(0,Q.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,Q.jsx)(w,{providerId:e.id}),e.label]},e.id))}),e===null&&!a&&(0,Q.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,Q.jsx)(s,{className:`size-3 animate-spin`}),` Checking configured providers...`]}),n===`claude`?(0,Q.jsx)(Le,{}):(0,Q.jsx)(qe,{})]})}export{Ye as AccountsSettingsSection};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-BBdkypKW.js";import"./api-client-DwXlVfXP.js";import"./portal-container-context-DeLx1cOI.js";import"./panel-store-D42k25jy.js";import"./window-store-CfxP5yor.js";import"./tab-store-B2ip0-Mv.js";import"./use-is-mobile-Bi42QhIi.js";import{t as e}from"./ai-settings-section-M07DCjAI.js";export{e as AISettingsSection};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-CuWCHIVb.js";import"./vendor-ui-BBdkypKW.js";import{i as e,n as t}from"./api-client-DwXlVfXP.js";export{t as api,e as projectUrl};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{K as e}from"./vendor-mermaid-CfY1-PkA.js";export{e as createArchitectureServices};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./createLucideIcon-D6fVXe3s.js";var t=e(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]);export{t};
|