@hienlh/ppm 0.20.8 → 0.20.9

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 (489) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/http-api.md +1 -1
  4. package/dist/web/assets/accounts-settings-section-ByM99C7p.js +1 -0
  5. package/dist/web/assets/{ai-resource-editor-CMQfhxXp.js → ai-resource-editor-BsB9wa0z.js} +1 -1
  6. package/dist/web/assets/{ai-settings-section-M07DCjAI.js → ai-settings-section-BT-QVUBa.js} +1 -1
  7. package/dist/web/assets/ai-settings-section-BUPOINaw.js +1 -0
  8. package/dist/web/assets/{angular-html-BtJLNcMw.js → angular-html-CTx8qAkv.js} +1 -1
  9. package/dist/web/assets/{angular-ts-CQiu5F_W.js → angular-ts-BhBGUAnu.js} +1 -1
  10. package/dist/web/assets/api-client-C6VTn7cG.js +1 -0
  11. package/dist/web/assets/{api-settings-BQIwZoLm.js → api-settings-CqiVKFUX.js} +1 -1
  12. package/dist/web/assets/{api-themes-CmJZLEY1.js → api-themes-DtLXqXpC.js} +1 -1
  13. package/dist/web/assets/{apl-CKZvgs-w.js → apl-Dec3pSzF.js} +1 -1
  14. package/dist/web/assets/{appearance-settings-section-BBlJtEm5.js → appearance-settings-section-DJEoECoJ.js} +1 -1
  15. package/dist/web/assets/architecture-PBZL5I3N-D55g5j-p.js +1 -0
  16. package/dist/web/assets/arrow-right-BqNSIscF.js +1 -0
  17. package/dist/web/assets/{astro-D0b8ssLD.js → astro-Cb_3-S86.js} +1 -1
  18. package/dist/web/assets/{audio-preview-DPMXOZ55.js → audio-preview-CF4tTFv_.js} +1 -1
  19. package/dist/web/assets/{blade-DOIpINLw.js → blade-1QMj5JxI.js} +1 -1
  20. package/dist/web/assets/{bsl-CJ7_JlQ8.js → bsl-D0bT3Wjp.js} +1 -1
  21. package/dist/web/assets/{button-zgoXa9r7.js → button-DhnNoqpV.js} +1 -1
  22. package/dist/web/assets/{cairo-5CpV2T1P.js → cairo-DTuGb2w7.js} +1 -1
  23. package/dist/web/assets/{chat-tab-Dn45anqr.js → chat-tab-fD2vWwj2.js} +8 -8
  24. package/dist/web/assets/circle-question-mark-DUaySkoB.js +1 -0
  25. package/dist/web/assets/{cobol-BreMVrtc.js → cobol-DSx_Nb7T.js} +1 -1
  26. package/dist/web/assets/{code-editor-CKASeDbu.js → code-editor-CyFLXCsD.js} +2 -2
  27. package/dist/web/assets/codex-daily-guard-Cg19EWxk.js +1 -0
  28. package/dist/web/assets/{coffee-D7DoKh5b.js → coffee-DBcQ7DKB.js} +1 -1
  29. package/dist/web/assets/{conflict-editor-C-Nv8YYj.js → conflict-editor-DSjo2FRy.js} +1 -1
  30. package/dist/web/assets/{context-menu-DM9CgxGh.js → context-menu-DchAkdnL.js} +1 -1
  31. package/dist/web/assets/{cpp-BnWeWAoE.js → cpp-Bj1azGr-.js} +1 -1
  32. package/dist/web/assets/{crystal-D2pJbFUn.js → crystal-CCgkDI0i.js} +1 -1
  33. package/dist/web/assets/{csv-preview-ou3KFzIH.js → csv-preview-BIE3Wpww.js} +1 -1
  34. package/dist/web/assets/{data-grid-overlay-editor-dnWnblYo.js → data-grid-overlay-editor-C2NAQ-88.js} +1 -1
  35. package/dist/web/assets/{database-viewer-Ckqg_-SS.js → database-viewer-CMvIORcM.js} +1 -1
  36. package/dist/web/assets/{diff-viewer-CMzFnBCD.js → diff-viewer-BQQ6fUr6.js} +1 -1
  37. package/dist/web/assets/{docx-preview-B7Aospmh.js → docx-preview-DcCh59Oe.js} +1 -1
  38. package/dist/web/assets/{edge-aqGMtbY3.js → edge-ClBfeO7z.js} +1 -1
  39. package/dist/web/assets/{edit-diff-preview-BvgPvuhH.js → edit-diff-preview-CRjufuw_.js} +1 -1
  40. package/dist/web/assets/{elixir-CsYMBLc5.js → elixir-ir__-3kt.js} +1 -1
  41. package/dist/web/assets/{elm-BU8C2gFp.js → elm-CUv-xMuU.js} +1 -1
  42. package/dist/web/assets/{erb-Z_E49ab8.js → erb-DcRwHyUq.js} +1 -1
  43. package/dist/web/assets/{erlang-BRqOjXH9.js → erlang-DW-GAdmv.js} +1 -1
  44. package/dist/web/assets/{esm-BHyWbWKE.js → esm-DBm5LSCw.js} +1 -1
  45. package/dist/web/assets/{explorer-body-CVx4qaIF.js → explorer-body-DRo2JHP9.js} +2 -2
  46. package/dist/web/assets/explorer-window-content-7mnRpSqn.js +1 -0
  47. package/dist/web/assets/{extension-manager-section-CtcpVMWs.js → extension-manager-section-CEfr7-Kv.js} +1 -1
  48. package/dist/web/assets/{extension-webview-DZ_QRZSM.js → extension-webview-D7HqqdTv.js} +1 -1
  49. package/dist/web/assets/{files-settings-section-D7v-6nTa.js → files-settings-section-h6a-WpSO.js} +1 -1
  50. package/dist/web/assets/{fortran-fixed-form-CWbxmDGR.js → fortran-fixed-form-DrQbMSkt.js} +1 -1
  51. package/dist/web/assets/{fsharp-DKMYbq6I.js → fsharp-DvDj84Ys.js} +1 -1
  52. package/dist/web/assets/{gdresource-B3yFau4V.js → gdresource-CPgY7R2s.js} +1 -1
  53. package/dist/web/assets/{general-settings-section-BW_h8pdA.js → general-settings-section-Bt3KNcyM.js} +1 -1
  54. package/dist/web/assets/{git-commit-BW0p3Ekk.js → git-commit-NJ9iGbTd.js} +1 -1
  55. package/dist/web/assets/{git-log-panel-BQZkJDu0.js → git-log-panel-H-Bg9p7m.js} +1 -1
  56. package/dist/web/assets/{git-rebase-DrvmQCS7.js → git-rebase-DBSy9OKE.js} +1 -1
  57. package/dist/web/assets/gitGraph-HDMCJU4V-At-P8hlA.js +1 -0
  58. package/dist/web/assets/{glide-data-grid-JKEslqGe.js → glide-data-grid-D3Xc_WGh.js} +4 -4
  59. package/dist/web/assets/{glimmer-js-BY1XApJJ.js → glimmer-js-EGWSSdwJ.js} +1 -1
  60. package/dist/web/assets/{glimmer-ts-DPZtxF8N.js → glimmer-ts-BpfXRYRV.js} +1 -1
  61. package/dist/web/assets/{glsl-DZ8G_Hvf.js → glsl-BtWQ4j8X.js} +1 -1
  62. package/dist/web/assets/{graphql-Ck06uCZy.js → graphql-DHR5AO2c.js} +1 -1
  63. package/dist/web/assets/{group-chat-tab-CTAhtVCr.js → group-chat-tab-BkLt7J_s.js} +1 -1
  64. package/dist/web/assets/{hack-pLogDwAs.js → hack-A3iOItmC.js} +1 -1
  65. package/dist/web/assets/{haml-CBqeCQ2A.js → haml-DXA8NXfZ.js} +1 -1
  66. package/dist/web/assets/{handlebars-B66JmVtp.js → handlebars-BdIFK4pP.js} +1 -1
  67. package/dist/web/assets/{html-Dk4wmfwC.js → html-BTA4eRkb.js} +1 -1
  68. package/dist/web/assets/{html-derivative-CJWqfN51.js → html-derivative-Cd_vDV4L.js} +1 -1
  69. package/dist/web/assets/{http-CexhotTh.js → http-CMY5fp9k.js} +1 -1
  70. package/dist/web/assets/{hurl-BScKFk3Z.js → hurl-DJZLRi6K.js} +1 -1
  71. package/dist/web/assets/{hxml-DAle7vtu.js → hxml-C2EdtM37.js} +1 -1
  72. package/dist/web/assets/{image-preview-V5SglTWk.js → image-preview-D_6-FhZP.js} +1 -1
  73. package/dist/web/assets/{index-DVNJ2W5R.js → index-BV_sFdHY.js} +6 -6
  74. package/dist/web/assets/index-Di9nVG3y.css +2 -0
  75. package/dist/web/assets/info-3K5VOQVL-btSsuixb.js +1 -0
  76. package/dist/web/assets/{jinja-yHpyD80t.js → jinja-DWU92jHm.js} +1 -1
  77. package/dist/web/assets/{jira-watcher-section-VyzVbAnw.js → jira-watcher-section-BhQzWJ3r.js} +1 -1
  78. package/dist/web/assets/{jison-BY6WLJVu.js → jison-Bt3f5-S6.js} +1 -1
  79. package/dist/web/assets/{julia-Dd_iYQDT.js → julia-BS-e0jQg.js} +1 -1
  80. package/dist/web/assets/{just-BTuUKpxF.js → just-OU89Ot3I.js} +1 -1
  81. package/dist/web/assets/keybindings-store-alreySno.js +1 -0
  82. package/dist/web/assets/{keyboard-shortcuts-section-DOJi75mV.js → keyboard-shortcuts-section-B_D0FamP.js} +1 -1
  83. package/dist/web/assets/{latex-Dt3OUlMZ.js → latex-Bt5mTs31.js} +1 -1
  84. package/dist/web/assets/{liquid-BxPJU2ix.js → liquid-C03IGCJ6.js} +1 -1
  85. package/dist/web/assets/{lua-DEGIvn7d.js → lua-Dl4zPu0P.js} +1 -1
  86. package/dist/web/assets/{markdown-renderer-DtQIHtLs.js → markdown-renderer-CG_nGh7k.js} +3 -3
  87. package/dist/web/assets/markdown-renderer-CgbqvSuc.js +1 -0
  88. package/dist/web/assets/{marko-BDxwBJur.js → marko-BEnkIoHY.js} +1 -1
  89. package/dist/web/assets/{mdc-B8aXPTg7.js → mdc-DGglct19.js} +1 -1
  90. package/dist/web/assets/{media-url-TYMlO0M5.js → media-url-LiPp2UsV.js} +1 -1
  91. package/dist/web/assets/{mobile-bottom-sheet-Ch1e_JBq.js → mobile-bottom-sheet-BizNfPAu.js} +1 -1
  92. package/dist/web/assets/mobile-explorer-sheet-DAZTzi1k.js +1 -0
  93. package/dist/web/assets/{nextflow-DBVZnnT_.js → nextflow-DKFYidyC.js} +1 -1
  94. package/dist/web/assets/{nginx-Crpyd-Do.js → nginx-Bhq0tzlh.js} +1 -1
  95. package/dist/web/assets/{nim-BSqTBYDj.js → nim-CSuBzart.js} +1 -1
  96. package/dist/web/assets/notification-store-HCg5Shw9.js +1 -0
  97. package/dist/web/assets/{notifications-settings-section-CeRvkXOM.js → notifications-settings-section-BAs_p_ai.js} +1 -1
  98. package/dist/web/assets/{number-overlay-editor-DldrUNs4.js → number-overlay-editor-CYHlP43e.js} +1 -1
  99. package/dist/web/assets/{overview-panel-DA0QB1-5.js → overview-panel-xn2BYvn6.js} +1 -1
  100. package/dist/web/assets/packet-RMMSAZCW-B20_sIFd.js +1 -0
  101. package/dist/web/assets/{panel-store-D42k25jy.js → panel-store-XhAruR6D.js} +1 -1
  102. package/dist/web/assets/{pdf-preview-Cq33D5ej.js → pdf-preview-BJjqU3AX.js} +1 -1
  103. package/dist/web/assets/{perl-BU0kbB-K.js → perl-uDVR7Ceh.js} +1 -1
  104. package/dist/web/assets/{php-D9n1ikHN.js → php-Bby8J3zk.js} +1 -1
  105. package/dist/web/assets/pie-UPGHQEXC-nzfJdXCC.js +1 -0
  106. package/dist/web/assets/{postgres-viewer-C__Z0C0s.js → postgres-viewer-CJbHLcGE.js} +3 -3
  107. package/dist/web/assets/{ppmbot-settings-section-Cma4VU7p.js → ppmbot-settings-section-5U0a58oj.js} +1 -1
  108. package/dist/web/assets/{process-table-DH_HXtGc.js → process-table-CqGL0Bcj.js} +1 -1
  109. package/dist/web/assets/{project-store-C83MMnlt.js → project-store-Dy3A3LJT.js} +1 -1
  110. package/dist/web/assets/{proxy-settings-section-xrTsFlTF.js → proxy-settings-section-B1LDpGSc.js} +1 -1
  111. package/dist/web/assets/{pug-BOpaczDr.js → pug-EapfojTW.js} +1 -1
  112. package/dist/web/assets/{qml-B-cQXhrg.js → qml-DiR6J5_C.js} +1 -1
  113. package/dist/web/assets/{query-audit-section-Drk97gb8.js → query-audit-section-DfCvY94_.js} +1 -1
  114. package/dist/web/assets/radar-KQ55EAFF-CS4sHKD5.js +1 -0
  115. package/dist/web/assets/{razor-DFB0pNCh.js → razor-B2QvlGNY.js} +1 -1
  116. package/dist/web/assets/remote-desktop-mobile-sheet-_LH4uCcA.js +2 -0
  117. package/dist/web/assets/{remote-desktop-mobile-view-Gk8UCVIx.js → remote-desktop-mobile-view-C5TUPDh_.js} +1 -1
  118. package/dist/web/assets/{remote-desktop-readiness-gate-6reSZvad.js → remote-desktop-readiness-gate-DuT4A893.js} +1 -1
  119. package/dist/web/assets/{remote-desktop-window-content-BW2KqONI.js → remote-desktop-window-content-B4V-1aJn.js} +1 -1
  120. package/dist/web/assets/{rst-DAXedsgm.js → rst-D2eJ0kH4.js} +1 -1
  121. package/dist/web/assets/{ruby-BCO4polC.js → ruby-DzpnBpz-.js} +1 -1
  122. package/dist/web/assets/{run-in-terminal-DoTOtgQS.js → run-in-terminal-DisO5HC-.js} +1 -1
  123. package/dist/web/assets/{sas-DfB5dcFC.js → sas-WDAKsX0U.js} +1 -1
  124. package/dist/web/assets/{schedules-settings-section-DcKEz-S7.js → schedules-settings-section-C2SjwWFB.js} +1 -1
  125. package/dist/web/assets/{scss-BknIVgn7.js → scss-Ci6PdscL.js} +1 -1
  126. package/dist/web/assets/{send-to-chat-Kl-0dNwN.js → send-to-chat-DDFdKWNf.js} +1 -1
  127. package/dist/web/assets/{separator-DvCsdlws.js → separator-CyisF27O.js} +1 -1
  128. package/dist/web/assets/settings-body-CdFauCAU.js +2 -0
  129. package/dist/web/assets/{settings-store-_s4xFcFq.js → settings-store-BkNrLdjk.js} +2 -2
  130. package/dist/web/assets/settings-tab-DGUlmMbc.js +1 -0
  131. package/dist/web/assets/settings-window-content-CIH5sihe.js +1 -0
  132. package/dist/web/assets/{shaderlab-CPu31TpY.js → shaderlab-Cv3mWofL.js} +1 -1
  133. package/dist/web/assets/{shellsession-CFX4c_TM.js → shellsession-D1KVtQa1.js} +1 -1
  134. package/dist/web/assets/{soy-rz9hilgm.js → soy-BGLBwFZT.js} +1 -1
  135. package/dist/web/assets/{sparql-Bo8ZDeqE.js → sparql-TvnQmFDh.js} +1 -1
  136. package/dist/web/assets/{sql-query-editor-BoYxc5vd.js → sql-query-editor-DaQqRBNA.js} +1 -1
  137. package/dist/web/assets/{sqlite-viewer-O5lF3MMj.js → sqlite-viewer-Bpz7QnBk.js} +1 -1
  138. package/dist/web/assets/{stata-B5J-QMyE.js → stata-Gi-BKyEv.js} +1 -1
  139. package/dist/web/assets/{streaming-store-QQvg1cS-.js → streaming-store-DAbnOfLu.js} +1 -1
  140. package/dist/web/assets/{surrealql-Caw1ADnG.js → surrealql-BVXs6tkz.js} +1 -1
  141. package/dist/web/assets/{svelte-D3oMVcxz.js → svelte-BlnFpLWV.js} +1 -1
  142. package/dist/web/assets/{system-monitor-body-C2mVJ7PV.js → system-monitor-body-BBJOWFCa.js} +2 -2
  143. package/dist/web/assets/system-monitor-tab-D7RIwhmg.js +1 -0
  144. package/dist/web/assets/{system-monitor-window-content-BaKoFDEz.js → system-monitor-window-content-CH0UmMP9.js} +1 -1
  145. package/dist/web/assets/{tab-host-window-content-C7F6D8hJ.js → tab-host-window-content-C_yU5MH_.js} +1 -1
  146. package/dist/web/assets/{tab-store-B2ip0-Mv.js → tab-store-B7BksLr-.js} +1 -1
  147. package/dist/web/assets/team-member-sheet-CopMME1E.js +2 -0
  148. package/dist/web/assets/{team-member-window-content-BwOTsc9r.js → team-member-window-content-CUDQ6oX7.js} +1 -1
  149. package/dist/web/assets/{templ-BAdNyIOL.js → templ-YJYH5r1A.js} +1 -1
  150. package/dist/web/assets/{terminal-tab-DlZW3MCn.js → terminal-tab-BjI95uG5.js} +1 -1
  151. package/dist/web/assets/{tex-IQ8mELOR.js → tex-IVZLDIeh.js} +1 -1
  152. package/dist/web/assets/{tool-cards-yiwO861p.js → tool-cards-I71v1w5Z.js} +6 -6
  153. package/dist/web/assets/treemap-KZPCXAKY-BBrhTPZk.js +1 -0
  154. package/dist/web/assets/{ts-tags-D1DDO2jl.js → ts-tags-DBd321I-.js} +1 -1
  155. package/dist/web/assets/{twig-C8Fd5RvV.js → twig-DQENQjEn.js} +1 -1
  156. package/dist/web/assets/{use-blob-url-D358Rpyp.js → use-blob-url-CGChX4vi.js} +1 -1
  157. package/dist/web/assets/{use-inline-blame-D2pZjDoA.js → use-inline-blame-CRUwd6FF.js} +1 -1
  158. package/dist/web/assets/{use-monaco-theme-DTPfPPvF.js → use-monaco-theme-qzMbRfCW.js} +1 -1
  159. package/dist/web/assets/{use-open-team-member-DGEx9xB0.js → use-open-team-member-kmNnlzDD.js} +1 -1
  160. package/dist/web/assets/{use-remote-desktop-display-choice-BnVT4dhX.js → use-remote-desktop-display-choice-0zDkCmsK.js} +1 -1
  161. package/dist/web/assets/{use-websocket-DQg9BQcq.js → use-websocket-D8OGBwH8.js} +1 -1
  162. package/dist/web/assets/{vendor-mermaid-CfY1-PkA.js → vendor-mermaid-BoRFiriK.js} +1 -1
  163. package/dist/web/assets/{video-preview-Dc4YbBqm.js → video-preview-Mlgl7hGr.js} +1 -1
  164. package/dist/web/assets/{vue-EvccXlkP.js → vue-Do2JXEwi.js} +1 -1
  165. package/dist/web/assets/{vue-html-Dg0xUJCh.js → vue-html-Bse0CwSC.js} +1 -1
  166. package/dist/web/assets/{vue-vine-BdrMg72k.js → vue-vine-C8JSXu5Z.js} +1 -1
  167. package/dist/web/assets/{window-pip-registry-BWxaVLj5.js → window-pip-registry-C2dcY0pE.js} +1 -1
  168. package/dist/web/assets/{window-store-CfxP5yor.js → window-store-2z4t5YAt.js} +1 -1
  169. package/dist/web/assets/ws-auth-DI1E6Fe7.js +1 -0
  170. package/dist/web/assets/{xml-MmDclzxK.js → xml-OX6YmzGK.js} +1 -1
  171. package/dist/web/assets/{xsl-DQEFs6Dd.js → xsl-RQUQgcgy.js} +1 -1
  172. package/dist/web/index.html +34 -34
  173. package/dist/web/sw.js +1 -1
  174. package/package.json +1 -1
  175. package/src/providers/codex-app-server/codex-event-mapper.ts +28 -1
  176. package/src/providers/codex-app-server/codex-provider.ts +38 -5
  177. package/src/providers/codex-app-server/codex-usage-parser.ts +3 -1
  178. package/src/server/routes/codex-accounts.ts +9 -5
  179. package/src/services/codex-account-login.ts +33 -5
  180. package/src/services/codex-account-portability.ts +3 -2
  181. package/src/services/codex-account.service.ts +48 -7
  182. package/src/services/codex-login-callback.ts +18 -0
  183. package/src/services/db.service.ts +14 -0
  184. package/src/shared/codex-daily-guard.ts +27 -0
  185. package/src/shared/codex-plan-label.ts +17 -0
  186. package/src/web/components/chat/codex-usage-panel.tsx +22 -2
  187. package/src/web/components/settings/accounts/account-card.tsx +43 -2
  188. package/src/web/components/settings/accounts/codex-accounts-section.tsx +43 -2
  189. package/src/web/components/settings/accounts/use-codex-accounts.ts +14 -2
  190. package/dist/web/assets/accounts-settings-section-CRXY4Bsc.js +0 -1
  191. package/dist/web/assets/ai-settings-section-446NZWhI.js +0 -1
  192. package/dist/web/assets/api-client-CYZ79uUS.js +0 -1
  193. package/dist/web/assets/architecture-PBZL5I3N-DfR8k8Bc.js +0 -1
  194. package/dist/web/assets/circle-question-mark-qcWYO1P_.js +0 -1
  195. package/dist/web/assets/explorer-window-content-CqKVMkgW.js +0 -1
  196. package/dist/web/assets/gitGraph-HDMCJU4V-CPd78aaT.js +0 -1
  197. package/dist/web/assets/index-B9Wbjl0o.css +0 -2
  198. package/dist/web/assets/info-3K5VOQVL-BciNds6R.js +0 -1
  199. package/dist/web/assets/keybindings-store-B5dEz0n1.js +0 -1
  200. package/dist/web/assets/markdown-renderer-BGPo364Y.js +0 -1
  201. package/dist/web/assets/mobile-explorer-sheet-C1q_DhrI.js +0 -1
  202. package/dist/web/assets/notification-store-DvUtkAXs.js +0 -1
  203. package/dist/web/assets/packet-RMMSAZCW-ClD3l2Bs.js +0 -1
  204. package/dist/web/assets/pie-UPGHQEXC-PU6kD0rW.js +0 -1
  205. package/dist/web/assets/radar-KQ55EAFF-4LzjL0Zt.js +0 -1
  206. package/dist/web/assets/remote-desktop-mobile-sheet-6JdUr0Bj.js +0 -2
  207. package/dist/web/assets/settings-body-CcKls51a.js +0 -2
  208. package/dist/web/assets/settings-tab-ChAk8nh2.js +0 -1
  209. package/dist/web/assets/settings-window-content-sA1K0cPW.js +0 -1
  210. package/dist/web/assets/system-monitor-tab-tXkg3jpV.js +0 -1
  211. package/dist/web/assets/team-member-sheet-BA70_jmM.js +0 -2
  212. package/dist/web/assets/treemap-KZPCXAKY-DiumLNMg.js +0 -1
  213. package/dist/web/assets/use-accounts-data-B9t4BQaI.js +0 -1
  214. package/dist/web/assets/ws-auth-FRzMmfQx.js +0 -1
  215. /package/dist/web/assets/{abap-D-o-bvtI.js → abap-BIHt2d9F.js} +0 -0
  216. /package/dist/web/assets/{actionscript-3-D2tIzAm8.js → actionscript-3-rbCNRHFj.js} +0 -0
  217. /package/dist/web/assets/{ada-DxatBcxS.js → ada-CN94LQTJ.js} +0 -0
  218. /package/dist/web/assets/{andromeeda-D0LK9YJ3.js → andromeeda-BsmcoXuQ.js} +0 -0
  219. /package/dist/web/assets/{apache-B7uMPNiW.js → apache-pRQmqcVZ.js} +0 -0
  220. /package/dist/web/assets/{apex-B7GiXrAr.js → apex-CNEumC1X.js} +0 -0
  221. /package/dist/web/assets/{api-client-DwXlVfXP.js → api-client-DKvkxuDr.js} +0 -0
  222. /package/dist/web/assets/{applescript-D_SIFkKe.js → applescript-DjEVsS-3.js} +0 -0
  223. /package/dist/web/assets/{apply-theme-BVXAUYoN.js → apply-theme-Abd1TNqE.js} +0 -0
  224. /package/dist/web/assets/{ara-C3iECgdg.js → ara-DbhZRlTL.js} +0 -0
  225. /package/dist/web/assets/{asciidoc-gc8z_MMY.js → asciidoc-BsfbAXIK.js} +0 -0
  226. /package/dist/web/assets/{asm-27qeoPOI.js → asm-Vw5NMXjI.js} +0 -0
  227. /package/dist/web/assets/{aurora-x-C5J9fWe1.js → aurora-x-CoahU6sR.js} +0 -0
  228. /package/dist/web/assets/{awk-B7GBzF92.js → awk-ChKjCxHz.js} +0 -0
  229. /package/dist/web/assets/{ayu-dark-XlnQhuLL.js → ayu-dark-By9RKxTf.js} +0 -0
  230. /package/dist/web/assets/{ayu-light-DKLLilkU.js → ayu-light-CEsgeLON.js} +0 -0
  231. /package/dist/web/assets/{ayu-mirage-Dv-XOprJ.js → ayu-mirage-CYrtwSLW.js} +0 -0
  232. /package/dist/web/assets/{ballerina-DACRT-sT.js → ballerina-CCSVz22W.js} +0 -0
  233. /package/dist/web/assets/{bat-BlQCq2XE.js → bat-DU4--CMj.js} +0 -0
  234. /package/dist/web/assets/{beancount-DYDztRI0.js → beancount-DF_tlRlF.js} +0 -0
  235. /package/dist/web/assets/{berry-BE5YKqvx.js → berry-CZTnatvO.js} +0 -0
  236. /package/dist/web/assets/{bibtex-CAm7mgEm.js → bibtex-BSpXy8jk.js} +0 -0
  237. /package/dist/web/assets/{bicep-BKgAbfVa.js → bicep-yv1Ydq5Z.js} +0 -0
  238. /package/dist/web/assets/{bird2-yrBNbW1G.js → bird2-Db7Z7SMN.js} +0 -0
  239. /package/dist/web/assets/{c-txZFr4RM.js → c-C3ivhwA4.js} +0 -0
  240. /package/dist/web/assets/{c3-D_DrzBUd.js → c3-N4mKyst9.js} +0 -0
  241. /package/dist/web/assets/{cadence-CUFCEgG9.js → cadence-BYK8tFFk.js} +0 -0
  242. /package/dist/web/assets/{can-open-in-ppm-_yqa69dV.js → can-open-in-ppm-DU5MH6XF.js} +0 -0
  243. /package/dist/web/assets/{catppuccin-frappe-Dn32MuhA.js → catppuccin-frappe-BK9Tv2XG.js} +0 -0
  244. /package/dist/web/assets/{catppuccin-latte-Dewo7yDf.js → catppuccin-latte-De4mVCp3.js} +0 -0
  245. /package/dist/web/assets/{catppuccin-macchiato-D8WOWZeo.js → catppuccin-macchiato-Bxt_D7cs.js} +0 -0
  246. /package/dist/web/assets/{catppuccin-mocha-b0md48XM.js → catppuccin-mocha-Dz2o8gN7.js} +0 -0
  247. /package/dist/web/assets/{circle-OKk7s0DX.js → circle-BpGTLAas.js} +0 -0
  248. /package/dist/web/assets/{clarity-Ct3UqLBj.js → clarity-BJdh0Pw-.js} +0 -0
  249. /package/dist/web/assets/{clock-BmPiGrSF.js → clock-Dqq0H9yH.js} +0 -0
  250. /package/dist/web/assets/{clojure-CwP5aPEo.js → clojure-DG-FYGzn.js} +0 -0
  251. /package/dist/web/assets/{cmake-D5RF49e5.js → cmake-D1imEXan.js} +0 -0
  252. /package/dist/web/assets/{code-CRiIHSiv.js → code-CX6640Tv.js} +0 -0
  253. /package/dist/web/assets/{codeowners-Cl5897L_.js → codeowners-YpylTFB5.js} +0 -0
  254. /package/dist/web/assets/{codeql-BKh1RCg0.js → codeql-ajDEPgqi.js} +0 -0
  255. /package/dist/web/assets/{common-lisp-BhHuD6t0.js → common-lisp-C2sCrd-m.js} +0 -0
  256. /package/dist/web/assets/{copy-CXuIH4VC.js → copy-Bt_1tjoJ.js} +0 -0
  257. /package/dist/web/assets/{coq-Dco3qwD8.js → coq-BqybyDc9.js} +0 -0
  258. /package/dist/web/assets/{csharp-Dpjw9ZA9.js → csharp-nKCEiujy.js} +0 -0
  259. /package/dist/web/assets/{css-CPe4cabH.js → css-CJSp2CsD.js} +0 -0
  260. /package/dist/web/assets/{csv-BAcTN8Kt.js → csv-Nh9vQwQm.js} +0 -0
  261. /package/dist/web/assets/{csv-parser-DbxGKdMG.js → csv-parser-iow1WWML.js} +0 -0
  262. /package/dist/web/assets/{cue-Cr6y60TA.js → cue-Ch79RPsU.js} +0 -0
  263. /package/dist/web/assets/{cypher-DWtqXXFP.js → cypher-CgiOQ6hs.js} +0 -0
  264. /package/dist/web/assets/{d-BASiTZk4.js → d-CmBcySpH.js} +0 -0
  265. /package/dist/web/assets/{dark-plus-56kmnrcl.js → dark-plus-COLEX2ui.js} +0 -0
  266. /package/dist/web/assets/{dart-C5mZnjoE.js → dart-BTAArMcJ.js} +0 -0
  267. /package/dist/web/assets/{data-grid-types-BfGeMDy0.js → data-grid-types-tNj9zuRV.js} +0 -0
  268. /package/dist/web/assets/{database-Dz0W7OH7.js → database-9_p74TtY.js} +0 -0
  269. /package/dist/web/assets/{dax-B4I2e7d8.js → dax-BbZzRY9i.js} +0 -0
  270. /package/dist/web/assets/{desktop-DekGg0BT.js → desktop-OmQvU3-J.js} +0 -0
  271. /package/dist/web/assets/{diff-CWnJBd73.js → diff-BEPnb9Fb.js} +0 -0
  272. /package/dist/web/assets/{dist-BKOM_AoT.js → dist-BDpuZ376.js} +0 -0
  273. /package/dist/web/assets/{dist-CWMPvPem.js → dist-BiqPfYiP.js} +0 -0
  274. /package/dist/web/assets/{docker-DevchDxK.js → docker-Cg17HgTD.js} +0 -0
  275. /package/dist/web/assets/{dotenv-DCvtdaGJ.js → dotenv-DEMIaY7V.js} +0 -0
  276. /package/dist/web/assets/{download-D70Q4Ba6.js → download-CEPFebri.js} +0 -0
  277. /package/dist/web/assets/{dracula-8U6Vkk3l.js → dracula-BkCFq8SO.js} +0 -0
  278. /package/dist/web/assets/{dracula-soft-Bfeew5Wg.js → dracula-soft-Cjp6-ltF.js} +0 -0
  279. /package/dist/web/assets/{dream-maker-DDTJVuoy.js → dream-maker-Ce7Y_UKj.js} +0 -0
  280. /package/dist/web/assets/{emacs-lisp-CEHJqI4m.js → emacs-lisp-BjpyfTbN.js} +0 -0
  281. /package/dist/web/assets/{everforest-dark-CHHLt7cq.js → everforest-dark-9r4okw1s.js} +0 -0
  282. /package/dist/web/assets/{everforest-light-TcTbK1sM.js → everforest-light-GCQTZ3Ju.js} +0 -0
  283. /package/dist/web/assets/{eye-dfZn7evX.js → eye-BQaWPI4P.js} +0 -0
  284. /package/dist/web/assets/{eye-off-CmtfyRUD.js → eye-off-BlB3QV90.js} +0 -0
  285. /package/dist/web/assets/{fennel-Bh4vsA1A.js → fennel-ITjY5Z6u.js} +0 -0
  286. /package/dist/web/assets/{file-exclamation-point-D5K2aaLi.js → file-exclamation-point-BDmSZbxs.js} +0 -0
  287. /package/dist/web/assets/{fish-D0T0fILG.js → fish-DP2uEzyg.js} +0 -0
  288. /package/dist/web/assets/{flask-conical-Dix4qNDj.js → flask-conical-Cj-J6cxs.js} +0 -0
  289. /package/dist/web/assets/{fluent-CgXDXdyy.js → fluent-irzaP1f6.js} +0 -0
  290. /package/dist/web/assets/{folder-symlink-BavsIzoj.js → folder-symlink-BSYalAHC.js} +0 -0
  291. /package/dist/web/assets/{format-bytes-Bc6SqF7M.js → format-bytes-B9Dbme9a.js} +0 -0
  292. /package/dist/web/assets/{fortran-free-form-CUg3Xhz4.js → fortran-free-form-BAPoainr.js} +0 -0
  293. /package/dist/web/assets/{gdscript-Cx056p_k.js → gdscript-DJ098V1z.js} +0 -0
  294. /package/dist/web/assets/{gdshader-Dj1qP4I5.js → gdshader-DS2Jfy-K.js} +0 -0
  295. /package/dist/web/assets/{genie-SBt15wn7.js → genie-CqfOaFFx.js} +0 -0
  296. /package/dist/web/assets/{gherkin-bTJiHIrB.js → gherkin-CoZ2ucDH.js} +0 -0
  297. /package/dist/web/assets/{github-dark-BOPhyugs.js → github-dark-BNLgnSO9.js} +0 -0
  298. /package/dist/web/assets/{github-dark-default-Cktqe6NF.js → github-dark-default-CYlSggwi.js} +0 -0
  299. /package/dist/web/assets/{github-dark-dimmed-CeWfII_B.js → github-dark-dimmed-DumUysDk.js} +0 -0
  300. /package/dist/web/assets/{github-dark-high-contrast-CTx8LpdV.js → github-dark-high-contrast-TKrcDJ2I.js} +0 -0
  301. /package/dist/web/assets/{github-light-DVsO5Un1.js → github-light-DVENFHLJ.js} +0 -0
  302. /package/dist/web/assets/{github-light-default-BiyPxicr.js → github-light-default-DtN8AGcE.js} +0 -0
  303. /package/dist/web/assets/{github-light-high-contrast-BPlnke0a.js → github-light-high-contrast-NSyF37x4.js} +0 -0
  304. /package/dist/web/assets/{gleam-CWSxvD0C.js → gleam-hp4NMSb5.js} +0 -0
  305. /package/dist/web/assets/{gn-D7NUVJuv.js → gn-Dptw2PEu.js} +0 -0
  306. /package/dist/web/assets/{gnuplot-c5uXmJKc.js → gnuplot-9juRzjwv.js} +0 -0
  307. /package/dist/web/assets/{go-CRsHi4Cw.js → go-D-QLCda0.js} +0 -0
  308. /package/dist/web/assets/{groovy-DpV0RA5r.js → groovy-DHKNy6Eh.js} +0 -0
  309. /package/dist/web/assets/{gruvbox-dark-hard-DD9fguUN.js → gruvbox-dark-hard-BFD6aQdB.js} +0 -0
  310. /package/dist/web/assets/{gruvbox-dark-medium-BvcwpYJ-.js → gruvbox-dark-medium-D5llYBNp.js} +0 -0
  311. /package/dist/web/assets/{gruvbox-dark-soft-48dCxX9M.js → gruvbox-dark-soft-DOztQmNR.js} +0 -0
  312. /package/dist/web/assets/{gruvbox-light-hard-CjJ994Ip.js → gruvbox-light-hard-BFGD-8Pd.js} +0 -0
  313. /package/dist/web/assets/{gruvbox-light-medium-DQJQZ_rV.js → gruvbox-light-medium-DzoyXgT7.js} +0 -0
  314. /package/dist/web/assets/{gruvbox-light-soft-AqsC9mKw.js → gruvbox-light-soft-B1Ix2zLN.js} +0 -0
  315. /package/dist/web/assets/{hand-CIPALZsE.js → hand-BkDyLfcc.js} +0 -0
  316. /package/dist/web/assets/{haskell-B5V7yvmh.js → haskell-BnrJ0k7G.js} +0 -0
  317. /package/dist/web/assets/{haxe-LWTKfPKr.js → haxe-DwShHT_-.js} +0 -0
  318. /package/dist/web/assets/{hcl-QmNZdAtI.js → hcl-VOjEibVB.js} +0 -0
  319. /package/dist/web/assets/{hjson-CboJsAzK.js → hjson-BHEn7pNn.js} +0 -0
  320. /package/dist/web/assets/{hlsl-Bd-DO_WL.js → hlsl-CrvxlGii.js} +0 -0
  321. /package/dist/web/assets/{horizon-CU8Bi_ss.js → horizon-D3T-P0u6.js} +0 -0
  322. /package/dist/web/assets/{horizon-bright-iSQ3_3jP.js → horizon-bright-vifGsEdk.js} +0 -0
  323. /package/dist/web/assets/{houston-CTXv3Puz.js → houston-IrOgT7r4.js} +0 -0
  324. /package/dist/web/assets/{hy-Cd4hTidD.js → hy-5eSgTJ8G.js} +0 -0
  325. /package/dist/web/assets/{image-gallery-J8h8IY0c.js → image-gallery-COea0nSk.js} +0 -0
  326. /package/dist/web/assets/{imba-BipCHEY2.js → imba-Dp0I4DVl.js} +0 -0
  327. /package/dist/web/assets/{ini-Dd1KkMrB.js → ini-CHDKad9O.js} +0 -0
  328. /package/dist/web/assets/{java-rGr0OQD8.js → java-YLv7IDJ1.js} +0 -0
  329. /package/dist/web/assets/{javascript-DHhCH2TN.js → javascript-jr4kIdgl.js} +0 -0
  330. /package/dist/web/assets/{json-CMMLBCUf.js → json-EJWSOZfp.js} +0 -0
  331. /package/dist/web/assets/{json5-mPOwTOsB.js → json5-D6f_uNwJ.js} +0 -0
  332. /package/dist/web/assets/{jsonc-Bie0E6D3.js → jsonc-DrHCdmos.js} +0 -0
  333. /package/dist/web/assets/{jsonl-CpqHmtC1.js → jsonl-Cwc3cXEL.js} +0 -0
  334. /package/dist/web/assets/{jsonnet-D21Ms51e.js → jsonnet-BwZfaIFT.js} +0 -0
  335. /package/dist/web/assets/{jssm-BXnl1nur.js → jssm-BpEmg_MT.js} +0 -0
  336. /package/dist/web/assets/{jsx-Chnii_vB.js → jsx-DBGPwcr4.js} +0 -0
  337. /package/dist/web/assets/{kanagawa-dragon-DhxR0UjL.js → kanagawa-dragon-DRfVaGIX.js} +0 -0
  338. /package/dist/web/assets/{kanagawa-lotus-fupRg5wp.js → kanagawa-lotus-CjOlny0Q.js} +0 -0
  339. /package/dist/web/assets/{kanagawa-wave-DSWbRS9M.js → kanagawa-wave-DvdM88a4.js} +0 -0
  340. /package/dist/web/assets/{kdl-DirGHqUy.js → kdl-DSo3PvM0.js} +0 -0
  341. /package/dist/web/assets/{key-round-oIll4vo-.js → key-round-Cv4z7_KG.js} +0 -0
  342. /package/dist/web/assets/{keyboard-BLwfiRkT.js → keyboard-HG0BUtuN.js} +0 -0
  343. /package/dist/web/assets/{kotlin-DkhUVMDC.js → kotlin-BV8TwCGu.js} +0 -0
  344. /package/dist/web/assets/{kusto-DU7OpovF.js → kusto-DCo1Fdmm.js} +0 -0
  345. /package/dist/web/assets/{laserwave-iLKb1ZCT.js → laserwave-DPX9FvD9.js} +0 -0
  346. /package/dist/web/assets/{lean-Cuvh_QAP.js → lean-Cya8dqZu.js} +0 -0
  347. /package/dist/web/assets/{less-B5tQZOdI.js → less-CJUPgkIs.js} +0 -0
  348. /package/dist/web/assets/{lib-BAsciSLw.js → lib-DUBAP_Gd.js} +0 -0
  349. /package/dist/web/assets/{libesm-CdttTIAd.js → libesm-CcPYXCKp.js} +0 -0
  350. /package/dist/web/assets/{light-plus-DiHU2KL5.js → light-plus-BXXrlFJH.js} +0 -0
  351. /package/dist/web/assets/{llvm-sCBTKCKN.js → llvm-CUbQanZr.js} +0 -0
  352. /package/dist/web/assets/{loader-circle-DxI3O9_f.js → loader-circle-H81ywCuQ.js} +0 -0
  353. /package/dist/web/assets/{log-DtyR34Ie.js → log-B3fFlSMd.js} +0 -0
  354. /package/dist/web/assets/{logo-CP91aQyG.js → logo-ucAyw6zf.js} +0 -0
  355. /package/dist/web/assets/{luau-nfGo2ulP.js → luau-C4l6TSTB.js} +0 -0
  356. /package/dist/web/assets/{make-XbDn9GHe.js → make-CDtGIVc7.js} +0 -0
  357. /package/dist/web/assets/{markdown-BB1_3xLr.js → markdown-CH1zKu2p.js} +0 -0
  358. /package/dist/web/assets/{material-theme-CIx_sxAy.js → material-theme-CEuGVTmh.js} +0 -0
  359. /package/dist/web/assets/{material-theme-darker-DsQeueDD.js → material-theme-darker-CUZ3MoIr.js} +0 -0
  360. /package/dist/web/assets/{material-theme-lighter-x_lMi74j.js → material-theme-lighter-DxAqJSid.js} +0 -0
  361. /package/dist/web/assets/{material-theme-ocean-Bkgh25P8.js → material-theme-ocean-BSvvHJp6.js} +0 -0
  362. /package/dist/web/assets/{material-theme-palenight-CoOjdbti.js → material-theme-palenight-QVOl50_m.js} +0 -0
  363. /package/dist/web/assets/{matlab-D6xZas_8.js → matlab-CZLQLwUp.js} +0 -0
  364. /package/dist/web/assets/{mdx-Cl5_YNoz.js → mdx-DO4NJsOo.js} +0 -0
  365. /package/dist/web/assets/{mermaid-8Eow4jz_.js → mermaid-CIwzg1uO.js} +0 -0
  366. /package/dist/web/assets/{min-dark-D4DhjgRE.js → min-dark-BdIgslXy.js} +0 -0
  367. /package/dist/web/assets/{min-light-DzAckd0t.js → min-light-DyU-T1r2.js} +0 -0
  368. /package/dist/web/assets/{mipsasm-zI_zu0tj.js → mipsasm-DRad-Klm.js} +0 -0
  369. /package/dist/web/assets/{mojo-DQnGGPHf.js → mojo-DXp5LDOc.js} +0 -0
  370. /package/dist/web/assets/{monitor-CG69bSMW.js → monitor-CKcYUoAV.js} +0 -0
  371. /package/dist/web/assets/{monokai-CrFoD2VD.js → monokai-BiKX3qby.js} +0 -0
  372. /package/dist/web/assets/{moonbit-DdphIGs6.js → moonbit-BOUoLF5r.js} +0 -0
  373. /package/dist/web/assets/{move-BUlkn0xW.js → move-Dlk64FWK.js} +0 -0
  374. /package/dist/web/assets/{narrat-CbOBdtCn.js → narrat-B-qd2Lh0.js} +0 -0
  375. /package/dist/web/assets/{nextflow-groovy-CeVLUTuQ.js → nextflow-groovy-iAMYas0F.js} +0 -0
  376. /package/dist/web/assets/{night-owl-Bm4LhUR1.js → night-owl-3YNqjftR.js} +0 -0
  377. /package/dist/web/assets/{night-owl-light-DtcBiMEf.js → night-owl-light-GIncHb5w.js} +0 -0
  378. /package/dist/web/assets/{nix-DrdwQ70g.js → nix-xjlEb3uw.js} +0 -0
  379. /package/dist/web/assets/{nord-B0Head1v.js → nord-C8tvWx7P.js} +0 -0
  380. /package/dist/web/assets/{nushell-CmUdltKn.js → nushell-BqBb4pU6.js} +0 -0
  381. /package/dist/web/assets/{objective-c-BGDR33XN.js → objective-c-Bk6s0Cn5.js} +0 -0
  382. /package/dist/web/assets/{objective-cpp-Buc1Zhd0.js → objective-cpp-DGTVWQ3V.js} +0 -0
  383. /package/dist/web/assets/{ocaml-xdzl9rRD.js → ocaml-D6wPQ4kw.js} +0 -0
  384. /package/dist/web/assets/{odin-DiUFngnd.js → odin-C9mw2xRN.js} +0 -0
  385. /package/dist/web/assets/{one-dark-pro-BURxmIp3.js → one-dark-pro-SMBlneFb.js} +0 -0
  386. /package/dist/web/assets/{one-light-BMRMInAj.js → one-light-C9JMU1Cx.js} +0 -0
  387. /package/dist/web/assets/{openscad-DAgLA5J3.js → openscad-C0I9CtuA.js} +0 -0
  388. /package/dist/web/assets/{pascal-CoDZxcRB.js → pascal-D0z4DJnY.js} +0 -0
  389. /package/dist/web/assets/{pkl-DzKM6BuM.js → pkl-CITYNGVz.js} +0 -0
  390. /package/dist/web/assets/{plastic-vF15LmNS.js → plastic-Bf0T6rmg.js} +0 -0
  391. /package/dist/web/assets/{plsql-C1v07teA.js → plsql-Chr907pu.js} +0 -0
  392. /package/dist/web/assets/{po-CLLC8BuA.js → po-07U75CYV.js} +0 -0
  393. /package/dist/web/assets/{poimandres-Uq0xysxM.js → poimandres-B0T4qwXY.js} +0 -0
  394. /package/dist/web/assets/{polar-2-luY1Pc.js → polar-BvNJMMV5.js} +0 -0
  395. /package/dist/web/assets/{portal-container-context-DeLx1cOI.js → portal-container-context-Bqn516X4.js} +0 -0
  396. /package/dist/web/assets/{postcss-lbFhe0rz.js → postcss-BSdf-zzo.js} +0 -0
  397. /package/dist/web/assets/{power-CvtnQHU4.js → power-D_wlLkC0.js} +0 -0
  398. /package/dist/web/assets/{powerquery-RL8O9Wie.js → powerquery-B2Ad_HK8.js} +0 -0
  399. /package/dist/web/assets/{powershell-upFWhb-b.js → powershell-DO5WY2v2.js} +0 -0
  400. /package/dist/web/assets/{prisma-DBtYaWFk.js → prisma-BfaRPYzs.js} +0 -0
  401. /package/dist/web/assets/{prolog-D8jSMykJ.js → prolog-Cz0Nue9e.js} +0 -0
  402. /package/dist/web/assets/{proto-BM4eadF7.js → proto-FVleUZJO.js} +0 -0
  403. /package/dist/web/assets/{puppet-BQDQ3Snu.js → puppet-BEX5o7hE.js} +0 -0
  404. /package/dist/web/assets/{purescript-Cj2aTX4s.js → purescript-BZX6Kw4j.js} +0 -0
  405. /package/dist/web/assets/{python-BYpqq6u4.js → python-CO89UIxE.js} +0 -0
  406. /package/dist/web/assets/{qmldir-4uiTcwAu.js → qmldir-DH526DWB.js} +0 -0
  407. /package/dist/web/assets/{qss-D5xB-Mqo.js → qss-wp8im4Iz.js} +0 -0
  408. /package/dist/web/assets/{r-P6Ujy8rf.js → r-F9n--bvq.js} +0 -0
  409. /package/dist/web/assets/{racket-COKgCFuM.js → racket-BQvbOE5D.js} +0 -0
  410. /package/dist/web/assets/{raku-z14Q9i7K.js → raku-B0iWSynj.js} +0 -0
  411. /package/dist/web/assets/{react-DqIU0LFM.js → react-Bcm1Oab0.js} +0 -0
  412. /package/dist/web/assets/{red-ObAvgvQ5.js → red-Cm00r9eI.js} +0 -0
  413. /package/dist/web/assets/{reg-Qv4f0JFA.js → reg-CBuhna22.js} +0 -0
  414. /package/dist/web/assets/{regexp-CEOVGIzy.js → regexp-C9j1_6oU.js} +0 -0
  415. /package/dist/web/assets/{rel-cWOyTUwd.js → rel-BYzlBhbq.js} +0 -0
  416. /package/dist/web/assets/{resolve-theme-CMp5xxCW.js → resolve-theme-Dm8ehbOv.js} +0 -0
  417. /package/dist/web/assets/{riscv-BZDwx-lv.js → riscv-CQQP0Ro9.js} +0 -0
  418. /package/dist/web/assets/{ron-BpjosPS0.js → ron-j1ON9YzM.js} +0 -0
  419. /package/dist/web/assets/{rose-pine-DhxfJWcm.js → rose-pine-Cbri3jon.js} +0 -0
  420. /package/dist/web/assets/{rose-pine-dawn-BbGt9Wy_.js → rose-pine-dawn-BMuvKrGo.js} +0 -0
  421. /package/dist/web/assets/{rose-pine-moon-dj4Zxgik.js → rose-pine-moon-4biZzaYD.js} +0 -0
  422. /package/dist/web/assets/{rosmsg-EciOaHo2.js → rosmsg-CXx22rtz.js} +0 -0
  423. /package/dist/web/assets/{rust-C_eH59O_.js → rust-D28cFIhL.js} +0 -0
  424. /package/dist/web/assets/{sass-Dos3R5lL.js → sass-DtNw4V28.js} +0 -0
  425. /package/dist/web/assets/{save-B1y4KIK9.js → save-BehCuMf4.js} +0 -0
  426. /package/dist/web/assets/{scala-8lVKsTvf.js → scala-hv69_YQC.js} +0 -0
  427. /package/dist/web/assets/{scheme-Bd3VdaZj.js → scheme-Dtp9B_ng.js} +0 -0
  428. /package/dist/web/assets/{sdbl-C4Yrjlgh.js → sdbl-DEwEngAE.js} +0 -0
  429. /package/dist/web/assets/{send-B9VUQlEK.js → send-CtXcGcsk.js} +0 -0
  430. /package/dist/web/assets/{shellscript-OFZbPKZH.js → shellscript-CCOF9tox.js} +0 -0
  431. /package/dist/web/assets/{shield-check-BJSX7cAS.js → shield-check-z9PX8HVZ.js} +0 -0
  432. /package/dist/web/assets/{shield-off-E1cQwXdc.js → shield-off-Du0U5dVI.js} +0 -0
  433. /package/dist/web/assets/{slack-dark-aL6vlxZs.js → slack-dark-DT0E0ABt.js} +0 -0
  434. /package/dist/web/assets/{slack-ochin-BKt1E7sL.js → slack-ochin-DHHiQnxo.js} +0 -0
  435. /package/dist/web/assets/{smalltalk-D6qVBL1U.js → smalltalk-BF_I35xJ.js} +0 -0
  436. /package/dist/web/assets/{snazzy-light-BrWerT0t.js → snazzy-light-Cv7tIZo9.js} +0 -0
  437. /package/dist/web/assets/{solarized-dark-CzxTJgVQ.js → solarized-dark-wZ5YPCys.js} +0 -0
  438. /package/dist/web/assets/{solarized-light-BecaDAnG.js → solarized-light-DGDOr1AS.js} +0 -0
  439. /package/dist/web/assets/{solidity-C9t7pZ84.js → solidity-BJknuPqJ.js} +0 -0
  440. /package/dist/web/assets/{sparkles-blTKn0vi.js → sparkles-CO9zx1f-.js} +0 -0
  441. /package/dist/web/assets/{splunk-CtxfFKtF.js → splunk-B1ClO_KU.js} +0 -0
  442. /package/dist/web/assets/{sql-7FE_Duz0.js → sql-CXZ66NtF.js} +0 -0
  443. /package/dist/web/assets/{ssh-config-3Fr37ACC.js → ssh-config-kgM67Sf6.js} +0 -0
  444. /package/dist/web/assets/{stylus-BP4mE1sO.js → stylus-RcVaInR-.js} +0 -0
  445. /package/dist/web/assets/{swift-0uqTFouD.js → swift-Cm0fh2lX.js} +0 -0
  446. /package/dist/web/assets/{synthwave-84-DQaNM3DI.js → synthwave-84-CwLiazxr.js} +0 -0
  447. /package/dist/web/assets/{system-verilog-DUIVrZHZ.js → system-verilog-CzYaDVLH.js} +0 -0
  448. /package/dist/web/assets/{systemd-CtNo_WIh.js → systemd-DbSagfLw.js} +0 -0
  449. /package/dist/web/assets/{table-8HT8BG30.js → table-BK4h8E7u.js} +0 -0
  450. /package/dist/web/assets/{talonscript-B0HXaCVT.js → talonscript-BCFnWejL.js} +0 -0
  451. /package/dist/web/assets/{tasl-Cb7RAl11.js → tasl-BUdqtEe1.js} +0 -0
  452. /package/dist/web/assets/{tcl-B79aC6l5.js → tcl-CR_lTV9N.js} +0 -0
  453. /package/dist/web/assets/{terraform-75jJDjpW.js → terraform-Bqsha-xe.js} +0 -0
  454. /package/dist/web/assets/{text-wrap-DafY0-Pa.js → text-wrap-DLtVgSnU.js} +0 -0
  455. /package/dist/web/assets/{tokyo-night-Cz9Uh9qb.js → tokyo-night-Cnuo6JB6.js} +0 -0
  456. /package/dist/web/assets/{toml-CD6y9A-z.js → toml-CLFdhT22.js} +0 -0
  457. /package/dist/web/assets/{tsv-CXJMbBrb.js → tsv-Dw3tLrZN.js} +0 -0
  458. /package/dist/web/assets/{tsx-BuYN0I2t.js → tsx-B8k1sFqw.js} +0 -0
  459. /package/dist/web/assets/{turtle-DWH-Rjse.js → turtle-BMKMfTrj.js} +0 -0
  460. /package/dist/web/assets/{typescript-BPd-hsrR.js → typescript-D38LfGSl.js} +0 -0
  461. /package/dist/web/assets/{typespec-B0wvVykx.js → typespec-EbgGJHV_.js} +0 -0
  462. /package/dist/web/assets/{typst-DWG2c48-.js → typst-CQXV2SzX.js} +0 -0
  463. /package/dist/web/assets/{use-coarse-long-press-BsBpxWup.js → use-coarse-long-press-XrJ4Upuv.js} +0 -0
  464. /package/dist/web/assets/{use-is-mobile-Bi42QhIi.js → use-is-mobile-Dypg-2ZO.js} +0 -0
  465. /package/dist/web/assets/{use-visual-viewport-CNdG4QHH.js → use-visual-viewport-Bj3QHRkF.js} +0 -0
  466. /package/dist/web/assets/{utils-IrnQujwR.js → utils-CwNUra6_.js} +0 -0
  467. /package/dist/web/assets/{v-Ch6E4Egd.js → v-Ci1jObJJ.js} +0 -0
  468. /package/dist/web/assets/{vala-CGVKwbPx.js → vala-C_NdfqrY.js} +0 -0
  469. /package/dist/web/assets/{vb-BIEbSxyT.js → vb-K_r_h_s8.js} +0 -0
  470. /package/dist/web/assets/{vendor-xterm-YQlzIWv2.js → vendor-xterm-BtjgHRUe.js} +0 -0
  471. /package/dist/web/assets/{verilog-A-3pYPad.js → verilog-DQPYLsZI.js} +0 -0
  472. /package/dist/web/assets/{vesper-CK1naZAV.js → vesper-BrmzEV8s.js} +0 -0
  473. /package/dist/web/assets/{vhdl-CVawmgMg.js → vhdl-CjxQGaH2.js} +0 -0
  474. /package/dist/web/assets/{viml-CiWjaqBY.js → viml-CTKJNQH1.js} +0 -0
  475. /package/dist/web/assets/{vitesse-black-PYXW4-BO.js → vitesse-black-i-H_3p1i.js} +0 -0
  476. /package/dist/web/assets/{vitesse-dark-BU5s4AuG.js → vitesse-dark-DZC_Yy3_.js} +0 -0
  477. /package/dist/web/assets/{vitesse-light-DgkIT-N7.js → vitesse-light-rf4kpmk8.js} +0 -0
  478. /package/dist/web/assets/{vyper-D8cRDPp3.js → vyper-BLnOw4Nf.js} +0 -0
  479. /package/dist/web/assets/{wasm-ClFJgzmT.js → wasm-CWeHvGNG.js} +0 -0
  480. /package/dist/web/assets/{wasm-C02wlRbP.js → wasm-DbLMmiW0.js} +0 -0
  481. /package/dist/web/assets/{wenyan-B8plxIr8.js → wenyan-CLwdRuzd.js} +0 -0
  482. /package/dist/web/assets/{wgsl-CVujtm3V.js → wgsl-CBTDMVJR.js} +0 -0
  483. /package/dist/web/assets/{wikitext-CmcG9B69.js → wikitext-CQHrF84e.js} +0 -0
  484. /package/dist/web/assets/{wit--gl2Jium.js → wit-8xdbdipU.js} +0 -0
  485. /package/dist/web/assets/{wolfram-6T_1D-NS.js → wolfram-tFwx32a_.js} +0 -0
  486. /package/dist/web/assets/{x-Bdaog6Az.js → x-DlnNFF2t.js} +0 -0
  487. /package/dist/web/assets/{yaml-CIVV9uA1.js → yaml-BP8N91fU.js} +0 -0
  488. /package/dist/web/assets/{zenscript-CoT4yNdA.js → zenscript-B10Pj7JT.js} +0 -0
  489. /package/dist/web/assets/{zig-BWs2Qo3G.js → zig-BZKcTtrK.js} +0 -0
