@hienlh/ppm 0.23.5 → 0.23.6

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.
Files changed (305) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/cli-reference.md +4 -4
  4. package/assets/skills/ppm/references/http-api.md +2 -1
  5. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js +1 -0
  6. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.br +0 -0
  7. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.gz +0 -0
  8. package/dist/web/assets/{ai-resource-editor-DKcsVDle.js → ai-resource-editor-Dn_wB-o5.js} +1 -1
  9. package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.br +0 -0
  10. package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.gz +0 -0
  11. package/dist/web/assets/{ai-settings-section-D7zJ-hCO.js → ai-settings-section-CEbW8jRy.js} +1 -1
  12. package/dist/web/assets/ai-settings-section-CEbW8jRy.js.br +0 -0
  13. package/dist/web/assets/ai-settings-section-CEbW8jRy.js.gz +0 -0
  14. package/dist/web/assets/{ai-settings-section-OPqC2bYG.js → ai-settings-section-D-mwEYFZ.js} +1 -1
  15. package/dist/web/assets/{appearance-settings-section-DL466x83.js → appearance-settings-section-tw6TpFb6.js} +1 -1
  16. package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.br +0 -0
  17. package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.gz +0 -0
  18. package/dist/web/assets/{branch-review-tab-Dag86n_R.js → branch-review-tab-MBuMWp_i.js} +1 -1
  19. package/dist/web/assets/branch-review-tab-MBuMWp_i.js.br +0 -0
  20. package/dist/web/assets/branch-review-tab-MBuMWp_i.js.gz +0 -0
  21. package/dist/web/assets/{chat-tab-QFDhzzBZ.js → chat-tab-DVvnqhw6.js} +1 -1
  22. package/dist/web/assets/chat-tab-DVvnqhw6.js.br +0 -0
  23. package/dist/web/assets/chat-tab-DVvnqhw6.js.gz +0 -0
  24. package/dist/web/assets/chat-tab-DaEHva22.js +15 -0
  25. package/dist/web/assets/chat-tab-DaEHva22.js.br +0 -0
  26. package/dist/web/assets/chat-tab-DaEHva22.js.gz +0 -0
  27. package/dist/web/assets/{code-editor-K-IN8VwJ.js → code-editor-Bu9lhTVp.js} +3 -3
  28. package/dist/web/assets/code-editor-Bu9lhTVp.js.br +0 -0
  29. package/dist/web/assets/code-editor-Bu9lhTVp.js.gz +0 -0
  30. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js +1 -0
  31. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.br +0 -0
  32. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.gz +0 -0
  33. package/dist/web/assets/{conflict-editor-qMGJH0Bx.js → conflict-editor-BA3y-qSH.js} +1 -1
  34. package/dist/web/assets/conflict-editor-BA3y-qSH.js.br +0 -0
  35. package/dist/web/assets/conflict-editor-BA3y-qSH.js.gz +0 -0
  36. package/dist/web/assets/{csv-preview-D2I742dl.js → csv-preview-BioxkrQF.js} +1 -1
  37. package/dist/web/assets/csv-preview-BioxkrQF.js.br +0 -0
  38. package/dist/web/assets/csv-preview-BioxkrQF.js.gz +0 -0
  39. package/dist/web/assets/{database-viewer-Bz4LjgIa.js → database-viewer-BSoJ0E6p.js} +1 -1
  40. package/dist/web/assets/database-viewer-BSoJ0E6p.js.br +0 -0
  41. package/dist/web/assets/database-viewer-BSoJ0E6p.js.gz +0 -0
  42. package/dist/web/assets/{design-tab-C987MtMR.js → design-tab-iU2CviE3.js} +1 -1
  43. package/dist/web/assets/design-tab-iU2CviE3.js.br +0 -0
  44. package/dist/web/assets/design-tab-iU2CviE3.js.gz +0 -0
  45. package/dist/web/assets/{designs-sidebar-panel-CapP1yXq.js → designs-sidebar-panel-DHh5QsH9.js} +1 -1
  46. package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.br +0 -0
  47. package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.gz +0 -0
  48. package/dist/web/assets/{diff-viewer-CdXi7cZN.js → diff-viewer-lctWoSmG.js} +1 -1
  49. package/dist/web/assets/diff-viewer-lctWoSmG.js.br +0 -0
  50. package/dist/web/assets/diff-viewer-lctWoSmG.js.gz +0 -0
  51. package/dist/web/assets/{editor-language-service-Zle_PZV8.js → editor-language-service-fPG56hQO.js} +1 -1
  52. package/dist/web/assets/editor-language-service-fPG56hQO.js.br +0 -0
  53. package/dist/web/assets/editor-language-service-fPG56hQO.js.gz +0 -0
  54. package/dist/web/assets/{explorer-body-DHMQR1Rk.js → explorer-body-BgF7FsxI.js} +1 -1
  55. package/dist/web/assets/explorer-body-BgF7FsxI.js.br +0 -0
  56. package/dist/web/assets/explorer-body-BgF7FsxI.js.gz +0 -0
  57. package/dist/web/assets/{explorer-window-content-Df40nQBk.js → explorer-window-content-C21w_7lf.js} +1 -1
  58. package/dist/web/assets/explorer-window-content-C21w_7lf.js.br +0 -0
  59. package/dist/web/assets/explorer-window-content-C21w_7lf.js.gz +0 -0
  60. package/dist/web/assets/{extension-manager-section-B2nZzJ2b.js → extension-manager-section-rbkXsZVR.js} +1 -1
  61. package/dist/web/assets/extension-manager-section-rbkXsZVR.js.br +0 -0
  62. package/dist/web/assets/extension-manager-section-rbkXsZVR.js.gz +0 -0
  63. package/dist/web/assets/{extension-webview-BGoDxkdF.js → extension-webview-uPO0WgCq.js} +1 -1
  64. package/dist/web/assets/extension-webview-uPO0WgCq.js.br +0 -0
  65. package/dist/web/assets/extension-webview-uPO0WgCq.js.gz +0 -0
  66. package/dist/web/assets/{files-settings-section-DC3OzzOl.js → files-settings-section-CT7mDb0L.js} +1 -1
  67. package/dist/web/assets/files-settings-section-CT7mDb0L.js.br +0 -0
  68. package/dist/web/assets/files-settings-section-CT7mDb0L.js.gz +0 -0
  69. package/dist/web/assets/{general-settings-section-i41W43ER.js → general-settings-section-DANPfMRN.js} +1 -1
  70. package/dist/web/assets/general-settings-section-DANPfMRN.js.br +0 -0
  71. package/dist/web/assets/general-settings-section-DANPfMRN.js.gz +0 -0
  72. package/dist/web/assets/{git-log-panel-DHzPIkJg.js → git-log-panel-BJPkLiEw.js} +1 -1
  73. package/dist/web/assets/git-log-panel-BJPkLiEw.js.br +0 -0
  74. package/dist/web/assets/git-log-panel-BJPkLiEw.js.gz +0 -0
  75. package/dist/web/assets/{glide-data-grid-Dj4vrDvj.js → glide-data-grid-R4PcAntf.js} +1 -1
  76. package/dist/web/assets/glide-data-grid-R4PcAntf.js.br +0 -0
  77. package/dist/web/assets/glide-data-grid-R4PcAntf.js.gz +0 -0
  78. package/dist/web/assets/{group-chat-tab-DfwZb-fI.js → group-chat-tab-BXMdo8w9.js} +1 -1
  79. package/dist/web/assets/group-chat-tab-BXMdo8w9.js.br +0 -0
  80. package/dist/web/assets/group-chat-tab-BXMdo8w9.js.gz +0 -0
  81. package/dist/web/assets/{index-jG9mLs-J.js → index-C8nGqkKN.js} +5 -5
  82. package/dist/web/assets/index-C8nGqkKN.js.br +0 -0
  83. package/dist/web/assets/index-C8nGqkKN.js.gz +0 -0
  84. package/dist/web/assets/{index-DMA-So69.css → index-DvClbTQx.css} +1 -1
  85. package/dist/web/assets/index-DvClbTQx.css.br +0 -0
  86. package/dist/web/assets/{index-DMA-So69.css.gz → index-DvClbTQx.css.gz} +0 -0
  87. package/dist/web/assets/{jira-watcher-section-BJ9edGEP.js → jira-watcher-section-DHRoyWcG.js} +1 -1
  88. package/dist/web/assets/{keybindings-store-BlapkC6O.js → keybindings-store-BGKlQQAv.js} +1 -1
  89. package/dist/web/assets/{keyboard-shortcuts-section-CxdGSNGr.js → keyboard-shortcuts-section-BKej4mUf.js} +1 -1
  90. package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.br +0 -0
  91. package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.gz +0 -0
  92. package/dist/web/assets/{markdown-renderer-ok96IgnS.js → markdown-renderer-BHtYqkYZ.js} +1 -1
  93. package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.br +0 -0
  94. package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.gz +0 -0
  95. package/dist/web/assets/{markdown-renderer-DJ9EVU1B.js → markdown-renderer-vDNuKjel.js} +1 -1
  96. package/dist/web/assets/{mobile-explorer-sheet-Cc03LUKy.js → mobile-explorer-sheet-DtvxS7-r.js} +1 -1
  97. package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.br +0 -0
  98. package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.gz +0 -0
  99. package/dist/web/assets/{new-design-dialog-Drkjb_LI.js → new-design-dialog-DS_XrpTG.js} +1 -1
  100. package/dist/web/assets/new-design-dialog-DS_XrpTG.js.br +0 -0
  101. package/dist/web/assets/new-design-dialog-DS_XrpTG.js.gz +0 -0
  102. package/dist/web/assets/{notification-store-DCyxho0O.js → notification-store-Dnnj20Ky.js} +1 -1
  103. package/dist/web/assets/{ppmbot-settings-section-C8PFlvaq.js → ppmbot-settings-section-D8AES1BA.js} +1 -1
  104. package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.br +0 -0
  105. package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.gz +0 -0
  106. package/dist/web/assets/{problems-panel-CFYO0Ro3.js → problems-panel-DTBG4beI.js} +1 -1
  107. package/dist/web/assets/problems-panel-DTBG4beI.js.br +0 -0
  108. package/dist/web/assets/problems-panel-DTBG4beI.js.gz +0 -0
  109. package/dist/web/assets/{process-table-BVeRguFg.js → process-table-D_gR2XA6.js} +1 -1
  110. package/dist/web/assets/process-table-D_gR2XA6.js.br +0 -0
  111. package/dist/web/assets/process-table-D_gR2XA6.js.gz +0 -0
  112. package/dist/web/assets/{proxy-settings-section-BcHIEANE.js → proxy-settings-section-CqtmbeRj.js} +1 -1
  113. package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.br +0 -0
  114. package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.gz +0 -0
  115. package/dist/web/assets/{remote-desktop-clipboard-notice-BGsp0edA.js → remote-desktop-clipboard-notice-Djt6cpNL.js} +1 -1
  116. package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.br +0 -0
  117. package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.gz +0 -0
  118. package/dist/web/assets/{remote-desktop-mobile-sheet-DxkmF8qb.js → remote-desktop-mobile-sheet-BQxhJUkm.js} +2 -2
  119. package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.br +0 -0
  120. package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.gz +0 -0
  121. package/dist/web/assets/{remote-desktop-mobile-view-DMD0M9Jh.js → remote-desktop-mobile-view-DGnT8RY7.js} +1 -1
  122. package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.br +0 -0
  123. package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.gz +0 -0
  124. package/dist/web/assets/{remote-desktop-readiness-gate-CsZCCRJI.js → remote-desktop-readiness-gate-DNJF8TcF.js} +1 -1
  125. package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.br +0 -0
  126. package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.gz +0 -0
  127. package/dist/web/assets/{remote-desktop-window-content-DrHw_vwY.js → remote-desktop-window-content-Ds0DKmM0.js} +1 -1
  128. package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.br +0 -0
  129. package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.gz +0 -0
  130. package/dist/web/assets/{schedules-settings-section-Ci0O2Ng6.js → schedules-settings-section-BKoPovy2.js} +1 -1
  131. package/dist/web/assets/schedules-settings-section-BKoPovy2.js.br +0 -0
  132. package/dist/web/assets/schedules-settings-section-BKoPovy2.js.gz +0 -0
  133. package/dist/web/assets/{settings-body-B6JGOIYb.js → settings-body-k2qPgRFe.js} +2 -2
  134. package/dist/web/assets/settings-body-k2qPgRFe.js.br +0 -0
  135. package/dist/web/assets/settings-body-k2qPgRFe.js.gz +0 -0
  136. package/dist/web/assets/{settings-tab-CIQM4fNE.js → settings-tab-Bb23VdBu.js} +1 -1
  137. package/dist/web/assets/{settings-window-content-BGNNz-E5.js → settings-window-content-ClarWusz.js} +1 -1
  138. package/dist/web/assets/{sql-query-editor-4iCGE4h2.js → sql-query-editor-BjIMi9Wk.js} +1 -1
  139. package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.br +0 -0
  140. package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.gz +0 -0
  141. package/dist/web/assets/{sqlite-viewer-CK6DulYk.js → sqlite-viewer-BNcA6Irq.js} +1 -1
  142. package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.br +0 -0
  143. package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.gz +0 -0
  144. package/dist/web/assets/{system-monitor-body-J9JtvAWV.js → system-monitor-body-D0T3ggt2.js} +2 -2
  145. package/dist/web/assets/system-monitor-body-D0T3ggt2.js.br +0 -0
  146. package/dist/web/assets/system-monitor-body-D0T3ggt2.js.gz +0 -0
  147. package/dist/web/assets/{system-monitor-tab-DjBeRE81.js → system-monitor-tab-I1Igmoey.js} +1 -1
  148. package/dist/web/assets/{system-monitor-window-content-BT7-ugFx.js → system-monitor-window-content-C5SeUv1H.js} +1 -1
  149. package/dist/web/assets/{tab-host-window-content-CWBaWKjA.js → tab-host-window-content-CIRGNCvi.js} +1 -1
  150. package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.br +0 -0
  151. package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.gz +0 -0
  152. package/dist/web/assets/{team-member-sheet-Br6mrxrw.js → team-member-sheet-CwXpLi3X.js} +2 -2
  153. package/dist/web/assets/team-member-sheet-CwXpLi3X.js.br +0 -0
  154. package/dist/web/assets/team-member-sheet-CwXpLi3X.js.gz +0 -0
  155. package/dist/web/assets/{team-member-window-content-CwCy7ZWf.js → team-member-window-content-4swiiDz7.js} +1 -1
  156. package/dist/web/assets/team-member-window-content-4swiiDz7.js.br +0 -0
  157. package/dist/web/assets/team-member-window-content-4swiiDz7.js.gz +0 -0
  158. package/dist/web/assets/{terminal-tab-BW14RpCb.js → terminal-tab-BGcdtMMT.js} +1 -1
  159. package/dist/web/assets/terminal-tab-BGcdtMMT.js.br +0 -0
  160. package/dist/web/assets/terminal-tab-BGcdtMMT.js.gz +0 -0
  161. package/dist/web/assets/{tool-cards-CgOBEUnb.js → tool-cards-D0-krtA2.js} +2 -2
  162. package/dist/web/assets/tool-cards-D0-krtA2.js.br +0 -0
  163. package/dist/web/assets/tool-cards-D0-krtA2.js.gz +0 -0
  164. package/dist/web/assets/{use-inline-blame-Bzjfru4n.js → use-inline-blame-pKaXyGU-.js} +1 -1
  165. package/dist/web/assets/use-inline-blame-pKaXyGU-.js.br +0 -0
  166. package/dist/web/assets/use-inline-blame-pKaXyGU-.js.gz +0 -0
  167. package/dist/web/assets/{use-lsp-hGdjL2hV.js → use-lsp-71azTXQz.js} +1 -1
  168. package/dist/web/assets/use-lsp-71azTXQz.js.br +0 -0
  169. package/dist/web/assets/use-lsp-71azTXQz.js.gz +0 -0
  170. package/dist/web/assets/{use-monaco-theme-rH6epJYA.js → use-monaco-theme-C88KphGx.js} +1 -1
  171. package/dist/web/assets/{use-websocket-QwURkjpV.js → use-websocket-Chk9guIU.js} +1 -1
  172. package/dist/web/assets/{video-preview-P9T-ZVdN.js → video-preview-DxEX-uGo.js} +1 -1
  173. package/dist/web/assets/video-preview-DxEX-uGo.js.br +0 -0
  174. package/dist/web/assets/video-preview-DxEX-uGo.js.gz +0 -0
  175. package/dist/web/index.html +2 -2
  176. package/dist/web/index.html.br +0 -0
  177. package/dist/web/index.html.gz +0 -0
  178. package/dist/web/sw.js +1 -1
  179. package/dist/web/sw.js.br +0 -0
  180. package/dist/web/sw.js.gz +0 -0
  181. package/package.json +1 -1
  182. package/src/providers/codex-app-server/codex-reset-credit.ts +49 -0
  183. package/src/server/routes/codex-accounts.ts +14 -0
  184. package/src/services/codex-reset-credit.service.ts +70 -0
  185. package/src/services/edge-forwarder.ts +191 -191
  186. package/src/services/windows-process-tree.ts +351 -351
  187. package/src/shared/usage-extra.ts +19 -0
  188. package/src/types/chat.ts +2 -0
  189. package/src/web/components/chat/codex-usage-panel.tsx +4 -0
  190. package/src/web/components/settings/accounts/account-card.tsx +5 -1
  191. package/src/web/components/settings/accounts/account-usage-extras.tsx +3 -2
  192. package/src/web/components/settings/accounts/codex-accounts-section.tsx +3 -1
  193. package/src/web/components/settings/accounts/codex-reset-credit-button.tsx +120 -0
  194. package/dist/web/assets/accounts-settings-section-CgG5P3Jm.js +0 -1
  195. package/dist/web/assets/accounts-settings-section-CgG5P3Jm.js.br +0 -0
  196. package/dist/web/assets/accounts-settings-section-CgG5P3Jm.js.gz +0 -0
  197. package/dist/web/assets/ai-resource-editor-DKcsVDle.js.br +0 -0
  198. package/dist/web/assets/ai-resource-editor-DKcsVDle.js.gz +0 -0
  199. package/dist/web/assets/ai-settings-section-D7zJ-hCO.js.br +0 -0
  200. package/dist/web/assets/ai-settings-section-D7zJ-hCO.js.gz +0 -0
  201. package/dist/web/assets/appearance-settings-section-DL466x83.js.br +0 -0
  202. package/dist/web/assets/appearance-settings-section-DL466x83.js.gz +0 -0
  203. package/dist/web/assets/branch-review-tab-Dag86n_R.js.br +0 -0
  204. package/dist/web/assets/branch-review-tab-Dag86n_R.js.gz +0 -0
  205. package/dist/web/assets/chat-tab-CcYZLXls.js +0 -15
  206. package/dist/web/assets/chat-tab-CcYZLXls.js.br +0 -0
  207. package/dist/web/assets/chat-tab-CcYZLXls.js.gz +0 -0
  208. package/dist/web/assets/chat-tab-QFDhzzBZ.js.br +0 -0
  209. package/dist/web/assets/chat-tab-QFDhzzBZ.js.gz +0 -0
  210. package/dist/web/assets/code-editor-K-IN8VwJ.js.br +0 -0
  211. package/dist/web/assets/code-editor-K-IN8VwJ.js.gz +0 -0
  212. package/dist/web/assets/codex-sign-in-again-dialog-C8JvblLG.js +0 -1
  213. package/dist/web/assets/codex-sign-in-again-dialog-C8JvblLG.js.br +0 -0
  214. package/dist/web/assets/codex-sign-in-again-dialog-C8JvblLG.js.gz +0 -0
  215. package/dist/web/assets/conflict-editor-qMGJH0Bx.js.br +0 -0
  216. package/dist/web/assets/conflict-editor-qMGJH0Bx.js.gz +0 -0
  217. package/dist/web/assets/csv-preview-D2I742dl.js.br +0 -0
  218. package/dist/web/assets/csv-preview-D2I742dl.js.gz +0 -0
  219. package/dist/web/assets/database-viewer-Bz4LjgIa.js.br +0 -0
  220. package/dist/web/assets/database-viewer-Bz4LjgIa.js.gz +0 -0
  221. package/dist/web/assets/design-tab-C987MtMR.js.br +0 -0
  222. package/dist/web/assets/design-tab-C987MtMR.js.gz +0 -0
  223. package/dist/web/assets/designs-sidebar-panel-CapP1yXq.js.br +0 -0
  224. package/dist/web/assets/designs-sidebar-panel-CapP1yXq.js.gz +0 -0
  225. package/dist/web/assets/diff-viewer-CdXi7cZN.js.br +0 -0
  226. package/dist/web/assets/diff-viewer-CdXi7cZN.js.gz +0 -0
  227. package/dist/web/assets/editor-language-service-Zle_PZV8.js.br +0 -0
  228. package/dist/web/assets/editor-language-service-Zle_PZV8.js.gz +0 -0
  229. package/dist/web/assets/explorer-body-DHMQR1Rk.js.br +0 -0
  230. package/dist/web/assets/explorer-body-DHMQR1Rk.js.gz +0 -0
  231. package/dist/web/assets/explorer-window-content-Df40nQBk.js.br +0 -0
  232. package/dist/web/assets/explorer-window-content-Df40nQBk.js.gz +0 -0
  233. package/dist/web/assets/extension-manager-section-B2nZzJ2b.js.br +0 -0
  234. package/dist/web/assets/extension-manager-section-B2nZzJ2b.js.gz +0 -0
  235. package/dist/web/assets/extension-webview-BGoDxkdF.js.br +0 -0
  236. package/dist/web/assets/extension-webview-BGoDxkdF.js.gz +0 -0
  237. package/dist/web/assets/files-settings-section-DC3OzzOl.js.br +0 -0
  238. package/dist/web/assets/files-settings-section-DC3OzzOl.js.gz +0 -0
  239. package/dist/web/assets/general-settings-section-i41W43ER.js.br +0 -0
  240. package/dist/web/assets/general-settings-section-i41W43ER.js.gz +0 -0
  241. package/dist/web/assets/git-log-panel-DHzPIkJg.js.br +0 -0
  242. package/dist/web/assets/git-log-panel-DHzPIkJg.js.gz +0 -0
  243. package/dist/web/assets/glide-data-grid-Dj4vrDvj.js.br +0 -0
  244. package/dist/web/assets/glide-data-grid-Dj4vrDvj.js.gz +0 -0
  245. package/dist/web/assets/group-chat-tab-DfwZb-fI.js.br +0 -0
  246. package/dist/web/assets/group-chat-tab-DfwZb-fI.js.gz +0 -0
  247. package/dist/web/assets/index-DMA-So69.css.br +0 -0
  248. package/dist/web/assets/index-jG9mLs-J.js.br +0 -0
  249. package/dist/web/assets/index-jG9mLs-J.js.gz +0 -0
  250. package/dist/web/assets/keyboard-shortcuts-section-CxdGSNGr.js.br +0 -0
  251. package/dist/web/assets/keyboard-shortcuts-section-CxdGSNGr.js.gz +0 -0
  252. package/dist/web/assets/markdown-renderer-ok96IgnS.js.br +0 -0
  253. package/dist/web/assets/markdown-renderer-ok96IgnS.js.gz +0 -0
  254. package/dist/web/assets/mobile-explorer-sheet-Cc03LUKy.js.br +0 -0
  255. package/dist/web/assets/mobile-explorer-sheet-Cc03LUKy.js.gz +0 -0
  256. package/dist/web/assets/new-design-dialog-Drkjb_LI.js.br +0 -0
  257. package/dist/web/assets/new-design-dialog-Drkjb_LI.js.gz +0 -0
  258. package/dist/web/assets/ppmbot-settings-section-C8PFlvaq.js.br +0 -0
  259. package/dist/web/assets/ppmbot-settings-section-C8PFlvaq.js.gz +0 -0
  260. package/dist/web/assets/problems-panel-CFYO0Ro3.js.br +0 -0
  261. package/dist/web/assets/problems-panel-CFYO0Ro3.js.gz +0 -0
  262. package/dist/web/assets/process-table-BVeRguFg.js.br +0 -0
  263. package/dist/web/assets/process-table-BVeRguFg.js.gz +0 -0
  264. package/dist/web/assets/proxy-settings-section-BcHIEANE.js.br +0 -0
  265. package/dist/web/assets/proxy-settings-section-BcHIEANE.js.gz +0 -0
  266. package/dist/web/assets/remote-desktop-clipboard-notice-BGsp0edA.js.br +0 -0
  267. package/dist/web/assets/remote-desktop-clipboard-notice-BGsp0edA.js.gz +0 -0
  268. package/dist/web/assets/remote-desktop-mobile-sheet-DxkmF8qb.js.br +0 -0
  269. package/dist/web/assets/remote-desktop-mobile-sheet-DxkmF8qb.js.gz +0 -0
  270. package/dist/web/assets/remote-desktop-mobile-view-DMD0M9Jh.js.br +0 -0
  271. package/dist/web/assets/remote-desktop-mobile-view-DMD0M9Jh.js.gz +0 -0
  272. package/dist/web/assets/remote-desktop-readiness-gate-CsZCCRJI.js.br +0 -0
  273. package/dist/web/assets/remote-desktop-readiness-gate-CsZCCRJI.js.gz +0 -0
  274. package/dist/web/assets/remote-desktop-window-content-DrHw_vwY.js.br +0 -0
  275. package/dist/web/assets/remote-desktop-window-content-DrHw_vwY.js.gz +0 -0
  276. package/dist/web/assets/schedules-settings-section-Ci0O2Ng6.js.br +0 -0
  277. package/dist/web/assets/schedules-settings-section-Ci0O2Ng6.js.gz +0 -0
  278. package/dist/web/assets/settings-body-B6JGOIYb.js.br +0 -0
  279. package/dist/web/assets/settings-body-B6JGOIYb.js.gz +0 -0
  280. package/dist/web/assets/sql-query-editor-4iCGE4h2.js.br +0 -3
  281. package/dist/web/assets/sql-query-editor-4iCGE4h2.js.gz +0 -0
  282. package/dist/web/assets/sqlite-viewer-CK6DulYk.js.br +0 -0
  283. package/dist/web/assets/sqlite-viewer-CK6DulYk.js.gz +0 -0
  284. package/dist/web/assets/system-monitor-body-J9JtvAWV.js.br +0 -0
  285. package/dist/web/assets/system-monitor-body-J9JtvAWV.js.gz +0 -0
  286. package/dist/web/assets/tab-host-window-content-CWBaWKjA.js.br +0 -0
  287. package/dist/web/assets/tab-host-window-content-CWBaWKjA.js.gz +0 -0
  288. package/dist/web/assets/team-member-sheet-Br6mrxrw.js.br +0 -0
  289. package/dist/web/assets/team-member-sheet-Br6mrxrw.js.gz +0 -0
  290. package/dist/web/assets/team-member-window-content-CwCy7ZWf.js.br +0 -0
  291. package/dist/web/assets/team-member-window-content-CwCy7ZWf.js.gz +0 -0
  292. package/dist/web/assets/terminal-tab-BW14RpCb.js.br +0 -0
  293. package/dist/web/assets/terminal-tab-BW14RpCb.js.gz +0 -0
  294. package/dist/web/assets/tool-cards-CgOBEUnb.js.br +0 -0
  295. package/dist/web/assets/tool-cards-CgOBEUnb.js.gz +0 -0
  296. package/dist/web/assets/use-inline-blame-Bzjfru4n.js.br +0 -0
  297. package/dist/web/assets/use-inline-blame-Bzjfru4n.js.gz +0 -0
  298. package/dist/web/assets/use-lsp-hGdjL2hV.js.br +0 -0
  299. package/dist/web/assets/use-lsp-hGdjL2hV.js.gz +0 -0
  300. package/dist/web/assets/video-preview-P9T-ZVdN.js.br +0 -0
  301. package/dist/web/assets/video-preview-P9T-ZVdN.js.gz +0 -0
  302. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  303. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  304. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  305. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