@@ -19,9 +19,11 @@ import {
19
19
  peekCodexAccount,
20
20
  selectCodexAccount,
21
21
  getAllCodexUsages,
22
+ getCodexAccountUsage,
22
23
  codexUsageLevel,
23
24
  type CodexAccount,
24
25
  } from "../../services/codex-account.service.ts";
26
+ import { dailyGuardMessage, dailyGuardState } from "../../shared/codex-daily-guard.ts";
25
27
  import { isCodexAccountUsageLimited, markCodexAccountUsageLimited } from "../../services/codex-account-cooldown.ts";
26
28
  import { isCodexUsageLimit, codexErrorMessage, parseCodexUsageLimitReset } from "./codex-usage-limit.ts";
27
29
  import { killProcessTree } from "../../services/windows-process-tree.ts";
@@ -157,6 +159,8 @@ interface LiveSession {
157
159
  * nothing downstream can notice. Follow-ups therefore wait in `pendingTurns`
158
160
  * and are sent when the running turn reports `turn/completed`. */
159
161
  turnInFlight?: boolean;
162
+ /** A daily-guard usage read is in progress before the next turn starts. */
163
+ checkingDailyGuard?: boolean;
160
164
  /** Id of the running turn — `turn/interrupt` needs it, `threadId` alone is rejected. */
161
165
  activeTurnId?: string | null;
162
166
  /** Interrupt asked for before `turn/started` named the turn; fired on arrival. */
@@ -397,7 +401,7 @@ export class CodexAppServerProvider implements AIProvider {
397
401
  return;
398
402
  }
399
403
  }