@@ -84,9 +84,28 @@ export function parseCodexResetCredits(raw: unknown): ResetCredits | undefined {
84
84
  available: available.length,
85
85
  ...(typeof next?.expiresAt === "number" ? { nextExpiresAt: new Date(next.expiresAt * 1000).toISOString() } : {}),
86
86
  ...(typeof next?.title === "string" ? { title: next.title } : {}),
87
+ ...(typeof next?.id === "string" ? { nextCreditId: next.id } : {}),
87
88
  };
88
89
  }
89
90
 
91
+ /**
92
+ * Whether a limit has actually been reached — at 100% of a window, as the card rounds it.
93
+ *
94
+ * The one rule both the "Use reset" button and the server's refusal follow, so the button can
95
+ * never offer what the server would turn down. Reached, not approaching: spending a reset at
96
+ * 90% throws away the 10% left *and* moves the weekly reset date (OpenAI: the next weekly reset
97
+ * is counted from when you continue, and the original one is not also granted).
98
+ */
99
+ export function usageLimitReached(u: { session?: { utilization: number }; weekly?: { utilization: number } }): boolean {
100
+ const atCap = (util?: number) => Math.round((util ?? 0) * 100) >= 100;
101
+ return atCap(u.session?.utilization) || atCap(u.weekly?.utilization);
102
+ }
103
+
104
+ /** A reset may be offered: a limit is reached and a credit is left to spend on it. */
105
+ export function canUseResetCredit(u: { session?: { utilization: number }; weekly?: { utilization: number }; resetCredits?: ResetCredits }): boolean {
106
+ return usageLimitReached(u) && (u.resetCredits?.available ?? 0) > 0;
107
+ }
108
+
90
109
  /** The extra fields of a `UsageInfo`, as the JSON column holds them — null when there are none. */
91
110
  export function serializeUsageExtra(u: { weeklyScoped?: ScopedLimitBucket[]; resetCredits?: ResetCredits }): string | null {
92
111
  const extra: UsageExtra = {};
package/src/types/chat.ts CHANGED
@@ -230,6 +230,8 @@ export interface ResetCredits {
230
230
  nextExpiresAt?: string;
231
231
  /** What the soonest one resets, as Codex words it ("Full reset (Weekly + 5 hr)"). */
232
232
  title?: string;
233
+ /** Codex's opaque id of that soonest-expiring credit — the one "Use reset" spends. */
234
+ nextCreditId?: string;
233
235
  }
234
236
 
235
237
  /** Result subtype from SDK ResultMessage */
@@ -27,6 +27,7 @@ import { UsagePanelShell } from "./usage-panel-shell";
27
27
 
28
28
  import { CODEX_SIGNED_OUT_HINT, type CodexAccount } from "@/components/settings/accounts/use-codex-accounts";
29
29
  import { CodexSignInAgainDialog } from "@/components/settings/accounts/codex-sign-in-again-dialog";
30
+ import { CodexResetCreditButton } from "@/components/settings/accounts/codex-reset-credit-button";
30
31
  type Usage = Pick<UsageInfo, "fiveHour" | "sevenDay" | "session" | "weekly" | "resetCredits">;
31
32
 
32
33
  /** Matches the whole-percent figure the bars show, so a refusal agrees with the card. */
@@ -212,6 +213,9 @@ export function CodexUsagePanel({ onClose, usage, onReload, onSelectAccount, sel
212
213
  dailyGuardToggling={togglingId === a.id}
213
214
  reauthHint={a.signedOut ? CODEX_SIGNED_OUT_HINT : undefined}
214
215
  resetCredits={u.resetCredits}
216
+ resetCreditAction={
217
+ <CodexResetCreditButton account={a} usage={u} onDone={(m) => { setPanelError(m); void reload(); }} />
218
+ }
215
219
  // Only a ChatGPT sign-in can be renewed in place; a dead API key is replaced.
216
220
  onReauth={a.type === "chatgpt" ? () => setSignInAgain(a) : undefined}
217
221
  />
@@ -27,6 +27,7 @@ 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
29
  import type { DailyGuardState } from "../../../../shared/codex-daily-guard.ts";
30
+ import type { ReactNode } from "react";
30
31
  import type { ResetCredits } from "../../../../types/chat";
31
32
  import { ResetCreditsChip, ScopedBucketRows } from "./account-usage-extras";
32
33
 
@@ -73,6 +74,8 @@ export interface AccountCardProps {
73
74
  onReauth?: (id: string) => void;
74
75
  /** Codex's free rate-limit resets for this account, shown in the footer. */
75
76
  resetCredits?: ResetCredits;
77
+ /** Control beside the reset count — Codex's "Use reset", which renders only at a limit. */
78
+ resetCreditAction?: ReactNode;
76
79
  }
77
80
 
78
81
  // Fixed widths so a row scrolls instead of squeezing. Two of them: a read-only card holds a
@@ -83,7 +86,7 @@ const STRIP_WIDTH = { readOnly: "min-w-[220px]", withActions: "min-w-[300px]" }
83
86
  export function AccountCard({
84
87
  entry, isActive, accountInfo, onToggle, toggling, onDelete, onExport, onViewProfile, flash,
85
88
  onSelect, unselectableReason, selecting, planLabel, dailyGuard, onDailyGuardToggle, dailyGuardToggling,
86
- reauthHint, onReauth, resetCredits, layout = "list",
89
+ reauthHint, onReauth, resetCredits, resetCreditAction, layout = "list",
87
90
  }: AccountCardProps) {
88
91
  const { usage } = entry;
89
92
  const hasBuckets = usage.session || usage.weekly || usage.weeklyOpus || usage.weeklySonnet || usage.weeklyScoped?.length;
@@ -318,6 +321,7 @@ export function AccountCard({
318
321
 
319
322
  <div className="flex items-center gap-2 text-[10px] text-text-subtle flex-wrap">
320
323
  <ResetCreditsChip credits={resetCredits} />
324
+ {resetCreditAction}
321
325
  {usage.lastFetchedAt && (
322
326
  <AccountHint
323
327
  className="inline-flex items-center gap-1"
@@ -5,7 +5,8 @@
5
5
  * - `ScopedBucketRows` — a model's own weekly limit (Claude's "Fable"), one bar per model,
6
6
  * labelled with the name the provider gives it.
7
7
  * - `ResetCreditsChip` — how many free rate-limit resets Codex has granted the account and
8
- * when the next one lapses. PPM only reports these; they are spent from Codex itself.
8
+ * when the next one lapses. Spending one is `CodexResetCreditButton`, shown beside it only
9
+ * once a limit is reached.
9
10
  */
10
11
 
11
12
  import { RotateCcw } from "@/lib/icons";
@@ -32,7 +33,7 @@ export function ResetCreditsChip({ credits }: { credits?: ResetCredits }) {
32
33
  : `Codex has granted this account ${n} free rate-limit reset${n === 1 ? "" : "s"}`
33
34
  + `${credits.title ? ` (${credits.title})` : ""}.`
34
35
  + `${credits.nextExpiresAt ? ` The next one expires on ${new Date(credits.nextExpiresAt).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" })}.` : ""}`
35
- + " Use one from the Codex app when a limit is reached — PPM only shows the count.";
36
+ + " A \"Use reset\" button appears here once a limit is reached; a reset moves the weekly reset date, so spending one earlier wastes it.";
36
37
  return (
37
38
  <AccountHint className={`inline-flex items-center gap-1 ${n > 0 ? "text-primary" : ""}`} hint={hint}>
38
39
  <RotateCcw className="size-3 shrink-0" aria-hidden />
@@ -28,6 +28,7 @@ import { CodexUsageRows } from "./codex-usage-rows";
28
28
  import { CODEX_SIGNED_OUT_HINT, useCodexAccounts, type CodexAccount } from "./use-codex-accounts";
29
29
  import { CodexSignInAgainDialog } from "./codex-sign-in-again-dialog";
30
30
  import { ResetCreditsChip } from "./account-usage-extras";
31
+ import { CodexResetCreditButton } from "./codex-reset-credit-button";
31
32
  import { AccountHint } from "./account-hint";
32
33
  import { codexPlanLabel } from "../../../../shared/codex-plan-label.ts";
33
34
  import { dailyGuardState } from "../../../../shared/codex-daily-guard.ts";
@@ -137,8 +138,9 @@ export function CodexAccountsSection() {
137
138
  </div>
138
139
  <CodexUsageRows usage={u} />
139
140
  {u.resetCredits && (
140
- <div className="text-[10px] text-text-subtle">
141
+ <div className="flex items-center gap-2 flex-wrap text-[10px] text-text-subtle">
141
142
  <ResetCreditsChip credits={u.resetCredits} />
143
+ <CodexResetCreditButton account={a} usage={u} onDone={(m) => { c.setMsg(m); void c.load(); }} />
142
144
  </div>
143
145
  )}
144
146
  {u.session == null && (() => {
@@ -0,0 +1,120 @@
1
+ /**
2
+ * "Use reset": spend one of Codex's free rate-limit resets on an account — offered only once a
3
+ * limit is actually reached.
4
+ *
5
+ * Rendered nothing at all otherwise, on purpose: a reset is one-use, it moves the weekly reset
6
+ * date (the next weekly reset is counted from when you continue; the original one is not also
7
+ * granted), and spent early it throws away whatever was left of the window. The server applies
8
+ * the same rule (`usageLimitReached`) against a live read, so a stale card cannot slip past it.
9
+ *
10
+ * The confirmation says exactly that before anything is spent. Bottom sheet below `md`,
11
+ * centred dialog above, like every other confirmation in the accounts pane.
12
+ */
13
+
14
+ import { useState } from "react";
15
+ import { Loader2, RotateCcw } from "@/lib/icons";
16
+ import { api } from "@/lib/api-client";
17
+ import { Button } from "@/components/ui/button";
18
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
19
+ import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
20
+ import { useIsMobile } from "@/hooks/use-is-mobile";
21
+ import { canUseResetCredit } from "../../../../shared/usage-extra.ts";
22
+ import type { LimitBucket, ResetCredits } from "../../../../types/chat";
23
+
24
+ type Outcome = "reset" | "nothingToReset" | "noCredit" | "alreadyRedeemed";
25
+
26
+ const OUTCOME_MESSAGE: Record<Outcome, (label: string) => string> = {
27
+ reset: (l) => `${l}: limits reset to 0%. The weekly reset date now counts from your next use.`,
28
+ nothingToReset: (l) => `${l}: nothing needed resetting, so the reset was kept.`,
29
+ noCredit: (l) => `${l} has no free reset left.`,
30
+ alreadyRedeemed: (l) => `${l}: that reset had already been used.`,
31
+ };
32
+
33
+ function when(iso?: string): string | null {
34
+ return iso ? new Date(iso).toLocaleString(undefined, { dateStyle: "medium", timeStyle: "short" }) : null;
35
+ }
36
+
37
+ export function CodexResetCreditButton({ account, usage, onDone }: {
38
+ account: { id: string; label: string };
39
+ usage: { session?: LimitBucket; weekly?: LimitBucket; resetCredits?: ResetCredits };
40
+ /** Called after an attempt, with a message saying what happened (or why it was refused). */
41
+ onDone: (message: string) => void;
42
+ }) {
43
+ const isMobile = useIsMobile();
44
+ const [confirming, setConfirming] = useState(false);
45
+ const [busy, setBusy] = useState(false);
46
+
47
+ if (!canUseResetCredit(usage)) return null;
48
+ const credits = usage.resetCredits!;
49
+
50
+ async function spend() {
51
+ setBusy(true);
52
+ try {
53
+ const r = await api.post<{ outcome: Outcome }>(`/api/codex-accounts/${account.id}/reset-credit`);
54
+ onDone(OUTCOME_MESSAGE[r.outcome]?.(account.label) ?? `${account.label}: ${r.outcome}`);
55
+ } catch (e) {
56
+ onDone((e as Error).message || "Could not use the reset");
57
+ } finally {
58
+ setBusy(false);
59
+ setConfirming(false);
60
+ }
61
+ }
62
+
63
+ const weeklyNow = when(usage.weekly?.resetsAt);
64
+ const expires = when(credits.nextExpiresAt);
65
+ const body = (
66
+ <div className="space-y-3" data-testid="codex-reset-credit-confirm">
67
+ <p className="text-sm">
68
+ Use 1 of <span className="font-medium">{account.label}</span>'s {credits.available} free reset{credits.available === 1 ? "" : "s"}?
69
+ </p>
70
+ <ul className="text-xs text-text-secondary space-y-1.5 list-disc pl-4">
71
+ <li>{credits.title ?? "Full reset"}: the 5-hour and weekly usage go back to 0% now.</li>
72
+ <li>
73
+ The weekly reset date moves: the next one is about 7 days after you continue using Codex
74
+ {weeklyNow ? `, not ${weeklyNow} as now` : ""}. You do not also get that one.
75
+ </li>
76
+ {expires && <li>This spends the reset that expires first ({expires}).</li>}
77
+ </ul>
78
+ <div className="flex flex-col-reverse md:flex-row gap-2 md:justify-end pt-1">
79
+ <Button variant="outline" onClick={() => setConfirming(false)} disabled={busy} className="min-h-11">
80
+ Keep it
81
+ </Button>
82
+ <Button onClick={() => void spend()} disabled={busy} className="min-h-11 gap-1.5">
83
+ {busy ? <Loader2 className="size-4 animate-spin" /> : <RotateCcw className="size-4" />}
84
+ Use reset
85
+ </Button>
86
+ </div>
87
+ </div>
88
+ );
89
+
90
+ return (
91
+ <>
92
+ <Button
93
+ size="sm"
94
+ variant="outline"
95
+ className="min-h-11 md:min-h-0 md:h-7 gap-1 px-2 text-[11px] cursor-pointer border-primary/40 text-primary"
96
+ onClick={() => setConfirming(true)}
97
+ disabled={busy}
98
+ >
99
+ <RotateCcw className="size-3.5" /> Use reset
100
+ </Button>
101
+ {confirming && (isMobile ? (
102
+ <BottomSheet open onClose={() => { if (!busy) setConfirming(false); }}>
103
+ <div className="px-4 pb-4">
104
+ <h2 className="text-base font-semibold mb-3">Use a free reset</h2>
105
+ {body}
106
+ </div>
107
+ </BottomSheet>
108
+ ) : (
109
+ <Dialog open onOpenChange={(v) => { if (!v && !busy) setConfirming(false); }}>
110
+ <DialogContent className="sm:max-w-sm">
111
+ <DialogHeader>
112
+ <DialogTitle className="text-sm">Use a free reset</DialogTitle>
113
+ </DialogHeader>
114
+ {body}
115
+ </DialogContent>
116
+ </Dialog>
117
+ ))}
118
+ </>
119
+ );
120
+ }
@@ -1 +0,0 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{C as t,S as n}from"./vendor-markdown-QKPNiWEd.js";import"./vendor-ui-BHh12_0v.js";import{Jr as r,Lr as i,Mr as a,St as o,V as s,Zn as c,Zt as l,fn as u,fr as d,nt as f,st as p,un as m}from"./icons-CO_II6D-.js";import{r as h}from"./api-client-c8YOpTlT.js";import{n as g}from"./utils-btZ8C8-R.js";import"./portal-container-context-NFSuymMu.js";import"./chat-preparation-cache-BSIQGiWx.js";import{n as _}from"./use-is-mobile-BClDZJP5.js";import{n as v,t as y}from"./button-Ci9EUgqd.js";import{a as b,i as x,n as S,o as C,r as w,t as T}from"./dialog-B8clVkyi.js";import{t as E}from"./mobile-bottom-sheet-CuNi2FRv.js";import"./use-visual-viewport-BGpcMnIx.js";import{t as D}from"./input-CG8PS8mS.js";import{$n as O,Qn as k,Rn as A,Sn as j,Zn as M,bt as N,ct as P,dt as F,ft as I,lt as L,st as ee,ut as te}from"./index-jG9mLs-J.js";import{_ as ne,a as re,h as ie,m as ae,o as oe,p as se,r as ce,v as le,x as R,y as ue}from"./api-settings-BmvNoCbn.js";import{a as de,b as z,c as fe,f as B,g as pe,h as V,i as me,l as he,m as H,n as ge,o as U,p as _e,s as ve,t as ye,u as be,v as W,y as xe}from"./codex-sign-in-again-dialog-C8JvblLG.js";var G=e(t(),1),K=n(),q=[`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`,`Sun`],J=Array.from({length:24},(e,t)=>t);function Se(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 Ce(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 we(e){return J.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 Y(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 Te(e){return e<.3?`bg-success`:e<.7?`bg-warning`:`bg-error`}function Ee({accountId:e}){let[t,n]=(0,G.useState)(null),[r,i]=(0,G.useState)(!0),[a,o]=(0,G.useState)(`5h`);(0,G.useEffect)(()=>{i(!0),se(e).then(n).catch(()=>n([])).finally(()=>i(!1))},[e]);let s=(0,G.useMemo)(()=>t?Se(t,a):null,[t,a]),c=(0,G.useMemo)(()=>s?Ce(s):[],[s]),l=(0,G.useMemo)(()=>s?we(s):[],[s]),u=Math.max(...c,.01);if(Math.max(...l,.01),r)return(0,K.jsx)(`div`,{className:`flex items-center justify-center py-3`,children:(0,K.jsx)(m,{className:`size-3 animate-spin text-text-subtle`})});if(!t||t.length===0)return(0,K.jsx)(`div`,{className:`text-[10px] text-text-subtle py-2 text-center`,children:`No usage history yet`});let d=t.length,f=new Set(t.map(e=>new Date(e.recorded_at+(e.recorded_at.endsWith(`Z`)?``:`Z`)).toDateString())).size;return(0,K.jsxs)(`div`,{className:`mt-2 space-y-2`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`span`,{className:`text-[10px] font-medium text-text-subtle`,children:`Usage Pattern (7d)`}),(0,K.jsxs)(`div`,{className:`flex gap-0.5 text-[9px]`,children:[(0,K.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,K.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,K.jsxs)(`p`,{className:`text-[9px] text-text-subtle leading-tight`,children:[`Avg `,a===`5h`?`5-hour`:`weekly`,` limit usage over `,f,`d (`,d,` samples). Higher % = closer to rate limit. Hover cells for details.`]}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by day of week`}),(0,K.jsx)(`div`,{className:`flex flex-col gap-[2px] mt-0.5`,children:q.map((e,t)=>{let n=c[t]??0;return(0,K.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,K.jsx)(`span`,{className:`text-[8px] text-text-subtle w-5 shrink-0 text-right tabular-nums`,children:e}),(0,K.jsx)(`div`,{className:`flex-1 h-2.5 bg-surface-elevated rounded-sm overflow-hidden`,children:(0,K.jsx)(`div`,{className:`h-full rounded-sm transition-all ${Te(n)}`,style:{width:`${Math.round(n/u*100)}%`}})}),(0,K.jsxs)(`span`,{className:`text-[8px] text-text-subtle w-6 shrink-0 text-right tabular-nums`,children:[Math.round(n*100),`%`]})]},e)})})]}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Avg usage by hour (0h-23h)`}),(0,K.jsx)(`div`,{className:`flex gap-[1px] mt-0.5`,children:J.map(e=>{let t=l[e]??0;return(0,K.jsxs)(`div`,{className:`flex-1 flex flex-col items-center gap-[1px]`,children:[(0,K.jsx)(`div`,{className:`w-full aspect-square rounded-[2px] ${Y(t)}`,title:`${e}:00 — avg ${Math.round(t*100)}% usage`}),e%6==0&&(0,K.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})]},e)})})]}),s&&(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`span`,{className:`text-[9px] text-text-subtle`,children:`Day x Hour heatmap`}),(0,K.jsxs)(`div`,{className:`flex flex-col gap-[1px] mt-0.5`,children:[q.map((e,t)=>(0,K.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,K.jsx)(`span`,{className:`text-[7px] text-text-subtle w-4 shrink-0 text-right`,children:e.charAt(0)}),J.map(n=>{let r=s[t][n];return(0,K.jsx)(`div`,{className:`flex-1 aspect-square rounded-[1px] ${Y(r.avg)}`,title:`${e} ${n}:00 — ${r.count>0?`avg ${Math.round(r.avg*100)}% (${r.count} samples)`:`no data`}`},n)})]},e)),(0,K.jsxs)(`div`,{className:`flex items-center gap-[1px]`,children:[(0,K.jsx)(`span`,{className:`w-4 shrink-0`}),J.map(e=>(0,K.jsx)(`div`,{className:`flex-1 text-center`,children:e%6==0&&(0,K.jsx)(`span`,{className:`text-[7px] text-text-subtle tabular-nums`,children:e})},e))]})]})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[8px] text-text-subtle`,children:[(0,K.jsx)(`span`,{children:`Low`}),(0,K.jsxs)(`div`,{className:`flex gap-[2px]`,children:[(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/30`}),(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-success/60`}),(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/50`}),(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-warning/80`}),(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-error/80`})]}),(0,K.jsx)(`span`,{children:`High`}),(0,K.jsx)(`span`,{className:`ml-1`,children:`|`}),(0,K.jsx)(`div`,{className:`size-2 rounded-[1px] bg-surface-elevated border border-border/30`}),(0,K.jsx)(`span`,{children:`No data`})]})]})}function De({profile:e,accountId:t,onClose:n}){let i=[[`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,K.jsxs)(`section`,{className:`space-y-2 border-t border-border pt-3`,"data-testid":`account-profile-panel`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`h3`,{className:`text-sm font-medium`,children:`Profile`}),(0,K.jsx)(`button`,{className:`p-2 text-muted-foreground hover:text-foreground cursor-pointer`,onClick:n,"aria-label":`Close profile`,children:(0,K.jsx)(r,{className:`size-4`})})]}),(0,K.jsx)(`div`,{className:`grid grid-cols-[80px_1fr] gap-x-3 gap-y-1 text-xs`,children:i.map(([e,t])=>t?(0,K.jsxs)(`span`,{className:`contents`,children:[(0,K.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,K.jsx)(`span`,{className:`break-all`,children:t})]},e):null)}),(0,K.jsx)(Ee,{accountId:t})]})}function Oe({display:e,onConfirm:t,onCancel:n}){let r=_(),i=(0,K.jsxs)(`div`,{className:`space-y-4`,"data-testid":`account-delete-confirm`,children:[(0,K.jsxs)(`p`,{className:`text-sm`,children:[`Remove `,(0,K.jsx)(`span`,{className:`font-medium`,children:e}),`?`]}),(0,K.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,K.jsxs)(`div`,{className:`flex flex-col-reverse md:flex-row gap-2 md:justify-end pt-2`,children:[(0,K.jsx)(y,{variant:`outline`,onClick:n,className:`min-h-11`,children:`Cancel`}),(0,K.jsx)(y,{variant:`destructive`,autoFocus:!1,onClick:t,className:`min-h-11`,children:`Remove account`})]})]});return r?(0,K.jsx)(E,{open:!0,onClose:n,children:(0,K.jsxs)(`div`,{className:`px-4 pb-4`,children:[(0,K.jsx)(`h2`,{className:`text-base font-semibold mb-3`,children:`Remove account`}),i]})}):(0,K.jsx)(T,{open:!0,onOpenChange:e=>{e||n()},children:(0,K.jsxs)(S,{className:`sm:max-w-sm`,children:[(0,K.jsx)(b,{children:(0,K.jsx)(C,{className:`text-sm`,children:`Remove account`})}),i]})})}function ke(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 Ae({open:e,onOpenChange:t,accounts:n,preselectId:r,onMessage:i}){let a=n.filter(e=>e.hasRefreshToken),[o,s]=(0,G.useState)(new Set),[c,l]=(0,G.useState)(``),[d,g]=(0,G.useState)(!1),[_,v]=(0,G.useState)(!1),[E,O]=(0,G.useState)(!1),[k,A]=(0,G.useState)(!1);e&&!k&&(s(r?new Set([r]):new Set(a.map(e=>e.id))),A(!0)),!e&&k&&A(!1);function M(){t(!1),l(``),g(!1),v(!1)}async function P(e){if(o.size===0)return;O(!0);let t=c.trim()||`ppm-hienlh`;try{let n={"Content-Type":`application/json`},r=h();r&&(n.Authorization=`Bearer ${r}`);let a=await fetch(`/api/accounts/export`,{method:`POST`,headers:n,body:JSON.stringify({password:t,accountIds:[...o],includeRefreshToken:d,refreshBeforeExport:_})});if(!a.ok){let e=await a.json();throw Error(e.error??`Export failed: ${a.status}`)}let s=await a.text();e&&await j(s)?i?.(`Backup copied to clipboard!`):(ke(s),i?.(`Backup downloaded.`)),M()}catch{}O(!1)}let F=o.size>0&&!E;return(0,K.jsx)(T,{open:e,onOpenChange:e=>{e||M()},children:(0,K.jsxs)(S,{className:`sm:max-w-md`,children:[(0,K.jsxs)(b,{children:[(0,K.jsxs)(C,{className:`text-sm flex items-center gap-1.5`,children:[(0,K.jsx)(u,{className:`size-3.5`}),` Export Accounts`]}),(0,K.jsx)(w,{className:`text-xs`,children:`Select accounts and set a password to protect the backup.`})]}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between mb-1`,children:[(0,K.jsx)(`p`,{className:`text-[11px] font-medium text-muted-foreground`,children:`Accounts to export`}),(0,K.jsx)(`button`,{className:`text-[10px] text-primary hover:underline cursor-pointer`,onClick:()=>s(o.size===a.length?new Set:new Set(a.map(e=>e.id))),children:o.size===a.length?`Deselect all`:`Select all`})]}),a.length===0?(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground p-2 border rounded`,children:`No exportable accounts.`}):(0,K.jsx)(`div`,{className:`max-h-36 overflow-y-auto space-y-1 border rounded p-2`,children:a.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`input`,{type:`checkbox`,id:`exp-${e.id}`,checked:o.has(e.id),onChange:t=>{let n=new Set(o);t.target.checked?n.add(e.id):n.delete(e.id),s(n)},className:`size-3.5 accent-primary cursor-pointer`}),(0,K.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,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsxs)(N,{className:`text-xs`,children:[`Password `,(0,K.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,K.jsx)(D,{type:`password`,placeholder:`Leave empty for default`,value:c,onChange:e=>l(e.target.value),className:`text-xs h-8`,autoComplete:`new-password`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`input`,{type:`checkbox`,id:`exp-full`,checked:d,onChange:e=>g(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,K.jsx)(`label`,{htmlFor:`exp-full`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens (full transfer)`})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`input`,{type:`checkbox`,id:`exp-refresh`,checked:_,onChange:e=>v(e.target.checked),className:`size-3.5 accent-primary cursor-pointer`}),(0,K.jsx)(`label`,{htmlFor:`exp-refresh`,className:`text-[11px] cursor-pointer`,children:`Refresh tokens before export`})]}),d?(0,K.jsxs)(`div`,{className:`rounded-md border border-error/30 bg-error/5 p-2.5`,children:[(0,K.jsx)(`p`,{className:`text-[10px] font-medium text-error`,children:`Full transfer — source accounts will expire`}),(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Refresh tokens included. Source machine expires in ~1h after target refreshes.`})]}):_?(0,K.jsx)(`div`,{className:`rounded-md border border-warning/30 bg-warning/5 p-2.5`,children:(0,K.jsx)(`p`,{className:`text-[10px] font-medium text-warning`,children:`Refresh before export — invalidates previous shares`})}):(0,K.jsx)(`div`,{className:`rounded-md border border-success/30 bg-success/5 p-2.5`,children:(0,K.jsx)(`p`,{className:`text-[10px] font-medium text-success`,children:`Share current token (safe)`})}),(0,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`Encrypted with AES-256-GCM + scrypt.`})]}),(0,K.jsxs)(x,{className:`gap-1.5 flex-col sm:flex-row`,children:[(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:M,children:`Cancel`}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,disabled:!F,onClick:()=>P(!0),children:[(0,K.jsx)(f,{className:`size-3 mr-1`}),` Copy`]}),(0,K.jsx)(y,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!F,onClick:()=>P(!1),children:E?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(m,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(p,{className:`size-3 mr-1`}),` Download`]})})]})]})})}function je({open:e,onOpenChange:t,onSuccess:n}){let[r,i]=(0,G.useState)(``),[a,o]=(0,G.useState)(``),[s,c]=(0,G.useState)(!1),[l,d]=(0,G.useState)(null);function f(){t(!1),i(``),o(``),d(null)}async function p(){if(r.trim()){c(!0),d(null);try{let e=await ae({data:r.trim(),password:a.trim()||`ppm-hienlh`});f(),n(`Imported ${e.imported} account(s)`)}catch(e){d(e.message||`Import failed`)}c(!1)}}return(0,K.jsx)(T,{open:e,onOpenChange:e=>{e||f()},children:(0,K.jsxs)(S,{className:`sm:max-w-md`,children:[(0,K.jsxs)(b,{children:[(0,K.jsxs)(C,{className:`text-sm flex items-center gap-1.5`,children:[(0,K.jsx)(u,{className:`size-3.5`}),` Import Accounts`]}),(0,K.jsx)(w,{className:`text-xs`,children:`Paste backup data and enter the export password. Imported accounts are temporary (~1h).`})]}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsx)(N,{className:`text-xs`,children:`Backup data`}),(0,K.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,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsxs)(N,{className:`text-xs`,children:[`Password `,(0,K.jsx)(`span`,{className:`text-muted-foreground font-normal`,children:`(optional)`})]}),(0,K.jsx)(D,{type:`password`,placeholder:`Leave empty for default`,value:a,onChange:e=>o(e.target.value),className:`text-xs h-8`,autoComplete:`current-password`})]})]}),l&&(0,K.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:l}),(0,K.jsxs)(x,{children:[(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`text-xs h-7 cursor-pointer`,onClick:f,children:`Cancel`}),(0,K.jsx)(y,{size:`sm`,className:`text-xs h-7 cursor-pointer`,disabled:!r.trim()||s,onClick:p,children:s?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(m,{className:`size-3 animate-spin mr-1`}),` Importing...`]}):`Import`})]})]})})}var X=typeof window<`u`?window.matchMedia(`(min-width: 768px)`):null;function Me(e){return X?.addEventListener(`change`,e),()=>X?.removeEventListener(`change`,e)}function Ne(){return X?.matches??!0}function Z(){let[e,t]=(0,G.useState)(null),[n,r]=(0,G.useState)(!0);return(0,G.useEffect)(()=>{r(!0),oe().then(t).finally(()=>r(!1))},[]),n?(0,K.jsx)(`p`,{className:`text-xs text-text-subtle py-4 text-center`,children:`Loading...`}):e?(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Rotation Strategy`}),(0,K.jsxs)(ee,{value:e.strategy,onValueChange:async e=>{t(await R({strategy:e}))},children:[(0,K.jsx)(te,{className:`w-full h-9 text-xs`,children:(0,K.jsx)(F,{})}),(0,K.jsxs)(P,{children:[(0,K.jsx)(L,{value:`round-robin`,children:`Round-robin`}),(0,K.jsx)(L,{value:`fill-first`,children:`Fill-first`}),(0,K.jsx)(L,{value:`lowest-usage`,children:`Lowest usage`})]})]}),(0,K.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,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Max Retry`}),(0,K.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 R({maxRetry:n}))}}),(0,K.jsx)(`p`,{className:`text-[10px] text-text-subtle`,children:`How many accounts to try on failure. 0 = try all available accounts.`})]}),(0,K.jsxs)(`div`,{className:`space-y-1.5 border-t border-border pt-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`label`,{className:`text-xs font-medium text-text-primary`,children:`Cooldown parking`}),(0,K.jsx)(I,{checked:e.cooldownEnabled,onCheckedChange:async e=>{t(await R({cooldownEnabled:e}))}})]}),(0,K.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,K.jsxs)(`div`,{className:`flex items-center justify-between text-xs border-t border-border pt-3`,children:[(0,K.jsx)(`span`,{className:`text-text-subtle`,children:`Active accounts`}),(0,K.jsx)(`span`,{className:`font-medium text-text-primary`,children:e.activeCount})]})]}):(0,K.jsx)(`p`,{className:`text-xs text-text-subtle py-4 text-center`,children:`Failed to load settings`})}function Pe({open:e,onOpenChange:t}){let n=(0,G.useSyncExternalStore)(Me,Ne);return e?n?(0,K.jsx)(T,{open:e,onOpenChange:t,children:(0,K.jsxs)(S,{className:`sm:max-w-sm`,children:[(0,K.jsx)(b,{children:(0,K.jsxs)(C,{className:`text-sm flex items-center gap-2`,children:[(0,K.jsx)(d,{className:`size-4`}),` Rotation & Retry`]})}),(0,K.jsx)(Z,{})]})}):(0,K.jsxs)(K.Fragment,{children:[(0,K.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,K.jsxs)(`div`,{className:g(`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,K.jsx)(`div`,{className:`flex justify-center pt-3 pb-1`,children:(0,K.jsx)(`div`,{className:`w-10 h-1 rounded-full bg-border`})}),(0,K.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-2 border-b border-border`,children:[(0,K.jsxs)(`span`,{className:`text-sm font-semibold flex items-center gap-2`,children:[(0,K.jsx)(d,{className:`size-4`}),` Rotation & Retry`]}),(0,K.jsx)(`button`,{onClick:()=>t(!1),className:`flex items-center justify-center size-7 rounded-md hover:bg-surface-elevated transition-colors`,children:(0,K.jsx)(r,{className:`size-4`})})]}),(0,K.jsx)(`div`,{className:`px-4 py-4 pb-8`,children:(0,K.jsx)(Z,{})})]})]}):null}var Fe=v(`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 Q({className:e,variant:t,...n}){return(0,K.jsx)(`div`,{className:g(Fe({variant:t}),e),...n})}function Ie(e){let t=Math.floor(Date.now()/1e3);return e>t?`${Math.floor((e-t)/60)}m`:`exp`}function Le({accounts:e}){let[t,n]=(0,G.useState)([]),[r,i]=(0,G.useState)(!1),[a,o]=(0,G.useState)(!1),[s,c]=(0,G.useState)(new Map),l=e.filter(e=>e.hasRefreshToken);async function u(){if(l.length!==0){i(!0);try{let e=await le(l.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 d(e,t){c(t=>new Map(t).set(e,{loading:!0}));try{let n=await ue(t);c(t=>new Map(t).set(e,{loading:!1,...n}))}catch(t){c(n=>new Map(n).set(e,{loading:!1,status:`error`,error:t.message}))}}function f(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 p(){for(let e of t)for(let t of e.items)for(let n of f(e,t))n.token&&d(n.key,n.token)}return(0,K.jsxs)(`section`,{className:`border-t pt-4 space-y-2`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,K.jsx)(`p`,{className:`text-xs font-medium`,children:`Simulate export`}),t.length>0&&(0,K.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[t.length,` round(s)`]})]}),(0,K.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.`}),l.length===0?(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No OAuth account with a refresh token to export.`}):(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,K.jsx)(I,{id:`sim-include-refresh`,checked:a,onCheckedChange:o,className:`cursor-pointer`}),(0,K.jsx)(N,{htmlFor:`sim-include-refresh`,className:`text-[11px] cursor-pointer`,children:`Include refresh tokens`})]}),(0,K.jsx)(y,{size:`sm`,className:`h-7 text-xs cursor-pointer`,disabled:r,onClick:()=>void u(),children:r?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(m,{className:`size-3 animate-spin mr-1`}),` Exporting...`]}):`Run export #${t.length+1}`})]}),t.length>0&&(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`w-full h-7 text-[11px] cursor-pointer`,onClick:p,children:[`Test all tokens (`,t.reduce((e,t)=>e+t.items.length*3,0),`)`]}),t.map(e=>(0,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsxs)(`p`,{className:`text-xs font-medium text-primary`,children:[`Round #`,e.round]}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:e.time}),(0,K.jsx)(Q,{variant:e.includeRefresh?`destructive`:`secondary`,className:`text-[9px] px-1 py-0`,children:e.includeRefresh?`with refresh`:`access only`})]}),e.items.map(t=>(0,K.jsxs)(`div`,{className:`p-2 rounded-lg border bg-card space-y-1.5`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`span`,{className:`text-[11px] font-medium`,children:t.label??t.email??t.id.slice(0,8)}),t.tokenChanged&&(0,K.jsx)(Q,{variant:`secondary`,className:`text-[9px] px-1 py-0`,children:`DB token changed`})]}),f(e,t).map(e=>{let t=s.get(e.key);return(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[11px]`,children:[(0,K.jsx)(`span`,{className:`w-20 shrink-0 text-muted-foreground text-[10px]`,children:e.label}),(0,K.jsx)(`code`,{className:`flex-1 truncate font-mono text-[10px] bg-muted px-1 rounded`,children:e.preview??`N/A`}),e.expires&&(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground shrink-0`,children:Ie(e.expires)}),e.token?(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`h-6 text-[10px] px-1.5 cursor-pointer shrink-0`,disabled:t?.loading,onClick:()=>void d(e.key,e.token),children:t?.loading?(0,K.jsx)(m,{className:`size-3 animate-spin`}):`Test`}):(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:`-`}),t&&!t.loading&&(0,K.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 Re(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 ze({open:e,onOpenChange:t,accounts:n}){let[r,i]=(0,G.useState)(new Map),[a,s]=(0,G.useState)(!1);async function c(e){i(t=>new Map(t).set(e,{loading:!0}));try{let t=await ne(e,a);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 l(){for(let e of n.filter(e=>e.expiresAt!==null))c(e.id)}return(0,K.jsx)(T,{open:e,onOpenChange:t,children:(0,K.jsxs)(S,{className:`sm:max-w-xl max-h-[85vh] flex flex-col`,children:[(0,K.jsxs)(b,{children:[(0,K.jsxs)(C,{className:`text-sm flex items-center gap-1.5`,children:[(0,K.jsx)(o,{className:`size-4`}),` Token Test`]}),(0,K.jsx)(w,{className:`text-xs`,children:`Probe stored tokens for validity. Nothing is modified.`})]}),(0,K.jsxs)(`div`,{className:`space-y-4 overflow-y-auto flex-1 pr-1`,children:[(0,K.jsxs)(`section`,{className:`space-y-2`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,K.jsx)(`p`,{className:`text-xs font-medium`,children:`Current tokens`}),(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,K.jsx)(I,{id:`token-test-refresh`,checked:a,onCheckedChange:s,className:`cursor-pointer`}),(0,K.jsx)(N,{htmlFor:`token-test-refresh`,className:`text-[11px] cursor-pointer`,children:`Also test refresh`})]}),(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`h-7 text-xs cursor-pointer`,onClick:l,children:`Test all`})]})]}),n.length===0&&(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No accounts to test.`}),(0,K.jsx)(`div`,{className:`space-y-1.5`,children:n.map(e=>{let t=r.get(e.id),n=t?.result?.accessToken.status;return(0,K.jsxs)(`div`,{className:`p-2 rounded border bg-card space-y-1`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,K.jsx)(`span`,{className:`text-xs font-medium truncate block`,children:e.label??e.email??e.id.slice(0,8)}),e.expiresAt&&(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:Re(e.expiresAt)})]}),(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`h-7 text-xs cursor-pointer shrink-0`,disabled:t?.loading,onClick:()=>void c(e.id),children:t?.loading?(0,K.jsx)(m,{className:`size-3 animate-spin`}):`Test`})]}),t&&!t.loading&&(0,K.jsxs)(`div`,{className:`text-[11px] pl-2 border-l-2 border-muted`,children:[t.error&&(0,K.jsx)(`p`,{className:`text-error`,children:t.error}),n&&(0,K.jsxs)(`span`,{className:n.startsWith(`valid`)?`text-success`:`text-error`,children:[n,t.result?.accessToken.code?` (${t.result.accessToken.code})`:``]})]})]},e.id)})})]}),(0,K.jsx)(Le,{accounts:n})]}),(0,K.jsx)(x,{children:(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Close`})})]})})}function Be(){let{usages:e,accounts:t,activeAccountId:n,initialLoading:r,refreshing:a,flashIds:s,reload:u}=fe(),[f,h]=(0,G.useState)(null),[g,_]=(0,G.useState)(null),[v,b]=(0,G.useState)(null),[x,S]=(0,G.useState)(null),[C,w]=(0,G.useState)(null),[T,E]=(0,G.useState)(null),[D,O]=(0,G.useState)(void 0);function k(e){u(),e&&h(e)}async function A(e,t){_(e);try{await ie(e,{status:t===`disabled`?`active`:`disabled`})}catch(e){h(e.message)}_(null),u()}async function j(){if(v){try{await ce(v.id),h(`Account "${v.display}" removed.`),u()}catch(e){h(`Failed to remove: ${e.message}`)}b(null)}}let M=new Map(t.map(e=>[e.id,e])),N=e[0]?.usage.lastFetchedAt;return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(H,{description:`Connect multiple Claude accounts. PPM rotates between them automatically to avoid rate limits.`,onRefresh:()=>void u(),refreshing:a,disabled:r,actions:(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(y,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>{O(void 0),E(`add`)},children:[(0,K.jsx)(c,{className:`size-4`}),` Add account`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>{w(null),E(`export`)},children:[(0,K.jsx)(p,{className:`size-4`}),` Export`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>E(`import`),children:[(0,K.jsx)(i,{className:`size-4`}),` Import`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>E(`rotation`),children:[(0,K.jsx)(d,{className:`size-4`}),` Rotation`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>E(`token-test`),children:[(0,K.jsx)(o,{className:`size-4`}),` Token test`]})]})}),(0,K.jsx)(V,{message:f,onDismiss:()=>h(null)}),(0,K.jsxs)(`section`,{className:`space-y-2`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`h3`,{className:`text-sm font-medium`,children:`Accounts`}),N&&(0,K.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`usage `,xe(new Date(N).getTime())]})]}),r?(0,K.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,K.jsx)(m,{className:`size-4 animate-spin`}),` Loading accounts...`]}):e.length===0?(0,K.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,K.jsx)(l,{className:`size-5 text-muted-foreground`}),(0,K.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No accounts connected yet.`}),(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Add one to start using PPM.`})]}):(0,K.jsx)(B,{children:e.map(e=>(0,K.jsx)(he,{layout:`strip`,entry:e,isActive:e.accountId===n,accountInfo:M.get(e.accountId),onToggle:A,toggling:g===e.accountId,onDelete:(e,t)=>b({id:e,display:t}),onExport:e=>{w(e),E(`export`)},onViewProfile:(e,t)=>S({profile:e,accountId:t}),onReauth:()=>{O(e.accountLabel??e.accountId.slice(0,8)),E(`add`)},flash:s.has(e.accountId)},e.accountId))})]}),x&&(0,K.jsx)(De,{profile:x.profile,accountId:x.accountId,onClose:()=>S(null)}),v&&(0,K.jsx)(Oe,{display:v.display,onConfirm:()=>void j(),onCancel:()=>b(null)}),(0,K.jsx)(ve,{open:T===`add`,onOpenChange:e=>{E(e?`add`:null),e||O(void 0)},onSuccess:k,signInAgainFor:D}),(0,K.jsx)(Ae,{open:T===`export`,onOpenChange:e=>{E(e?`export`:null),e||w(null)},accounts:t,preselectId:C,onMessage:h}),(0,K.jsx)(je,{open:T===`import`,onOpenChange:e=>E(e?`import`:null),onSuccess:k}),(0,K.jsx)(Pe,{open:T===`rotation`,onOpenChange:e=>E(e?`rotation`:null)}),(0,K.jsx)(ze,{open:T===`token-test`,onOpenChange:e=>E(e?`token-test`:null),accounts:t})]})}function Ve({mode:e,onOpenChange:t,password:n,onPasswordChange:r,busy:a,onExport:o,onImport:s,error:c}){let l=(0,G.useRef)(null),d=e===`export`;return(0,K.jsx)(T,{open:e!==null,onOpenChange:t,children:(0,K.jsxs)(S,{className:`sm:max-w-md`,children:[(0,K.jsxs)(b,{children:[(0,K.jsxs)(C,{className:`text-sm flex items-center gap-1.5`,children:[(0,K.jsx)(u,{className:`size-4`}),` `,d?`Export Codex Accounts`:`Import Codex Accounts`]}),(0,K.jsx)(w,{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,K.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,K.jsx)(N,{htmlFor:`codex-backup-password`,className:`text-xs`,children:`Password`}),(0,K.jsx)(D,{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,K.jsx)(`p`,{className:`text-[10px] text-muted-foreground`,children:`A backup holds full logins — keep the file and its password together.`})]}),c&&(0,K.jsx)(`div`,{className:`text-[11px] p-2 rounded bg-error/10 text-error`,children:c}),(0,K.jsx)(`input`,{ref:l,type:`file`,accept:`application/json,.json`,className:`hidden`,onChange:e=>{let t=e.target.files?.[0];e.target.value=``,t&&s(t)}}),(0,K.jsxs)(x,{children:[(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Cancel`}),(0,K.jsxs)(y,{size:`sm`,className:`text-xs cursor-pointer gap-1.5`,disabled:!n.trim()||a,onClick:()=>d?o():l.current?.click(),children:[a?(0,K.jsx)(m,{className:`size-3.5 animate-spin`}):d?(0,K.jsx)(p,{className:`size-3.5`}):(0,K.jsx)(i,{className:`size-3.5`}),d?`Download backup`:`Choose file`]})]})]})})}var He=[{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 Ue({open:e,onOpenChange:t,strategy:n,onChange:r}){return(0,K.jsx)(T,{open:e,onOpenChange:t,children:(0,K.jsxs)(S,{className:`sm:max-w-md`,children:[(0,K.jsxs)(b,{children:[(0,K.jsx)(C,{className:`text-sm`,children:`Codex Rotation`}),(0,K.jsx)(w,{className:`text-xs leading-relaxed`,children:`How a new chat chooses among your Codex accounts.`})]}),(0,K.jsx)(`div`,{className:`space-y-2`,children:He.map(e=>(0,K.jsxs)(`button`,{type:`button`,onClick:()=>r(e.value),"aria-current":n===e.value?`true`:void 0,className:g(`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,K.jsx)(`p`,{className:`text-sm font-medium`,children:e.label}),(0,K.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.hint})]},e.value))}),(0,K.jsx)(x,{children:(0,K.jsx)(y,{size:`sm`,variant:`outline`,className:`text-xs cursor-pointer`,onClick:()=>t(!1),children:`Done`})})]})})}function $(e){return e==null?null:Math.round(e*100)}function We({usage:e}){let t=e.session==null&&e.weekly==null;return(0,K.jsxs)(`div`,{className:`space-y-2`,children:[(t||e.session!=null)&&(0,K.jsx)(W,{label:`5-Hour Session`,pct:$(e.fiveHour),reset:z(e.session),resetsAt:e.session?.resetsAt}),(t||e.weekly!=null)&&(0,K.jsx)(W,{label:`Weekly`,pct:$(e.sevenDay),reset:z(e.weekly),resetsAt:e.weekly?.resetsAt})]})}function Ge(){let[e,t]=(0,G.useState)(null),n=me(()=>t(null)),[r,o]=(0,G.useState)(null);return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(H,{description:(0,K.jsxs)(K.Fragment,{children:[`Each Codex account keeps its own login (`,(0,K.jsx)(`code`,{children:`CODEX_HOME`}),`). One is picked per chat by the rotation setting.`]}),onRefresh:()=>void n.load(),refreshing:n.loading,actions:(0,K.jsxs)(K.Fragment,{children:[(0,K.jsxs)(y,{size:`sm`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`add`),children:[(0,K.jsx)(c,{className:`size-4`}),` Add account`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`export`),children:[(0,K.jsx)(p,{className:`size-4`}),` Export`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`import`),children:[(0,K.jsx)(i,{className:`size-4`}),` Import`]}),(0,K.jsxs)(y,{size:`sm`,variant:`outline`,className:`cursor-pointer gap-1.5`,onClick:()=>t(`rotation`),children:[(0,K.jsx)(d,{className:`size-4`}),` Rotation`]})]})}),(0,K.jsx)(V,{message:n.msg??n.err,onDismiss:()=>{n.setMsg(null),n.setErr(null)}}),(0,K.jsxs)(`section`,{className:`space-y-2`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsx)(`h3`,{className:`text-sm font-medium`,children:`Codex Accounts`}),(0,K.jsx)(`span`,{className:`text-[10px] text-muted-foreground capitalize`,children:n.strategy.replace(`-`,` `)})]}),n.loading&&n.accounts.length===0?(0,K.jsxs)(`div`,{className:`flex items-center gap-2 py-6 text-xs text-muted-foreground`,children:[(0,K.jsx)(m,{className:`size-4 animate-spin`}),` Loading accounts...`]}):n.accounts.length===0?(0,K.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-8 text-center`,children:[(0,K.jsx)(l,{className:`size-5 text-muted-foreground`}),(0,K.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No Codex accounts yet.`}),(0,K.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Chats use your default `,(0,K.jsx)(`code`,{children:`~/.codex`}),` login until you add one.`]})]}):(0,K.jsx)(B,{children:n.accounts.map(e=>{let t=n.usages[e.id]??{};return(0,K.jsxs)(_e,{dense:!0,className:`min-w-[300px] shrink-0 snap-start${e.signedOut?` opacity-60`:``}`,"data-testid":`account-card`,"data-account-id":e.id,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`span`,{className:`text-sm font-medium truncate flex-1 min-w-0`,children:e.label}),e.signedOut&&(0,K.jsx)(pe,{className:`text-[10px] text-error shrink-0 font-medium`,hint:`Codex rejected this account's login (revoked or expired), so no turn can run on it and it is skipped. The usage shown is the last reading. Click to sign in again — the account keeps its settings and chats.`,onClick:e.type===`chatgpt`?()=>o(e):void 0,children:`Sign in again`}),(0,K.jsx)(`span`,{className:`text-[10px] uppercase tracking-wide text-text-subtle border border-border rounded px-1 shrink-0`,children:e.type}),U(e.planType)&&(0,K.jsx)(`span`,{className:`text-[10px] text-text-subtle shrink-0`,children:U(e.planType)}),(0,K.jsx)(I,{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,K.jsxs)(M,{children:[(0,K.jsx)(O,{asChild:!0,children:(0,K.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,K.jsx)(a,{className:`size-4`})})}),(0,K.jsx)(k,{side:`top`,children:`Remove account`})]})]}),(0,K.jsx)(We,{usage:t}),t.resetCredits&&(0,K.jsx)(`div`,{className:`text-[10px] text-text-subtle`,children:(0,K.jsx)(be,{credits:t.resetCredits})}),t.session==null&&(()=>{let r=de(t.weekly);return r?(0,K.jsxs)(`div`,{className:`flex min-h-12 items-center justify-between gap-3 rounded-md border px-2.5 py-1.5 ${e.dailyGuardEnabled&&r.blocked?`border-error/40 bg-error/5`:`border-border/50 bg-surface/40`}`,children:[(0,K.jsxs)(`div`,{className:`min-w-0 space-y-0.5`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs font-medium ${e.dailyGuardEnabled&&r.blocked?`text-error`:`text-text-secondary`}`,children:[(0,K.jsx)(`span`,{children:`Daily guard`}),(0,K.jsxs)(M,{children:[(0,K.jsx)(O,{asChild:!0,children:(0,K.jsx)(`button`,{type:`button`,"aria-label":`About Daily guard`,className:`text-text-subtle hover:text-text-primary cursor-help`,children:(0,K.jsx)(s,{className:`size-3.5`})})}),(0,K.jsx)(k,{side:`top`,className:`max-w-64 text-xs leading-relaxed`,children:`Spreads the weekly quota across five weekdays, adding 20% per weekday. Weekend slots keep the previous cap; unused allowance carries forward. Daily slots start at the reset time and use UTC weekdays. Turn it off any time to use the remaining quota freely.`})]})]}),(0,K.jsx)(`p`,{className:`text-[10px] tabular-nums ${e.dailyGuardEnabled&&r.blocked?`text-error`:`text-text-subtle`}`,children:e.dailyGuardEnabled&&r.blocked?`${Math.round(r.used*100)}% used / ${Math.round(r.cap*100)}% daily cap. New turns paused.`:`Weekday ${r.day}/5, ${Math.round(r.cap*100)}% daily cap`})]}),(0,K.jsxs)(`span`,{className:`hidden`,title:`Weekday ${r.day}/5: hold weekly usage at or below ${Math.round(r.cap*100)}% to last until reset.`,children:[`Daily guard `,e.dailyGuardEnabled?`· Weekday ${r.day}/5 cap ${Math.round(r.cap*100)}%`:``]}),(0,K.jsx)(I,{checked:!!e.dailyGuardEnabled,onCheckedChange:()=>void n.toggleDailyGuard(e.id,!!e.dailyGuardEnabled),disabled:n.toggling.has(e.id),"aria-label":e.dailyGuardEnabled?`Disable Daily guard`:`Enable Daily guard`,className:`cursor-pointer shrink-0`})]}):null})()]},e.id)})})]}),(0,K.jsx)(ge,{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,K.jsx)(Ve,{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}),r&&(0,K.jsx)(ye,{account:r,onClose:()=>o(null),onDone:()=>void n.load()}),(0,K.jsx)(Ue,{open:e===`rotation`,onOpenChange:e=>t(e?`rotation`:null),strategy:n.strategy,onChange:e=>void n.changeStrategy(e)})]})}var Ke=[{id:`claude`,label:`Claude`},{id:`codex`,label:`Codex`}];function qe(){let[e,t]=(0,G.useState)(null),[n,r]=(0,G.useState)(`claude`);(0,G.useEffect)(()=>{let e=!1;return re().then(n=>{e||t(new Set(Object.keys(n.providers??{})))}).catch(()=>{e||t(new Set([`claude`]))}),()=>{e=!0}},[]);let i=Ke.filter(t=>t.id===`claude`||e?.has(t.id)),a=i.length>1;return(0,K.jsxs)(`div`,{className:`space-y-4`,"data-testid":`accounts-pane`,"data-provider":n,children:[a&&(0,K.jsx)(`div`,{className:`flex gap-1 border-b border-border/50`,children:i.map(e=>(0,K.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,K.jsx)(A,{providerId:e.id}),e.label]},e.id))}),e===null&&!a&&(0,K.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,K.jsx)(m,{className:`size-3 animate-spin`}),` Checking configured providers...`]}),n===`claude`?(0,K.jsx)(Be,{}):(0,K.jsx)(Ge,{})]})}export{qe as AccountsSettingsSection};