400
- this.startTurn(live, message, opts);
404
+ void this.startTurn(live, message, opts);
401
405
  for await (const ev of live.channel.iterator) {
402
406
  yield ev;
403
407
  }
@@ -407,7 +411,23 @@ export class CodexAppServerProvider implements AIProvider {
407
411
  pushMessage(sessionId: string, content: string, opts?: SendMessageOpts): void {
408
412
  const live = this.live.get(sessionId);
409
413
  if (!live || live.client.isClosed) return;
410
- this.startTurn(live, content, opts);
414
+ void this.startTurn(live, content, opts);
415
+ }
416
+
417
+ /** Return a refusal only when this session's managed account opted into pacing. */
418
+ private async dailyGuardError(live: LiveSession): Promise<string | null> {
419
+ const accountId = live.threadId ? getSessionCodexAccount(live.threadId) : null;
420
+ const account = accountId ? getCodexAccount(accountId) : null;
421
+ if (!account?.dailyGuardEnabled) return null;
422
+ try {
423
+ const usage = await getCodexAccountUsage(account.id);
424
+ const state = usage.session == null ? dailyGuardState(usage.weekly) : null;
425
+ return state?.blocked ? dailyGuardMessage(state) : null;
426
+ } catch {
427
+ // An unreadable quota cannot honestly be called spent. Keep the account usable and let
428
+ // Codex's real quota refusal remain the authority until the next successful usage read.
429
+ return null;
430
+ }
411
431
  }
412
432
 
413
433
  /**
@@ -418,7 +438,7 @@ export class CodexAppServerProvider implements AIProvider {
418
438
  * second entry would both show it twice and shift every later `rollout-N` id, which
419
439
  * fork anchors resolve against.
420
440
  */
421
- private startTurn(live: LiveSession, message: string, opts?: SendMessageOpts, replay = false): void {
441
+ private async startTurn(live: LiveSession, message: string, opts?: SendMessageOpts, replay = false): Promise<void> {
422
442
  if (!live.threadId) return;
423
443
  // One turn at a time — anything sent now would be dropped without a trace.
424
444
  // `now` additionally cuts the running turn short so this one answers next.
@@ -428,6 +448,19 @@ export class CodexAppServerProvider implements AIProvider {
428
448
  if (priority === "now") this.interruptActiveTurn(live);
429
449
  return;
430
450
  }
451
+ if (live.checkingDailyGuard) {
452
+ this.enqueueTurn(live, { message, opts, priority: opts?.priority ?? "next" });
453
+ return;
454
+ }
455
+ live.checkingDailyGuard = true;
456
+ const guardError = await this.dailyGuardError(live);
457
+ live.checkingDailyGuard = false;
458
+ if (guardError) {
459
+ live.channel.push({ type: "error", message: guardError });
460
+ live.channel.push({ type: "done", sessionId: live.threadId, resultSubtype: "error_during_execution" });
461
+ this.endTurn(live);
462
+ return;
463
+ }
431
464
  live.turnInFlight = true;
432
465
  // `/compact` → trigger codex's real compaction (thread/compact/start), not a text turn.
433
466
  // Completion is surfaced on the `thread/compacted` notification (handleNotification).
@@ -516,7 +549,7 @@ export class CodexAppServerProvider implements AIProvider {
516
549
  live.interruptRequested = false;
517
550
  live.lastTurnInput = undefined;
518
551
  const next = live.pendingTurns.shift();
519
- if (next) this.startTurn(live, next.message, next.opts);
552
+ if (next) void this.startTurn(live, next.message, next.opts);
520
553
  }
521
554
 
522
555
  // ── Usage-limit rotation ──
@@ -593,7 +626,7 @@ export class CodexAppServerProvider implements AIProvider {
593
626
  live.turnInFlight = false;
594
627
  live.activeTurnId = null;
595
628
  live.interruptRequested = false;
596
- if (pending) this.startTurn(live, pending.message, pending.opts, true);
629
+ if (pending) void this.startTurn(live, pending.message, pending.opts, true);
597
630
  else this.endTurn(live);
598
631
  }
599
632
 
@@ -1,5 +1,6 @@
1
1
  import type { UsageInfo, LimitBucket } from "../provider.interface.ts";
2
2
  import type { GetAccountRateLimitsResponse, RateLimitWindow } from "./codex-protocol.ts";
3
+ import { codexPlanLabel } from "../../shared/codex-plan-label.ts";
3
4
 
4
5
  /** codex resetsAt is a unix timestamp; tolerate seconds or milliseconds. */
5
6
  function toIso(resetsAt: number | null | undefined): string | undefined {
@@ -64,6 +65,7 @@ export function parseCodexUsage(res: GetAccountRateLimitsResponse | null | undef
64
65
  out.session = toBucket(w);
65
66
  }
66
67
  });
67
- if (snap.planType) out.activeAccountLabel = String(snap.planType);
68
+ const planLabel = codexPlanLabel(snap.planType);
69
+ if (planLabel) out.activeAccountLabel = planLabel;
68
70
  return out;
69
71
  }
@@ -1,6 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import { ok, err } from "../../types/api.ts";
3
- import { listCodexAccounts, removeCodexAccount, getAllCodexUsages, getCodexStrategy, setCodexStrategy, selectCodexAccount, setCodexAccountStatus, codexUsageLevel, type CodexStrategy } from "../../services/codex-account.service.ts";
3
+ import { listCodexAccounts, removeCodexAccount, getAllCodexUsages, getCodexStrategy, setCodexStrategy, selectCodexAccount, setCodexAccountStatus, setCodexDailyGuard, codexUsageLevel, type CodexStrategy } from "../../services/codex-account.service.ts";
4
4
  import { addApiKeyAccount, startDeviceLogin, getDeviceLoginStatus, cancelDeviceLogin, startBrowserLogin, submitBrowserCallback, getBrowserLoginStatus, cancelBrowserLogin } from "../../services/codex-account-login.ts";
5
5
  import { exportCodexEncrypted, importCodexEncrypted } from "../../services/codex-account-portability.ts";
6
6
 
@@ -43,11 +43,15 @@ codexAccountsRoutes.post("/pick", async (c) => {
43
43
  * immediately instead of taking the better part of a minute.
44
44
  */
45
45
  codexAccountsRoutes.patch("/:id", async (c) => {
46
- const body = await c.req.json<{ status?: string }>().catch(() => ({} as { status?: string }));
47
- if (body.status !== "active" && body.status !== "disabled") {
48
- return c.json(err("status must be active or disabled"), 400);
46
+ const body = await c.req.json<{ status?: string; dailyGuardEnabled?: unknown }>().catch(() => ({} as { status?: string; dailyGuardEnabled?: unknown }));
47
+ if (body.status !== undefined) {
48
+ if (body.status !== "active" && body.status !== "disabled") return c.json(err("status must be active or disabled"), 400);
49
+ const updated = setCodexAccountStatus(c.req.param("id"), body.status);
50
+ if (!updated) return c.json(err("Account not found"), 404);
51
+ return c.json(ok(updated));
49
52
  }
50
- const updated = setCodexAccountStatus(c.req.param("id"), body.status);
53
+ if (typeof body.dailyGuardEnabled !== "boolean") return c.json(err("status or dailyGuardEnabled is required"), 400);
54
+ const updated = setCodexDailyGuard(c.req.param("id"), body.dailyGuardEnabled);
51
55
  if (!updated) return c.json(err("Account not found"), 404);
52
56
  return c.json(ok(updated));
53
57
  });
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import { randomUUID } from "node:crypto";
17
17
  import { mkdirSync, rmSync } from "node:fs";
18
- import { buildCodexCallback, checkCodexLoginPort, parseBrowserLogin, type BrowserLoginCallback } from "./codex-login-callback.ts";
18
+ import { buildCodexCallback, buildCodexSuccessCallback, checkCodexLoginPort, parseBrowserLogin, type BrowserLoginCallback } from "./codex-login-callback.ts";
19
19
  import { CodexJsonRpcClient, CONTROL_REQUEST_TIMEOUT_MS } from "../providers/codex-app-server/codex-jsonrpc-client.ts";
20
20
  import { codexAccountHome, createCodexAccount, type CodexAccount } from "./codex-account.service.ts";
21
21
 
@@ -218,18 +218,46 @@ export function submitBrowserCallback(id: string, callbackUrl: string, send: typ
218
218
  browser.submitted = true;
219
219
  const controller = new AbortController();
220
220
  p.callbackAbort = controller;
221
- const timeout = unref(setTimeout(() => controller.abort(), 30_000));
221
+ let timedOut = false;
222
+ const timeout = unref(setTimeout(() => {
223
+ timedOut = true;
224
+ controller.abort();
225
+ // Bun can leave a loopback fetch pending after its AbortSignal fires. Do not leave the
226
+ // browser polling forever: the callback code cannot safely be reused, so make the
227
+ // failure visible and let the user start a fresh authorization.
228
+ if (isCurrentPendingLogin(id, p)) {
229
+ settle(id, { state: "error", error: "Codex did not finish the callback within 30 seconds. Start a new browser login and try again." });
230
+ }
231
+ }, 30_000));
222
232
  void (async () => {
223
233
  try {
224
- const response = await send(target, { redirect: "manual", signal: controller.signal });
225
- // Do not render or log the OAuth response body or follow its redirect.
234
+ // Connect to 127.0.0.1 (never a user-controlled localhost resolution), but preserve
235
+ // the OAuth redirect's localhost Host header. Codex's loopback listener associates
236
+ // the callback with the redirect URI and otherwise accepts the socket without
237
+ // completing the login.
238
+ let response = await send(target, {
239
+ redirect: "manual",
240
+ signal: controller.signal,
241
+ headers: { Host: "localhost:1455" },
242
+ });
243
+ if (response.status >= 300 && response.status < 400) {
244
+ const location = response.headers.get("location");
245
+ await response.body?.cancel();
246
+ if (!location) throw new Error("Codex returned a callback redirect without a destination.");
247
+ response = await send(buildCodexSuccessCallback(location, browser), {
248
+ redirect: "manual",
249
+ signal: controller.signal,
250
+ headers: { Host: "localhost:1455" },
251
+ });
252
+ }
253
+ // Do not render or log either loopback OAuth response body.
226
254
  await response.body?.cancel();
227
255
  if (response.status >= 400 && isCurrentPendingLogin(id, p)) {
228
256
  settle(id, { state: "error", error: "Codex rejected the callback. Start a new browser login." });
229
257
  }
230
258
  } catch {
231
259
  // A closed callback socket may mean successful login. Polling owns the result.
232
- if (isCurrentPendingLogin(id, p)) browser.submitted = false;
260
+ if (!timedOut && isCurrentPendingLogin(id, p)) browser.submitted = false;
233
261
  } finally {
234
262
  clearTimeout(timeout);
235
263
  if (p.callbackAbort === controller) p.callbackAbort = undefined;
@@ -20,6 +20,7 @@ interface PortableCodexAccount {
20
20
  label: string;
21
21
  type: CodexAccountType;
22
22
  planType?: string | null;
23
+ dailyGuardEnabled?: boolean;
23
24
  authJson?: string | null; // contents of CODEX_HOME/auth.json
24
25
  creds?: CodexCreds | null; // apiKey creds (chatgpt auth lives in authJson)
25
26
  }
@@ -35,7 +36,7 @@ export function exportCodexEncrypted(password: string, accountIds?: string[]): s
35
36
  const authPath = join(a.home, "auth.json");
36
37
  if (existsSync(authPath)) authJson = readFileSync(authPath, "utf8");
37
38
  } catch { /* ignore unreadable home */ }
38
- return { id: a.id, label: a.label, type: a.type, planType: a.planType ?? null, authJson, creds: getCodexAccountCreds(a.id) };
39
+ return { id: a.id, label: a.label, type: a.type, planType: a.planType ?? null, dailyGuardEnabled: a.dailyGuardEnabled, authJson, creds: getCodexAccountCreds(a.id) };
39
40
  });
40
41
  return encryptWithPassword(JSON.stringify({ magic: BACKUP_MAGIC, accounts: portable }), password);
41
42
  }
@@ -56,7 +57,7 @@ export function importCodexEncrypted(blob: string, password: string): { imported
56
57
  // createCodexAccount inserts the row and mkdirs the CODEX_HOME (0700).
57
58
  createCodexAccount({
58
59
  id: p.id, label: p.label || "Imported", type: p.type,
59
- planType: p.planType ?? null, creds: p.creds ?? undefined,
60
+ planType: p.planType ?? null, creds: p.creds ?? undefined, dailyGuardEnabled: p.dailyGuardEnabled !== false,
60
61
  });
61
62
 
62
63
  // Restore auth.json so codex re-auths from it on next spawn.
@@ -16,6 +16,7 @@ import { configService } from "./config.service.ts";
16
16
  import { encrypt, decrypt } from "../lib/account-crypto.ts";
17
17
  import { getOrFetchUsage } from "./provider-usage/usage-registry.ts";
18
18
  import { isCodexAccountUsageLimited } from "./codex-account-cooldown.ts";
19
+ import { dailyGuardMessage, dailyGuardState } from "../shared/codex-daily-guard.ts";
19
20
  import type { UsageInfo } from "../providers/provider.interface.ts";
20
21
 
21
22
  export type CodexStrategy = "round-robin" | "fill-first" | "lowest-usage";
@@ -32,6 +33,7 @@ export interface CodexAccount {
32
33
  home: string;
33
34
  planType?: string | null;
34
35
  status: CodexAccountStatus;
36
+ dailyGuardEnabled: boolean;
35
37
  addedAt: string;
36
38
  }
37
39
 
@@ -44,6 +46,7 @@ interface Row {
44
46
  id: string; label: string | null; type: string; home: string;
45
47
  plan_type: string | null; creds_enc: string | null; added_at: string;
46
48
  status?: string | null;
49
+ daily_guard_enabled?: number | null;
47
50
  }
48
51
 
49
52
  function rowToAccount(r: Row): CodexAccount {
@@ -56,6 +59,7 @@ function rowToAccount(r: Row): CodexAccount {
56
59
  // A row written before the column existed reads as null; treat that as enabled, which
57
60
  // is what it effectively was.
58
61
  status: r.status === "disabled" ? "disabled" : "active",
62
+ dailyGuardEnabled: r.daily_guard_enabled !== 0,
59
63
  addedAt: r.added_at,
60
64
  };
61
65
  }
@@ -87,7 +91,7 @@ export function getCodexAccountCreds(id: string): CodexCreds | null {
87
91
  * verified label/planType and the creds to persist (encrypted). Idempotent dir create.
88
92
  */
89
93
  export function createCodexAccount(input: {
90
- label: string; type: CodexAccountType; planType?: string | null; creds?: CodexCreds; id?: string;
94
+ label: string; type: CodexAccountType; planType?: string | null; creds?: CodexCreds; id?: string; dailyGuardEnabled?: boolean;
91
95
  }): CodexAccount {
92
96
  const id = input.id ?? randomUUID();
93
97
  const home = codexAccountHome(id);
@@ -98,8 +102,8 @@ export function createCodexAccount(input: {
98
102
  const credsEnc = input.creds ? encrypt(JSON.stringify(input.creds)) : null;
99
103
  try {
100
104
  getDb().query(
101
- "INSERT INTO codex_accounts (id, label, type, home, plan_type, creds_enc) VALUES (?, ?, ?, ?, ?, ?)",
102
- ).run(id, input.label, input.type, home, input.planType ?? null, credsEnc);
105
+ "INSERT INTO codex_accounts (id, label, type, home, plan_type, creds_enc, daily_guard_enabled) VALUES (?, ?, ?, ?, ?, ?, ?)",
106
+ ).run(id, input.label, input.type, home, input.planType ?? null, credsEnc, input.dailyGuardEnabled === false ? 0 : 1);
103
107
  } catch (e) {
104
108
  // Keep the invariant row⟺home: drop the dir if the row didn't land.
105
109
  try { rmSync(home, { recursive: true, force: true }); } catch { /* ignore */ }
@@ -136,6 +140,15 @@ export function setCodexAccountStatus(id: string, status: CodexAccountStatus): C
136
140
  return getCodexAccount(id);
137
141
  }
138
142
 
143
+ /** Enable or disable the seven-day quota pacing guard for one account. */
144
+ export function setCodexDailyGuard(id: string, enabled: boolean): CodexAccount | null {
145
+ if (!getCodexAccount(id)) return null;
146
+ getDb().query("UPDATE codex_accounts SET daily_guard_enabled = ? WHERE id = ?").run(enabled ? 1 : 0, id);
147
+ return getCodexAccount(id);
148
+ }
149
+
150
+ export class CodexDailyGuardError extends Error {}
151
+
139
152
  /** Remove the account row and its CODEX_HOME dir. */
140
153
  export function removeCodexAccount(id: string): void {
141
154
  const acct = getCodexAccount(id);
@@ -279,15 +292,43 @@ export async function resolveCodexAccountForSession(sessionId?: string): Promise
279
292
  // would do nothing for exactly the conversations already using it. An account parked for
280
293
  // an exhausted quota lets go for a different reason — it would refuse the turn, and
281
294
  // spending one to rediscover that is worse than starting on an account that can answer.
282
- if (sticky) {
283
- const a = getCodexAccount(sticky);
284
- if (a && a.status !== "disabled" && !isCodexAccountUsageLimited(a.id)) return a;
285
- }
286
295
  // Usage is only worth fetching when it can change the answer, and with at most one
287
296
  // account able to serve it cannot. Parked accounts count as unable for the same reason
288
297
  // they are skipped below, so a pool of two where one is out of quota resolves without a
289
298
  // network read at all.
290
299
  const usable = listCodexAccounts().filter((a) => a.status !== "disabled" && !isCodexAccountUsageLimited(a.id));
300
+ const guarded = usable.filter((a) => a.dailyGuardEnabled);
301
+ if (guarded.length > 0) {
302
+ const usages = await getAllCodexUsages();
303
+ const blocked = guarded.flatMap((a) => {
304
+ // Pacing is for plans that only expose the weekly bucket. A Plus account's separate
305
+ // five-hour window is already the useful short-term control and must not gain this row.
306
+ const usage = usages[a.id];
307
+ const state = usage?.session == null ? dailyGuardState(usage?.weekly) : null;
308
+ return state?.blocked ? [a.id] : [];
309
+ });
310
+ if (blocked.length > 0) {
311
+ const stickyAccount = sticky ? getCodexAccount(sticky) : null;
312
+ if (stickyAccount && !blocked.includes(stickyAccount.id)
313
+ && stickyAccount.status !== "disabled" && !isCodexAccountUsageLimited(stickyAccount.id)) return stickyAccount;
314
+ if (blocked.length === usable.length && sessionId) {
315
+ const account = getCodexAccount(blocked[0]!);
316
+ const usage = account ? usages[account.id] : undefined;
317
+ const state = usage?.session == null ? dailyGuardState(usage?.weekly) : null;
318
+ throw new CodexDailyGuardError(state ? dailyGuardMessage(state) : "Daily guard reached for every available Codex account.");
319
+ }
320
+ return selectCodexAccount({ usageOf: (id) => codexUsageLevel(usages[id]), exclude: blocked });
321
+ }
322
+ if (sticky) {
323
+ const a = getCodexAccount(sticky);
324
+ if (a && a.status !== "disabled" && !isCodexAccountUsageLimited(a.id)) return a;
325
+ }
326
+ return selectCodexAccount({ usageOf: (id) => codexUsageLevel(usages[id]) });
327
+ }
328
+ if (sticky) {
329
+ const a = getCodexAccount(sticky);
330
+ if (a && a.status !== "disabled" && !isCodexAccountUsageLimited(a.id)) return a;
331
+ }
291
332
  if (usable.length <= 1) return selectCodexAccount();
292
333
  // Usage is read for every strategy, not just lowest-usage: it is also what lets the
293
334
  // selector skip an account with no five-hour room left. Reading it only for lowest-usage
@@ -55,3 +55,21 @@ export function buildCodexCallback(callbackUrl: string, login: BrowserLoginCallb
55
55
  expected.searchParams.set("state", state!);
56
56
  return expected;
57
57
  }
58
+
59
+ /**
60
+ * Codex accepts the authorization callback, then redirects to its own loopback
61
+ * success endpoint with the exchanged id token. Follow exactly that endpoint
62
+ * while keeping the TCP connection on 127.0.0.1.
63
+ */
64
+ export function buildCodexSuccessCallback(location: string, login: BrowserLoginCallback): URL {
65
+ let redirect: URL;
66
+ try { redirect = new URL(location); } catch { throw new Error("Codex returned an invalid callback redirect."); }
67
+ const expected = new URL(login.redirectUri);
68
+ if (redirect.protocol !== "http:" || redirect.hostname !== "localhost" || redirect.port !== expected.port
69
+ || redirect.pathname !== "/success" || redirect.username || redirect.password || redirect.hash
70
+ || redirect.searchParams.getAll("id_token").length !== 1) {
71
+ throw new Error("Codex returned an unsupported callback redirect.");
72
+ }
73
+ redirect.hostname = "127.0.0.1";
74
+ return redirect;
75
+ }
@@ -1121,6 +1121,20 @@ export function runMigrations(database: Database): void {
1121
1121
  try { database.exec(`ALTER TABLE codex_accounts ADD COLUMN status TEXT NOT NULL DEFAULT 'active'`); } catch { /* exists */ }
1122
1122
  database.exec(`PRAGMA user_version = 47;`);
1123
1123
  }
1124
+
1125
+ if (current < 48) {
1126
+ // Optional per-account pacing for weekly-only Codex plans. Disabled by default so an
1127
+ // upgrade never changes how an existing account is selected or used.
1128
+ try { database.exec(`ALTER TABLE codex_accounts ADD COLUMN daily_guard_enabled INTEGER NOT NULL DEFAULT 0`); } catch { /* exists */ }
1129
+ database.exec(`PRAGMA user_version = 48;`);
1130
+ }
1131
+
1132
+ if (current < 49) {
1133
+ // Daily guard was introduced as an opt-in during development. Ship it enabled so every
1134
+ // weekly-only account starts paced; Plus accounts simply do not surface or use it.
1135
+ database.exec(`UPDATE codex_accounts SET daily_guard_enabled = 1`);
1136
+ database.exec(`PRAGMA user_version = 49;`);
1137
+ }
1124
1138
  }
1125
1139
 
1126
1140
  // ---------------------------------------------------------------------------
@@ -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
  })}