codex-multi-auth 2.17.3 → 2.19.0

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 (384) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +10 -4
  3. package/config/README.md +1 -1
  4. package/config/codex-legacy.json +12 -212
  5. package/config/codex-modern.json +4 -80
  6. package/config/minimal-codex.json +1 -1
  7. package/dist/lib/account-policy.d.ts +3 -1
  8. package/dist/lib/account-policy.js +21 -5
  9. package/dist/lib/codex-manager/commands/history.js +3 -1
  10. package/dist/lib/codex-manager/commands/status.js +8 -3
  11. package/dist/lib/codex-manager/formatters/subscription-status.d.ts +16 -0
  12. package/dist/lib/codex-manager/formatters/subscription-status.js +69 -0
  13. package/dist/lib/codex-manager/health-check.js +17 -12
  14. package/dist/lib/codex-manager/quota-cache-helpers.js +8 -4
  15. package/dist/lib/context-budget/model-context-windows.d.ts +1 -1
  16. package/dist/lib/context-budget/model-context-windows.js +10 -13
  17. package/dist/lib/model-route-policy.d.ts +1 -1
  18. package/dist/lib/oc-chatgpt-target-detection.d.ts +3 -2
  19. package/dist/lib/oc-chatgpt-target-detection.js +40 -13
  20. package/dist/lib/quota-cache.d.ts +6 -0
  21. package/dist/lib/quota-cache.js +33 -16
  22. package/dist/lib/quota-probe.d.ts +3 -0
  23. package/dist/lib/quota-probe.js +5 -4
  24. package/dist/lib/quota-readiness.d.ts +1 -1
  25. package/dist/lib/quota-readiness.js +6 -2
  26. package/dist/lib/request/error-classification.js +41 -52
  27. package/dist/lib/request/fetch-helpers.js +1 -1
  28. package/dist/lib/request/helpers/model-map.d.ts +2 -2
  29. package/dist/lib/request/helpers/model-map.js +120 -78
  30. package/dist/lib/request/request-transformer.d.ts +1 -1
  31. package/dist/lib/request/request-transformer.js +1 -1
  32. package/dist/lib/runtime/account-model-catalog.d.ts +1 -1
  33. package/dist/lib/runtime/model-discovery-status.d.ts +2 -2
  34. package/dist/lib/runtime/subscription-first-use.js +1 -1
  35. package/dist/lib/ui/ui-copy.d.ts +1 -1
  36. package/dist/lib/ui/ui-copy.js +1 -1
  37. package/dist/lib/usage/pricing.d.ts +1 -1
  38. package/dist/lib/usage/pricing.js +41 -16
  39. package/package.json +2 -2
  40. package/scripts/codex.js +167 -85
  41. package/dist/index.d.ts.map +0 -1
  42. package/dist/lib/account-policy.d.ts.map +0 -1
  43. package/dist/lib/accounts/rate-limits.d.ts.map +0 -1
  44. package/dist/lib/accounts.d.ts.map +0 -1
  45. package/dist/lib/api-route-store.d.ts.map +0 -1
  46. package/dist/lib/audit.d.ts.map +0 -1
  47. package/dist/lib/auth/account-access.d.ts.map +0 -1
  48. package/dist/lib/auth/auth.d.ts.map +0 -1
  49. package/dist/lib/auth/browser.d.ts.map +0 -1
  50. package/dist/lib/auth/callback-guidance.d.ts.map +0 -1
  51. package/dist/lib/auth/device-auth.d.ts.map +0 -1
  52. package/dist/lib/auth/index.d.ts.map +0 -1
  53. package/dist/lib/auth/org-override.d.ts.map +0 -1
  54. package/dist/lib/auth/server.d.ts.map +0 -1
  55. package/dist/lib/auth/token-utils.d.ts.map +0 -1
  56. package/dist/lib/auth-rate-limit.d.ts.map +0 -1
  57. package/dist/lib/budget-guard.d.ts.map +0 -1
  58. package/dist/lib/capability-policy.d.ts.map +0 -1
  59. package/dist/lib/circuit-breaker.d.ts.map +0 -1
  60. package/dist/lib/cli.d.ts.map +0 -1
  61. package/dist/lib/codex-cli/index.d.ts.map +0 -1
  62. package/dist/lib/codex-cli/observability.d.ts.map +0 -1
  63. package/dist/lib/codex-cli/state.d.ts.map +0 -1
  64. package/dist/lib/codex-cli/sync.d.ts.map +0 -1
  65. package/dist/lib/codex-cli/writer.d.ts.map +0 -1
  66. package/dist/lib/codex-manager/account-credentials.d.ts.map +0 -1
  67. package/dist/lib/codex-manager/account-manager-commands.d.ts.map +0 -1
  68. package/dist/lib/codex-manager/account-pool-write.d.ts.map +0 -1
  69. package/dist/lib/codex-manager/api-login-menu.d.ts.map +0 -1
  70. package/dist/lib/codex-manager/backend-category-entry.d.ts.map +0 -1
  71. package/dist/lib/codex-manager/backend-category-helpers.d.ts.map +0 -1
  72. package/dist/lib/codex-manager/backend-category-prompt.d.ts.map +0 -1
  73. package/dist/lib/codex-manager/backend-settings-controller.d.ts.map +0 -1
  74. package/dist/lib/codex-manager/backend-settings-entry.d.ts.map +0 -1
  75. package/dist/lib/codex-manager/backend-settings-helpers.d.ts.map +0 -1
  76. package/dist/lib/codex-manager/backend-settings-prompt.d.ts.map +0 -1
  77. package/dist/lib/codex-manager/backend-settings-schema.d.ts.map +0 -1
  78. package/dist/lib/codex-manager/behavior-settings-panel.d.ts.map +0 -1
  79. package/dist/lib/codex-manager/commands/account.d.ts.map +0 -1
  80. package/dist/lib/codex-manager/commands/best.d.ts.map +0 -1
  81. package/dist/lib/codex-manager/commands/bridge.d.ts.map +0 -1
  82. package/dist/lib/codex-manager/commands/budget.d.ts.map +0 -1
  83. package/dist/lib/codex-manager/commands/check.d.ts.map +0 -1
  84. package/dist/lib/codex-manager/commands/config-explain.d.ts.map +0 -1
  85. package/dist/lib/codex-manager/commands/debug-bundle.d.ts.map +0 -1
  86. package/dist/lib/codex-manager/commands/forecast.d.ts.map +0 -1
  87. package/dist/lib/codex-manager/commands/history.d.ts.map +0 -1
  88. package/dist/lib/codex-manager/commands/init-config.d.ts.map +0 -1
  89. package/dist/lib/codex-manager/commands/integrations.d.ts.map +0 -1
  90. package/dist/lib/codex-manager/commands/limits.d.ts.map +0 -1
  91. package/dist/lib/codex-manager/commands/models.d.ts.map +0 -1
  92. package/dist/lib/codex-manager/commands/monitor.d.ts.map +0 -1
  93. package/dist/lib/codex-manager/commands/report.d.ts.map +0 -1
  94. package/dist/lib/codex-manager/commands/resets.d.ts.map +0 -1
  95. package/dist/lib/codex-manager/commands/rotation.d.ts.map +0 -1
  96. package/dist/lib/codex-manager/commands/status.d.ts.map +0 -1
  97. package/dist/lib/codex-manager/commands/switch.d.ts.map +0 -1
  98. package/dist/lib/codex-manager/commands/uninstall.d.ts.map +0 -1
  99. package/dist/lib/codex-manager/commands/unpin.d.ts.map +0 -1
  100. package/dist/lib/codex-manager/commands/usage.d.ts.map +0 -1
  101. package/dist/lib/codex-manager/commands/verify.d.ts.map +0 -1
  102. package/dist/lib/codex-manager/commands/why-selected.d.ts.map +0 -1
  103. package/dist/lib/codex-manager/commands/workspace.d.ts.map +0 -1
  104. package/dist/lib/codex-manager/dashboard-display-panel.d.ts.map +0 -1
  105. package/dist/lib/codex-manager/dashboard-formatters.d.ts.map +0 -1
  106. package/dist/lib/codex-manager/dashboard-settings-controller.d.ts.map +0 -1
  107. package/dist/lib/codex-manager/dashboard-settings-data.d.ts.map +0 -1
  108. package/dist/lib/codex-manager/dashboard-settings-entry.d.ts.map +0 -1
  109. package/dist/lib/codex-manager/experimental-settings-entry.d.ts.map +0 -1
  110. package/dist/lib/codex-manager/experimental-settings-prompt.d.ts.map +0 -1
  111. package/dist/lib/codex-manager/experimental-settings-schema.d.ts.map +0 -1
  112. package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts.map +0 -1
  113. package/dist/lib/codex-manager/experimental-sync-target.d.ts.map +0 -1
  114. package/dist/lib/codex-manager/forecast-report-shared.d.ts.map +0 -1
  115. package/dist/lib/codex-manager/formatters/account-formatters.d.ts.map +0 -1
  116. package/dist/lib/codex-manager/formatters/index.d.ts.map +0 -1
  117. package/dist/lib/codex-manager/formatters/model-formatters.d.ts.map +0 -1
  118. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +0 -1
  119. package/dist/lib/codex-manager/formatters/text-style.d.ts.map +0 -1
  120. package/dist/lib/codex-manager/health-check.d.ts.map +0 -1
  121. package/dist/lib/codex-manager/help.d.ts.map +0 -1
  122. package/dist/lib/codex-manager/login-action-panel.d.ts.map +0 -1
  123. package/dist/lib/codex-manager/login-flow.d.ts.map +0 -1
  124. package/dist/lib/codex-manager/login-menu-actions.d.ts.map +0 -1
  125. package/dist/lib/codex-manager/login-menu-data.d.ts.map +0 -1
  126. package/dist/lib/codex-manager/login-oauth.d.ts.map +0 -1
  127. package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +0 -1
  128. package/dist/lib/codex-manager/manual-callback.d.ts.map +0 -1
  129. package/dist/lib/codex-manager/persist-selected-account.d.ts.map +0 -1
  130. package/dist/lib/codex-manager/quota-cache-helpers.d.ts.map +0 -1
  131. package/dist/lib/codex-manager/rate-limit-markers.d.ts.map +0 -1
  132. package/dist/lib/codex-manager/repair-commands.d.ts.map +0 -1
  133. package/dist/lib/codex-manager/settings-hub/backend.d.ts.map +0 -1
  134. package/dist/lib/codex-manager/settings-hub/dashboard.d.ts.map +0 -1
  135. package/dist/lib/codex-manager/settings-hub/experimental.d.ts.map +0 -1
  136. package/dist/lib/codex-manager/settings-hub/index.d.ts.map +0 -1
  137. package/dist/lib/codex-manager/settings-hub/shared.d.ts.map +0 -1
  138. package/dist/lib/codex-manager/settings-hub-entry.d.ts.map +0 -1
  139. package/dist/lib/codex-manager/settings-hub-menu.d.ts.map +0 -1
  140. package/dist/lib/codex-manager/settings-hub-prompt.d.ts.map +0 -1
  141. package/dist/lib/codex-manager/settings-hub.d.ts.map +0 -1
  142. package/dist/lib/codex-manager/settings-panels.d.ts.map +0 -1
  143. package/dist/lib/codex-manager/settings-persist-utils.d.ts.map +0 -1
  144. package/dist/lib/codex-manager/settings-preview.d.ts.map +0 -1
  145. package/dist/lib/codex-manager/settings-write-queue.d.ts.map +0 -1
  146. package/dist/lib/codex-manager/statusline-settings-panel.d.ts.map +0 -1
  147. package/dist/lib/codex-manager/theme-settings-panel.d.ts.map +0 -1
  148. package/dist/lib/codex-manager/unified-settings-controller.d.ts.map +0 -1
  149. package/dist/lib/codex-manager/unified-settings-entry.d.ts.map +0 -1
  150. package/dist/lib/codex-manager.d.ts.map +0 -1
  151. package/dist/lib/concurrency.d.ts.map +0 -1
  152. package/dist/lib/config-schema.d.ts.map +0 -1
  153. package/dist/lib/config.d.ts.map +0 -1
  154. package/dist/lib/constants.d.ts.map +0 -1
  155. package/dist/lib/context-budget/model-context-windows.d.ts.map +0 -1
  156. package/dist/lib/context-budget-guard.d.ts.map +0 -1
  157. package/dist/lib/context-budget-response.d.ts.map +0 -1
  158. package/dist/lib/context-overflow.d.ts.map +0 -1
  159. package/dist/lib/dashboard-settings.d.ts.map +0 -1
  160. package/dist/lib/entitlement-cache.d.ts.map +0 -1
  161. package/dist/lib/env-parsing.d.ts.map +0 -1
  162. package/dist/lib/errors.d.ts.map +0 -1
  163. package/dist/lib/forecast.d.ts.map +0 -1
  164. package/dist/lib/fs-retry.d.ts.map +0 -1
  165. package/dist/lib/health.d.ts.map +0 -1
  166. package/dist/lib/index.d.ts.map +0 -1
  167. package/dist/lib/integration-generators.d.ts.map +0 -1
  168. package/dist/lib/live-account-sync.d.ts.map +0 -1
  169. package/dist/lib/local-bridge.d.ts.map +0 -1
  170. package/dist/lib/local-client-tokens.d.ts.map +0 -1
  171. package/dist/lib/logger.d.ts.map +0 -1
  172. package/dist/lib/model-capability-matrix.d.ts.map +0 -1
  173. package/dist/lib/model-route-policy.d.ts.map +0 -1
  174. package/dist/lib/named-backup-export.d.ts.map +0 -1
  175. package/dist/lib/oc-chatgpt-import-adapter.d.ts.map +0 -1
  176. package/dist/lib/oc-chatgpt-orchestrator.d.ts.map +0 -1
  177. package/dist/lib/oc-chatgpt-target-detection.d.ts.map +0 -1
  178. package/dist/lib/parallel-probe.d.ts.map +0 -1
  179. package/dist/lib/policy/runtime-policy.d.ts.map +0 -1
  180. package/dist/lib/preemptive-quota-scheduler.d.ts.map +0 -1
  181. package/dist/lib/proactive-refresh.d.ts.map +0 -1
  182. package/dist/lib/prompts/codex-host-bridge.d.ts.map +0 -1
  183. package/dist/lib/prompts/codex.d.ts.map +0 -1
  184. package/dist/lib/prompts/fetch-utils.d.ts.map +0 -1
  185. package/dist/lib/prompts/host-codex-prompt.d.ts.map +0 -1
  186. package/dist/lib/quota-cache.d.ts.map +0 -1
  187. package/dist/lib/quota-probe.d.ts.map +0 -1
  188. package/dist/lib/quota-readiness.d.ts.map +0 -1
  189. package/dist/lib/recovery/constants.d.ts.map +0 -1
  190. package/dist/lib/recovery/storage.d.ts.map +0 -1
  191. package/dist/lib/recovery/types.d.ts.map +0 -1
  192. package/dist/lib/recovery.d.ts.map +0 -1
  193. package/dist/lib/redaction.d.ts.map +0 -1
  194. package/dist/lib/refresh-guardian.d.ts.map +0 -1
  195. package/dist/lib/refresh-lease.d.ts.map +0 -1
  196. package/dist/lib/refresh-queue.d.ts.map +0 -1
  197. package/dist/lib/request/client-cancellation.d.ts.map +0 -1
  198. package/dist/lib/request/error-classification.d.ts.map +0 -1
  199. package/dist/lib/request/failover-config.d.ts.map +0 -1
  200. package/dist/lib/request/failure-policy.d.ts.map +0 -1
  201. package/dist/lib/request/fetch-helpers.d.ts.map +0 -1
  202. package/dist/lib/request/headers.d.ts.map +0 -1
  203. package/dist/lib/request/helpers/input-utils.d.ts.map +0 -1
  204. package/dist/lib/request/helpers/model-map.d.ts.map +0 -1
  205. package/dist/lib/request/helpers/tool-utils.d.ts.map +0 -1
  206. package/dist/lib/request/index.d.ts.map +0 -1
  207. package/dist/lib/request/rate-limit-backoff.d.ts.map +0 -1
  208. package/dist/lib/request/rate-limit-decision.d.ts.map +0 -1
  209. package/dist/lib/request/request-attempt-budget.d.ts.map +0 -1
  210. package/dist/lib/request/request-init.d.ts.map +0 -1
  211. package/dist/lib/request/request-resilience.d.ts.map +0 -1
  212. package/dist/lib/request/request-transformer.d.ts.map +0 -1
  213. package/dist/lib/request/response-compaction.d.ts.map +0 -1
  214. package/dist/lib/request/response-handler.d.ts.map +0 -1
  215. package/dist/lib/request/response-metadata.d.ts.map +0 -1
  216. package/dist/lib/request/response-outcome.d.ts.map +0 -1
  217. package/dist/lib/request/stream-failover-runtime.d.ts.map +0 -1
  218. package/dist/lib/request/stream-failover.d.ts.map +0 -1
  219. package/dist/lib/request/token-refresh.d.ts.map +0 -1
  220. package/dist/lib/request/url-rewriting.d.ts.map +0 -1
  221. package/dist/lib/request/wait-utils.d.ts.map +0 -1
  222. package/dist/lib/rotation.d.ts.map +0 -1
  223. package/dist/lib/routing-mutex.d.ts.map +0 -1
  224. package/dist/lib/routing-profiles.d.ts.map +0 -1
  225. package/dist/lib/runtime/account-check-helpers.d.ts.map +0 -1
  226. package/dist/lib/runtime/account-check-types.d.ts.map +0 -1
  227. package/dist/lib/runtime/account-check.d.ts.map +0 -1
  228. package/dist/lib/runtime/account-manager-cache-entry.d.ts.map +0 -1
  229. package/dist/lib/runtime/account-manager-cache.d.ts.map +0 -1
  230. package/dist/lib/runtime/account-model-catalog.d.ts.map +0 -1
  231. package/dist/lib/runtime/account-pool.d.ts.map +0 -1
  232. package/dist/lib/runtime/account-reset-credits.d.ts.map +0 -1
  233. package/dist/lib/runtime/account-scope.d.ts.map +0 -1
  234. package/dist/lib/runtime/account-select-event.d.ts.map +0 -1
  235. package/dist/lib/runtime/account-selection.d.ts.map +0 -1
  236. package/dist/lib/runtime/account-state.d.ts.map +0 -1
  237. package/dist/lib/runtime/account-status.d.ts.map +0 -1
  238. package/dist/lib/runtime/account-storage-scope-entry.d.ts.map +0 -1
  239. package/dist/lib/runtime/api-model-capabilities.d.ts.map +0 -1
  240. package/dist/lib/runtime/api-model-runtime.d.ts.map +0 -1
  241. package/dist/lib/runtime/app-bind.d.ts.map +0 -1
  242. package/dist/lib/runtime/app-helper-selection.d.ts.map +0 -1
  243. package/dist/lib/runtime/auth-facade.d.ts.map +0 -1
  244. package/dist/lib/runtime/automatic-account-checks.d.ts.map +0 -1
  245. package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +0 -1
  246. package/dist/lib/runtime/browser-oauth-flow.d.ts.map +0 -1
  247. package/dist/lib/runtime/capability-boost.d.ts.map +0 -1
  248. package/dist/lib/runtime/catalog-capabilities.d.ts.map +0 -1
  249. package/dist/lib/runtime/config-toml.d.ts.map +0 -1
  250. package/dist/lib/runtime/context-budget-settings.d.ts.map +0 -1
  251. package/dist/lib/runtime/event-handler.d.ts.map +0 -1
  252. package/dist/lib/runtime/first-run.d.ts.map +0 -1
  253. package/dist/lib/runtime/flagged-verify-types.d.ts.map +0 -1
  254. package/dist/lib/runtime/hydrate-emails.d.ts.map +0 -1
  255. package/dist/lib/runtime/inference-activity.d.ts.map +0 -1
  256. package/dist/lib/runtime/live-sync-entry.d.ts.map +0 -1
  257. package/dist/lib/runtime/live-sync.d.ts.map +0 -1
  258. package/dist/lib/runtime/loader-setup.d.ts.map +0 -1
  259. package/dist/lib/runtime/login-menu-accounts.d.ts.map +0 -1
  260. package/dist/lib/runtime/manual-oauth-flow.d.ts.map +0 -1
  261. package/dist/lib/runtime/model-discovery-status.d.ts.map +0 -1
  262. package/dist/lib/runtime/native-account-storage.d.ts.map +0 -1
  263. package/dist/lib/runtime/native-account-sync.d.ts.map +0 -1
  264. package/dist/lib/runtime/native-binding-lock.d.ts.map +0 -1
  265. package/dist/lib/runtime/native-client-auth.d.ts.map +0 -1
  266. package/dist/lib/runtime/native-provider-config.d.ts.map +0 -1
  267. package/dist/lib/runtime/native-rate-limits.d.ts.map +0 -1
  268. package/dist/lib/runtime/preemptive-quota.d.ts.map +0 -1
  269. package/dist/lib/runtime/quota-headers.d.ts.map +0 -1
  270. package/dist/lib/runtime/quota-probe.d.ts.map +0 -1
  271. package/dist/lib/runtime/quota-settings.d.ts.map +0 -1
  272. package/dist/lib/runtime/refresh-guardian-entry.d.ts.map +0 -1
  273. package/dist/lib/runtime/refresh-guardian.d.ts.map +0 -1
  274. package/dist/lib/runtime/request-init.d.ts.map +0 -1
  275. package/dist/lib/runtime/reset-credit-routing.d.ts.map +0 -1
  276. package/dist/lib/runtime/reset-credits.d.ts.map +0 -1
  277. package/dist/lib/runtime/response-output-history.d.ts.map +0 -1
  278. package/dist/lib/runtime/responses-websocket.d.ts.map +0 -1
  279. package/dist/lib/runtime/resume-picker.d.ts.map +0 -1
  280. package/dist/lib/runtime/rotation-account-selection.d.ts.map +0 -1
  281. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +0 -1
  282. package/dist/lib/runtime/rotation-server-types.d.ts.map +0 -1
  283. package/dist/lib/runtime/rotation-storage-meta.d.ts.map +0 -1
  284. package/dist/lib/runtime/rotation-token-refresh.d.ts.map +0 -1
  285. package/dist/lib/runtime/runtime-capability-failures.d.ts.map +0 -1
  286. package/dist/lib/runtime/runtime-current-account.d.ts.map +0 -1
  287. package/dist/lib/runtime/runtime-observability.d.ts.map +0 -1
  288. package/dist/lib/runtime/runtime-services.d.ts.map +0 -1
  289. package/dist/lib/runtime/session-affinity-entry.d.ts.map +0 -1
  290. package/dist/lib/runtime/session-recovery.d.ts.map +0 -1
  291. package/dist/lib/runtime/status-marker.d.ts.map +0 -1
  292. package/dist/lib/runtime/storage-scope.d.ts.map +0 -1
  293. package/dist/lib/runtime/subscription-first-use.d.ts.map +0 -1
  294. package/dist/lib/runtime/subscription-quota-event.d.ts.map +0 -1
  295. package/dist/lib/runtime/subscription-quota-order.d.ts.map +0 -1
  296. package/dist/lib/runtime/toast.d.ts.map +0 -1
  297. package/dist/lib/runtime/ui-runtime-entry.d.ts.map +0 -1
  298. package/dist/lib/runtime/ui-runtime.d.ts.map +0 -1
  299. package/dist/lib/runtime/verify-flagged.d.ts.map +0 -1
  300. package/dist/lib/runtime/workspace-model-scopes.d.ts.map +0 -1
  301. package/dist/lib/runtime-constants.d.ts.map +0 -1
  302. package/dist/lib/runtime-paths.d.ts.map +0 -1
  303. package/dist/lib/runtime-rotation-proxy.d.ts.map +0 -1
  304. package/dist/lib/schemas.d.ts.map +0 -1
  305. package/dist/lib/session-affinity.d.ts.map +0 -1
  306. package/dist/lib/shutdown.d.ts.map +0 -1
  307. package/dist/lib/storage/account-clear-entry.d.ts.map +0 -1
  308. package/dist/lib/storage/account-clear.d.ts.map +0 -1
  309. package/dist/lib/storage/account-match-utils.d.ts.map +0 -1
  310. package/dist/lib/storage/account-persistence.d.ts.map +0 -1
  311. package/dist/lib/storage/account-port.d.ts.map +0 -1
  312. package/dist/lib/storage/account-save-entry.d.ts.map +0 -1
  313. package/dist/lib/storage/account-save.d.ts.map +0 -1
  314. package/dist/lib/storage/account-snapshot.d.ts.map +0 -1
  315. package/dist/lib/storage/backup-metadata-builder.d.ts.map +0 -1
  316. package/dist/lib/storage/backup-metadata.d.ts.map +0 -1
  317. package/dist/lib/storage/backup-paths.d.ts.map +0 -1
  318. package/dist/lib/storage/backup-restore.d.ts.map +0 -1
  319. package/dist/lib/storage/cache-artifacts.d.ts.map +0 -1
  320. package/dist/lib/storage/credential-sidecars.d.ts.map +0 -1
  321. package/dist/lib/storage/error-hints.d.ts.map +0 -1
  322. package/dist/lib/storage/file-lock.d.ts.map +0 -1
  323. package/dist/lib/storage/file-paths.d.ts.map +0 -1
  324. package/dist/lib/storage/fixture-guards.d.ts.map +0 -1
  325. package/dist/lib/storage/flagged-entry.d.ts.map +0 -1
  326. package/dist/lib/storage/flagged-load-entry.d.ts.map +0 -1
  327. package/dist/lib/storage/flagged-save-entry.d.ts.map +0 -1
  328. package/dist/lib/storage/flagged-storage-file.d.ts.map +0 -1
  329. package/dist/lib/storage/flagged-storage-io.d.ts.map +0 -1
  330. package/dist/lib/storage/flagged-storage.d.ts.map +0 -1
  331. package/dist/lib/storage/gitignore.d.ts.map +0 -1
  332. package/dist/lib/storage/hash.d.ts.map +0 -1
  333. package/dist/lib/storage/health.d.ts.map +0 -1
  334. package/dist/lib/storage/identity.d.ts.map +0 -1
  335. package/dist/lib/storage/import-export.d.ts.map +0 -1
  336. package/dist/lib/storage/metadata-section.d.ts.map +0 -1
  337. package/dist/lib/storage/migrations.d.ts.map +0 -1
  338. package/dist/lib/storage/named-backup-entry.d.ts.map +0 -1
  339. package/dist/lib/storage/named-backups-entry.d.ts.map +0 -1
  340. package/dist/lib/storage/named-backups.d.ts.map +0 -1
  341. package/dist/lib/storage/path-state.d.ts.map +0 -1
  342. package/dist/lib/storage/paths.d.ts.map +0 -1
  343. package/dist/lib/storage/pending-auth.d.ts.map +0 -1
  344. package/dist/lib/storage/project-migration.d.ts.map +0 -1
  345. package/dist/lib/storage/public-types.d.ts.map +0 -1
  346. package/dist/lib/storage/record-identity.d.ts.map +0 -1
  347. package/dist/lib/storage/record-utils.d.ts.map +0 -1
  348. package/dist/lib/storage/restore-assessment.d.ts.map +0 -1
  349. package/dist/lib/storage/restore-backup-entry.d.ts.map +0 -1
  350. package/dist/lib/storage/restore-metadata.d.ts.map +0 -1
  351. package/dist/lib/storage/save-retry.d.ts.map +0 -1
  352. package/dist/lib/storage/snapshot-inspectors.d.ts.map +0 -1
  353. package/dist/lib/storage/snapshot-merge.d.ts.map +0 -1
  354. package/dist/lib/storage/storage-parser.d.ts.map +0 -1
  355. package/dist/lib/storage/transactions.d.ts.map +0 -1
  356. package/dist/lib/storage.d.ts.map +0 -1
  357. package/dist/lib/synthetic-response.d.ts.map +0 -1
  358. package/dist/lib/table-formatter.d.ts.map +0 -1
  359. package/dist/lib/temp-path.d.ts.map +0 -1
  360. package/dist/lib/tools/hashline-tools.d.ts.map +0 -1
  361. package/dist/lib/types.d.ts.map +0 -1
  362. package/dist/lib/ui/ansi.d.ts.map +0 -1
  363. package/dist/lib/ui/auth-menu-builder.d.ts.map +0 -1
  364. package/dist/lib/ui/auth-menu.d.ts.map +0 -1
  365. package/dist/lib/ui/check-progress.d.ts.map +0 -1
  366. package/dist/lib/ui/confirm.d.ts.map +0 -1
  367. package/dist/lib/ui/display-width.d.ts.map +0 -1
  368. package/dist/lib/ui/format.d.ts.map +0 -1
  369. package/dist/lib/ui/index.d.ts.map +0 -1
  370. package/dist/lib/ui/runtime.d.ts.map +0 -1
  371. package/dist/lib/ui/select.d.ts.map +0 -1
  372. package/dist/lib/ui/theme.d.ts.map +0 -1
  373. package/dist/lib/ui/ui-copy.d.ts.map +0 -1
  374. package/dist/lib/unified-settings.d.ts.map +0 -1
  375. package/dist/lib/update-notice.d.ts.map +0 -1
  376. package/dist/lib/usage/index.d.ts.map +0 -1
  377. package/dist/lib/usage/ledger.d.ts.map +0 -1
  378. package/dist/lib/usage/pricing.d.ts.map +0 -1
  379. package/dist/lib/usage/redaction.d.ts.map +0 -1
  380. package/dist/lib/usage/stream-usage-deferral.d.ts.map +0 -1
  381. package/dist/lib/usage/types.d.ts.map +0 -1
  382. package/dist/lib/usage/usage-extraction.d.ts.map +0 -1
  383. package/dist/lib/utils.d.ts.map +0 -1
  384. package/dist/lib/wsl.d.ts.map +0 -1
@@ -1,3 +1,6 @@
1
+ import { subscriptionStatus, formatSubscriptionStatus } from "./formatters/subscription-status.js";
2
+ import { getAccountPolicyKey, loadAccountPolicyStore } from "../account-policy.js";
3
+ import { automaticCheckWorkspaceId } from "../runtime/automatic-account-checks.js";
1
4
  import { refreshAndPrintResetCredits } from "../runtime/account-reset-credits.js";
2
5
  import { mapWithConcurrency } from "../concurrency.js";
3
6
  import { withCheckProgress } from "../ui/check-progress.js";
@@ -16,7 +19,7 @@ import { loadAccounts, saveAccounts, setStoragePath } from "../storage.js";
16
19
  import { applyTokenAccountIdentity, hasLikelyInvalidRefreshToken, hasUsableAccessToken, } from "./account-credentials.js";
17
20
  import { saveAccountsWithRetry } from "./forecast-report-shared.js";
18
21
  import { formatModelInspection, formatQuotaSnapshotForDashboard, formatResultSummary, inspectRequestedModel, normalizeFailureDetail, styleAccountDetailText, stylePromptText, } from "./formatters/index.js";
19
- import { cloneQuotaCacheData, DEFAULT_LIVE_PROBE_MODEL, pruneUnsafeQuotaEmailCacheEntry, updateQuotaCacheForAccount, } from "./quota-cache-helpers.js";
22
+ import { cloneQuotaCacheData, DEFAULT_LIVE_PROBE_MODEL, pruneUnsafeQuotaEmailCacheEntry, updateQuotaCacheForWorkspace, } from "./quota-cache-helpers.js";
20
23
  function appendAuthInvalidationMarker(account, detail) {
21
24
  return typeof account.authInvalidatedAt === "number" &&
22
25
  Number.isFinite(account.authInvalidatedAt)
@@ -44,6 +47,8 @@ export async function runHealthCheck(options = {}) {
44
47
  let quotaEmailFallbackState = liveProbe && quotaCache
45
48
  ? buildQuotaEmailFallbackState(storage.accounts)
46
49
  : null;
50
+ const policies = await loadAccountPolicyStore({ strict: true }).catch(() => null);
51
+ const subscriptionLine = (account, snapshot) => formatSubscriptionStatus(subscriptionStatus(account, { ...snapshot, updatedAt: snapshot.observedAt ?? Date.now() }, policies ? policies.accounts[getAccountPolicyKey(account)] ?? {} : undefined, Date.now()));
47
52
  let changed = false;
48
53
  let ok = 0;
49
54
  let failed = 0;
@@ -62,7 +67,7 @@ export async function runHealthCheck(options = {}) {
62
67
  const quickProbes = new Map();
63
68
  if (liveProbe && !forceRefresh) {
64
69
  const candidates = storage.accounts.flatMap((account, index) => {
65
- const accountId = account.accountId ?? extractAccountId(account.accessToken);
70
+ const accountId = automaticCheckWorkspaceId(account);
66
71
  return hasUsableAccessToken(account, now) && account.accessToken && accountId
67
72
  ? [{ index, accountId, accessToken: account.accessToken }] : [];
68
73
  });
@@ -104,14 +109,14 @@ export async function runHealthCheck(options = {}) {
104
109
  if (liveProbe) {
105
110
  const currentAccessToken = account.accessToken;
106
111
  const probeAccountId = currentAccessToken
107
- ? (account.accountId ?? extractAccountId(currentAccessToken))
112
+ ? automaticCheckWorkspaceId(account)
108
113
  : undefined;
109
114
  if (!probeAccountId || !currentAccessToken) {
110
115
  warnings += 1;
111
116
  signedInOnly += 1;
112
117
  healthTone = "warning";
113
118
  healthDetail =
114
- "signed in (live check skipped: missing account ID)";
119
+ "signed in (live check skipped: missing account ID or unavailable selected workspace)";
115
120
  }
116
121
  else {
117
122
  try {
@@ -124,10 +129,10 @@ export async function runHealthCheck(options = {}) {
124
129
  model: modelInspection.normalized,
125
130
  }), console.log);
126
131
  if (workingQuotaCache) {
127
- quotaCacheChanged =
128
- updateQuotaCacheForAccount(workingQuotaCache, account, snapshot, storage.accounts, quotaEmailFallbackState ?? undefined) || quotaCacheChanged;
132
+ updateQuotaCacheForWorkspace(workingQuotaCache, account, probeAccountId, snapshot, storage.accounts);
133
+ quotaCacheChanged = true;
129
134
  }
130
- healthDetail = formatQuotaSnapshotForDashboard(snapshot, display);
135
+ healthDetail = formatQuotaSnapshotForDashboard(snapshot, display) + " | " + subscriptionLine(account, snapshot);
131
136
  if (snapshot.primingFailure) {
132
137
  healthTone = "warning";
133
138
  warnings += 1;
@@ -210,13 +215,13 @@ export async function runHealthCheck(options = {}) {
210
215
  let healthyMessage = "working now";
211
216
  let healthyTone = "success";
212
217
  if (liveProbe) {
213
- const probeAccountId = account.accountId ?? tokenAccountId;
218
+ const probeAccountId = automaticCheckWorkspaceId(account);
214
219
  if (!probeAccountId) {
215
220
  warnings += 1;
216
221
  signedInOnly += 1;
217
222
  healthyTone = "warning";
218
223
  healthyMessage =
219
- "signed in (live check skipped: missing account ID)";
224
+ "signed in (live check skipped: missing account ID or unavailable selected workspace)";
220
225
  }
221
226
  else {
222
227
  try {
@@ -226,10 +231,10 @@ export async function runHealthCheck(options = {}) {
226
231
  model: modelInspection.normalized,
227
232
  }), console.log);
228
233
  if (workingQuotaCache) {
229
- quotaCacheChanged =
230
- updateQuotaCacheForAccount(workingQuotaCache, account, snapshot, storage.accounts, quotaEmailFallbackState ?? undefined) || quotaCacheChanged;
234
+ updateQuotaCacheForWorkspace(workingQuotaCache, account, probeAccountId, snapshot, storage.accounts);
235
+ quotaCacheChanged = true;
231
236
  }
232
- healthyMessage = formatQuotaSnapshotForDashboard(snapshot, display);
237
+ healthyMessage = formatQuotaSnapshotForDashboard(snapshot, display) + " | " + subscriptionLine(account, snapshot);
233
238
  if (snapshot.primingFailure) {
234
239
  healthyTone = "warning";
235
240
  warnings += 1;
@@ -1,4 +1,5 @@
1
1
  import { buildQuotaEmailFallbackState, findQuotaCacheEntryForAccount, quotaWorkspaceKey, hasSafeQuotaEmailFallback, hasUniqueQuotaAccountId, normalizeQuotaAccountId, normalizeQuotaEmail, } from "../quota-readiness.js";
2
+ import { mergeQuotaCacheEntry, } from "../quota-cache.js";
2
3
  import { DEFAULT_MODEL, DEFAULT_PROBE_MODEL, } from "../request/helpers/model-map.js";
3
4
  import { getRateLimitResetTimeForFamily } from "../runtime/account-status.js";
4
5
  /**
@@ -41,7 +42,10 @@ export function getPersistedQuotaViewForAccount(cache, account, accounts, now, e
41
42
  /** Retain only quota fields from a probe, never its credentials or response body. */
42
43
  function quotaEntryFromSnapshot(snapshot) {
43
44
  return {
44
- updatedAt: Date.now(),
45
+ ...(snapshot.primingCompleted ? { primingCompleted: true } : {}),
46
+ ...(snapshot.primingFailure ? { primingFailure: snapshot.primingFailure } : {}),
47
+ ...(snapshot.primingCompleted || snapshot.primingFailure ? { primingObservedAt: snapshot.primingObservedAt ?? Date.now() } : {}),
48
+ updatedAt: snapshot.observedAt ?? Date.now(),
45
49
  status: snapshot.status,
46
50
  model: snapshot.model,
47
51
  planType: snapshot.planType,
@@ -64,14 +68,14 @@ export function updateQuotaCacheForAccount(cache, account, snapshot, accounts, e
64
68
  const accountId = normalizeQuotaAccountId(account.accountId);
65
69
  const hasUniqueAccountId = accountId !== null && hasUniqueQuotaAccountId(accounts, account);
66
70
  if (hasUniqueAccountId) {
67
- cache.byAccountId[accountId] = nextEntry;
71
+ cache.byAccountId[accountId] = mergeQuotaCacheEntry(cache.byAccountId[accountId], nextEntry);
68
72
  changed = true;
69
73
  }
70
74
  const email = normalizeQuotaEmail(account.email);
71
75
  if (email &&
72
76
  hasSafeQuotaEmailFallback(emailFallbackState, account) &&
73
77
  !hasUniqueAccountId) {
74
- cache.byEmail[email] = nextEntry;
78
+ cache.byEmail[email] = mergeQuotaCacheEntry(cache.byEmail[email], nextEntry);
75
79
  changed = true;
76
80
  }
77
81
  else if (email && cache.byEmail[email]) {
@@ -86,7 +90,7 @@ export function updateQuotaCacheForWorkspace(cache, account, workspaceId, snapsh
86
90
  if (!key)
87
91
  return;
88
92
  cache.byWorkspace ??= {};
89
- cache.byWorkspace[key] = quotaEntryFromSnapshot(snapshot);
93
+ cache.byWorkspace[key] = mergeQuotaCacheEntry(cache.byWorkspace[key], quotaEntryFromSnapshot(snapshot));
90
94
  if (workspaceId === normalizeQuotaAccountId(account.accountId)) {
91
95
  updateQuotaCacheForAccount(cache, account, snapshot, accounts);
92
96
  }
@@ -6,7 +6,7 @@
6
6
  * behavior (see the v2.5.0 release notes) closely enough to launch that no
7
7
  * estimate here has been reviewed for it yet.
8
8
  */
9
- export declare const UNESTIMATED_ROUTABLE_MODELS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-6-astra", "gpt-6-astra-aeon", "gpt-6-sol", "gpt-6-luna", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest"];
9
+ export declare const UNESTIMATED_ROUTABLE_MODELS: readonly ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-6.1-sol", "gpt-daybreak-blue-latest", "gpt-daybreak-red-latest"];
10
10
  export interface EffectiveContextWindow {
11
11
  tokens: number;
12
12
  source: "override" | "estimate";
@@ -23,14 +23,11 @@ import { getNormalizedModel } from "../request/helpers/model-map.js";
23
23
  * it to UNESTIMATED_ROUTABLE_MODELS instead.
24
24
  */
25
25
  //
26
- // Retired models (`gpt-5.1` through `gpt-5.4-*`, `gpt-5-mini`/`nano`, the codex
27
- // models) are deliberately absent. Their ids now route to a replacement, and
28
- // estimating the window from the retired name would evaluate a request against
29
- // a model it no longer runs on.
30
- const ESTIMATED_MODEL_CONTEXT_WINDOWS = {
31
- "gpt-5.5": 260_000,
32
- "gpt-5.5-pro": 260_000,
33
- };
26
+ // Retired models (`gpt-5.1` through `gpt-5.5-pro`, `gpt-5-mini`/`nano`, the
27
+ // codex models) are deliberately absent. Their ids now route to a
28
+ // replacement, and estimating the window from the retired name would
29
+ // evaluate a request against a model it no longer runs on.
30
+ const ESTIMATED_MODEL_CONTEXT_WINDOWS = {};
34
31
  /**
35
32
  * Routable models this guard consciously does not estimate a window for.
36
33
  * `getEffectiveContextWindow` returns `null` for these absent an override,
@@ -52,11 +49,11 @@ export const UNESTIMATED_ROUTABLE_MODELS = [
52
49
  // measured ceiling for this transport, so it stays unestimated too. Set
53
50
  // `contextBudgetGuardModelWindowOverrides` once you know your real ceiling.
54
51
  "gpt-6-astra",
55
- "gpt-6-astra-aeon",
56
- // Sol and Luna carry the same 272K Codex / 872K max split in the upstream
57
- // catalog as Astra, so the same reasoning keeps them unestimated.
52
+ // Sol, Luna and 6.1 Sol carry the same 272K Codex / 872K max split in the
53
+ // upstream catalog as Astra, so the same reasoning keeps them unestimated.
58
54
  "gpt-6-sol",
59
55
  "gpt-6-luna",
56
+ "gpt-6.1-sol",
60
57
  "gpt-daybreak-blue-latest",
61
58
  "gpt-daybreak-red-latest",
62
59
  ];
@@ -79,8 +76,8 @@ function normalizeModelName(model) {
79
76
  * the way they type the model still wins, then the catalog's canonical id for
80
77
  * it. `getNormalizedModel` is deliberately the exact/alias-only resolver —
81
78
  * `resolveNormalizedModel` falls back to `DEFAULT_MODEL` for anything it does
82
- * not recognize, which would hand an unknown model gpt-5.5's window and
83
- * evaluate a real session against a fabricated number.
79
+ * not recognize, which would hand an unknown model the default model's
80
+ * window and evaluate a real session against a fabricated number.
84
81
  */
85
82
  function windowLookupCandidates(model) {
86
83
  const raw = normalizeModelName(model);
@@ -44,7 +44,7 @@ export declare function modelEntitlements(model: RouteModel): {
44
44
  reasoningLevels: string[];
45
45
  accessPrograms: string[];
46
46
  probes?: {
47
- [k: string]: "verified" | "unsupported" | "unverified" | "downgraded";
47
+ [k: string]: "unsupported" | "verified" | "unverified" | "downgraded";
48
48
  } | undefined;
49
49
  checkedAt?: number | undefined;
50
50
  model: string;
@@ -35,7 +35,8 @@ export type OcChatgptTargetDetectionResult = OcChatgptTargetFound | OcChatgptTar
35
35
  /**
36
36
  * Detects the oc-chatgpt multi-auth storage target by evaluating explicit, canonical, and per-project candidate roots.
37
37
  *
38
- * Examines an explicit override (OC_CHATGPT_MULTI_AUTH_DIR or options.explicitRoot), the canonical user store (~/.opencode),
38
+ * Examines an explicit override (OC_CODEX_MULTI_AUTH_DIR, the legacy OC_CHATGPT_MULTI_AUTH_DIR alias, or
39
+ * options.explicitRoot), the canonical user store (~/.opencode),
39
40
  * and a per-project storage location (derived from options.projectRoot or the current working directory). For each candidate
40
41
  * it checks for account artifacts and storage signals and returns a single resolved target, an ambiguity listing multiple
41
42
  * matching candidates, or a "none" result with the attempted candidates. This function performs synchronous filesystem checks
@@ -45,7 +46,7 @@ export type OcChatgptTargetDetectionResult = OcChatgptTargetFound | OcChatgptTar
45
46
  *
46
47
  * @param options - Optional overrides:
47
48
  * - explicitRoot: absolute path to force as the candidate root (use `null` to explicitly disable); if omitted the
48
- * OC_CHATGPT_MULTI_AUTH_DIR environment variable is considered.
49
+ * OC_CODEX_MULTI_AUTH_DIR environment variable is considered, then the legacy OC_CHATGPT_MULTI_AUTH_DIR alias.
49
50
  * - projectRoot: explicit project root to derive per-project storage; if omitted the current working directory is used to
50
51
  * discover the project root.
51
52
  * @returns An OcChatgptTargetDetectionResult describing either a resolved `target` (with `descriptor` and a `resolution`
@@ -2,7 +2,14 @@ import { existsSync, readdirSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { join, normalize, relative, resolve, sep, win32 } from "node:path";
4
4
  import { findProjectRoot, getProjectStorageKey, resolveProjectStorageIdentityRoot, } from "./storage/paths.js";
5
- const ACCOUNT_FILE_NAME = "openai-codex-accounts.json";
5
+ // The sibling plugin renamed its account file from `openai-codex-accounts.json`
6
+ // (oc-chatgpt-multi-auth era) to `oc-codex-multi-auth-accounts.json`; both are
7
+ // detected, preferring the current name when a root holds both.
8
+ const ACCOUNT_FILE_NAMES = [
9
+ "oc-codex-multi-auth-accounts.json",
10
+ "openai-codex-accounts.json",
11
+ ];
12
+ const ACCOUNT_FILE_NAME = ACCOUNT_FILE_NAMES[0];
6
13
  const BACKUPS_DIR_NAME = "backups";
7
14
  const PROJECTS_DIR_NAME = "projects";
8
15
  const CANONICAL_HOME_BASENAME = ".opencode";
@@ -107,17 +114,32 @@ function deduplicatePaths(paths) {
107
114
  }
108
115
  return result;
109
116
  }
117
+ /**
118
+ * Returns the path of the primary account file under `root`, preferring the
119
+ * current `oc-codex-multi-auth-accounts.json` name over the legacy
120
+ * `openai-codex-accounts.json` name when both exist, or `null` when neither
121
+ * file (nor its `.wal` sidecar) is present.
122
+ */
123
+ function findPrimaryAccountPath(root) {
124
+ for (const name of ACCOUNT_FILE_NAMES) {
125
+ const accountPath = join(root, name);
126
+ if (existsSync(accountPath) || existsSync(`${accountPath}.wal`)) {
127
+ return accountPath;
128
+ }
129
+ }
130
+ return null;
131
+ }
110
132
  /**
111
133
  * Detects whether an account file or rotated account artifacts exist under the specified storage root.
112
134
  *
113
- * Scans for the canonical account file and its WAL variant, rotated/archived files matching the account filename pattern (excluding `.tmp`, `.wal`, and names containing `.rotate.`), and the backups directory. The probe is tolerant of unreadable directories (errors are ignored) and does not read file contents. Callers should be aware of concurrent filesystem changes — a `false` result does not guarantee no artifact will appear shortly after. On Windows, filesystem matching should be considered case-insensitive by callers. This check does not expose or parse any token contents.
135
+ * Scans for an account file under either known name (`oc-codex-multi-auth-accounts.json` or the legacy `openai-codex-accounts.json`) and its WAL variant, rotated/archived files matching either account filename pattern (excluding `.tmp`, `.wal`, and names containing `.rotate.`), and the backups directory. The probe is tolerant of unreadable directories (errors are ignored) and does not read file contents. Callers should be aware of concurrent filesystem changes — a `false` result does not guarantee no artifact will appear shortly after. On Windows, filesystem matching should be considered case-insensitive by callers. This check does not expose or parse any token contents.
114
136
  *
115
137
  * @param root - Filesystem path of the storage root to probe
138
+ * @param primaryAccountPath - Result of `findPrimaryAccountPath(root)`, so callers resolve the descriptor path once
116
139
  * @returns `true` if any account file or rotated account artifact exists under `root` or its backups directory, `false` otherwise.
117
140
  */
118
- function hasAccountArtifacts(root) {
119
- const accountPath = join(root, ACCOUNT_FILE_NAME);
120
- if (existsSync(accountPath) || existsSync(`${accountPath}.wal`)) {
141
+ function hasAccountArtifacts(root, primaryAccountPath) {
142
+ if (primaryAccountPath !== null) {
121
143
  return true;
122
144
  }
123
145
  const hasRotated = (dir) => {
@@ -126,7 +148,7 @@ function hasAccountArtifacts(root) {
126
148
  for (const entry of entries) {
127
149
  if (!entry.isFile())
128
150
  continue;
129
- if (!entry.name.startsWith(`${ACCOUNT_FILE_NAME}.`))
151
+ if (!ACCOUNT_FILE_NAMES.some((name) => entry.name.startsWith(`${name}.`)))
130
152
  continue;
131
153
  if (entry.name.endsWith(".tmp"))
132
154
  continue;
@@ -146,7 +168,7 @@ function hasAccountArtifacts(root) {
146
168
  return true;
147
169
  }
148
170
  const backupsDir = join(root, BACKUPS_DIR_NAME);
149
- if (existsSync(join(backupsDir, ACCOUNT_FILE_NAME))) {
171
+ if (ACCOUNT_FILE_NAMES.some((name) => existsSync(join(backupsDir, name)))) {
150
172
  return true;
151
173
  }
152
174
  if (hasRotated(backupsDir)) {
@@ -191,7 +213,8 @@ function inferScopeFromRoot(root, canonicalRoot) {
191
213
  /**
192
214
  * Detects the oc-chatgpt multi-auth storage target by evaluating explicit, canonical, and per-project candidate roots.
193
215
  *
194
- * Examines an explicit override (OC_CHATGPT_MULTI_AUTH_DIR or options.explicitRoot), the canonical user store (~/.opencode),
216
+ * Examines an explicit override (OC_CODEX_MULTI_AUTH_DIR, the legacy OC_CHATGPT_MULTI_AUTH_DIR alias, or
217
+ * options.explicitRoot), the canonical user store (~/.opencode),
195
218
  * and a per-project storage location (derived from options.projectRoot or the current working directory). For each candidate
196
219
  * it checks for account artifacts and storage signals and returns a single resolved target, an ambiguity listing multiple
197
220
  * matching candidates, or a "none" result with the attempted candidates. This function performs synchronous filesystem checks
@@ -201,14 +224,17 @@ function inferScopeFromRoot(root, canonicalRoot) {
201
224
  *
202
225
  * @param options - Optional overrides:
203
226
  * - explicitRoot: absolute path to force as the candidate root (use `null` to explicitly disable); if omitted the
204
- * OC_CHATGPT_MULTI_AUTH_DIR environment variable is considered.
227
+ * OC_CODEX_MULTI_AUTH_DIR environment variable is considered, then the legacy OC_CHATGPT_MULTI_AUTH_DIR alias.
205
228
  * - projectRoot: explicit project root to derive per-project storage; if omitted the current working directory is used to
206
229
  * discover the project root.
207
230
  * @returns An OcChatgptTargetDetectionResult describing either a resolved `target` (with `descriptor` and a `resolution`
208
231
  * of `"accounts"` or `"signals"`), an `ambiguous` outcome listing conflicting candidates, or `none` with the tried candidates.
209
232
  */
210
233
  export function detectOcChatgptMultiAuthTarget(options) {
211
- const explicitFromEnv = (process.env.OC_CHATGPT_MULTI_AUTH_DIR ?? "").trim();
234
+ const explicitFromEnv = (firstNonEmpty([
235
+ process.env.OC_CODEX_MULTI_AUTH_DIR,
236
+ process.env.OC_CHATGPT_MULTI_AUTH_DIR,
237
+ ]) ?? "").trim();
212
238
  const hasExplicitRootOption = options !== undefined && "explicitRoot" in options;
213
239
  const explicitRoot = (hasExplicitRootOption ? (options.explicitRoot ?? "") : explicitFromEnv).trim();
214
240
  const userHome = getResolvedUserHomeDir();
@@ -233,9 +259,10 @@ export function detectOcChatgptMultiAuthTarget(options) {
233
259
  : inferredScope === "project"
234
260
  ? "project"
235
261
  : "default-global";
236
- const accountPath = join(root, ACCOUNT_FILE_NAME);
262
+ const primaryAccountPath = findPrimaryAccountPath(root);
263
+ const accountPath = primaryAccountPath ?? join(root, ACCOUNT_FILE_NAME);
237
264
  const backupRoot = join(root, BACKUPS_DIR_NAME);
238
- const hasAccountArtifactsFlag = hasAccountArtifacts(root);
265
+ const hasAccountArtifactsFlag = hasAccountArtifacts(root, primaryAccountPath);
239
266
  return {
240
267
  scope: inferredScope,
241
268
  source,
@@ -314,7 +341,7 @@ export function detectOcChatgptMultiAuthTarget(options) {
314
341
  }
315
342
  return {
316
343
  kind: "none",
317
- reason: "No oc-chatgpt-multi-auth target root found; create ~/.opencode or supply OC_CHATGPT_MULTI_AUTH_DIR.",
344
+ reason: "No oc-chatgpt-multi-auth target root found; create ~/.opencode or supply OC_CODEX_MULTI_AUTH_DIR (legacy OC_CHATGPT_MULTI_AUTH_DIR is still accepted).",
318
345
  tried: candidates.map(({ scope, source, root, accountPath, backupRoot }) => ({
319
346
  scope,
320
347
  source,
@@ -4,6 +4,10 @@ export interface QuotaCacheWindow {
4
4
  resetAtMs?: number;
5
5
  }
6
6
  export interface QuotaCacheEntry {
7
+ primingCompleted?: boolean;
8
+ /** Completion/failure time, independent of the quota header observation. */
9
+ primingObservedAt?: number;
10
+ primingFailure?: "timed out" | "stream ended early" | "upstream failed" | "response too large" | "network error";
7
11
  updatedAt: number;
8
12
  status: number;
9
13
  model: string;
@@ -47,6 +51,8 @@ export declare function getQuotaCachePath(): string;
47
51
  * will be empty if the on-disk file is absent, malformed, or could not be read.
48
52
  */
49
53
  export declare function loadQuotaCache(): Promise<QuotaCacheData>;
54
+ /** Merge quota and priming evidence independently; subsequent quota retires old outcomes. */
55
+ export declare function mergeQuotaCacheEntry(latest: QuotaCacheEntry | undefined, update: QuotaCacheEntry): QuotaCacheEntry;
50
56
  /**
51
57
  * Persist the quota cache to the on-disk JSON file used by the multi-auth runtime.
52
58
  *
@@ -58,6 +58,9 @@ function normalizeEntry(value) {
58
58
  return null;
59
59
  }
60
60
  return {
61
+ ...(value.primingCompleted === true ? { primingCompleted: true } : {}),
62
+ ...(typeof value.primingFailure === "string" && ["timed out", "stream ended early", "upstream failed", "response too large", "network error"].includes(value.primingFailure) ? { primingFailure: value.primingFailure } : {}),
63
+ ...(normalizeNumber(value.primingObservedAt) !== undefined ? { primingObservedAt: normalizeNumber(value.primingObservedAt) } : {}),
61
64
  updatedAt,
62
65
  status,
63
66
  model: model.trim(),
@@ -158,6 +161,32 @@ async function readQuotaCache() {
158
161
  ...(parsed.byWorkspace ? { byWorkspace: normalizeEntryMap(parsed.byWorkspace) } : {}),
159
162
  };
160
163
  }
164
+ /** Merge quota and priming evidence independently; subsequent quota retires old outcomes. */
165
+ export function mergeQuotaCacheEntry(latest, update) {
166
+ if (!latest)
167
+ return update;
168
+ const quota = update.updatedAt >= latest.updatedAt ? update : latest;
169
+ const outcomeTime = (entry) => entry.primingCompleted || entry.primingFailure
170
+ ? entry.primingObservedAt ?? entry.updatedAt : -Infinity;
171
+ // A timeout does not undo a completion from an overlapping attempt.
172
+ // Only completions at/after the newest quota observation remain relevant.
173
+ const completion = [update, latest].filter(entry => entry.primingCompleted && outcomeTime(entry) >= quota.updatedAt)
174
+ .sort((a, b) => outcomeTime(b) - outcomeTime(a))[0];
175
+ const evidence = completion ?? (outcomeTime(update) >= outcomeTime(latest) ? update : latest);
176
+ const result = { ...quota };
177
+ delete result.primingCompleted;
178
+ delete result.primingFailure;
179
+ delete result.primingObservedAt;
180
+ if (outcomeTime(evidence) >= quota.updatedAt) {
181
+ if (evidence.primingCompleted)
182
+ result.primingCompleted = true;
183
+ else if (evidence.primingFailure)
184
+ result.primingFailure = evidence.primingFailure;
185
+ if (evidence.primingObservedAt !== undefined)
186
+ result.primingObservedAt = evidence.primingObservedAt;
187
+ }
188
+ return result;
189
+ }
161
190
  /** Reapply this run's changed entries, preserving unrelated or newer concurrent observations. */
162
191
  function mergeQuotaChanges(current, proposed, baseline) {
163
192
  const same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
@@ -168,24 +197,12 @@ function mergeQuotaChanges(current, proposed, baseline) {
168
197
  continue;
169
198
  const latest = current[namespace]?.[key], update = next[key];
170
199
  if (update) {
171
- if (!latest || update.updatedAt >= latest.updatedAt) {
172
- current[namespace] ??= {};
173
- current[namespace][key] = update;
174
- }
175
- else if (same(latest, before[key])) {
176
- // The on-disk entry is still exactly the one this caller's
177
- // baseline saw, so nothing concurrent touched this key:
178
- // `update` is a deliberate write whose lower stamp can only
179
- // come from a backward clock jump on this writer. Re-stamp
180
- // it just ahead instead of silently losing it. A raced key
181
- // (`!same`) falls through and keeps the on-disk entry: its
182
- // higher stamp marks a newer observation, and bumping an
183
- // older one past it would let stale quota data overwrite
184
- // fresher data.
200
+ if (latest && update.updatedAt < latest.updatedAt && same(latest, before[key])) {
201
+ // Preserve the existing backward-clock handling for an unraced write.
185
202
  update.updatedAt = latest.updatedAt + 1;
186
- current[namespace] ??= {};
187
- current[namespace][key] = update;
188
203
  }
204
+ current[namespace] ??= {};
205
+ current[namespace][key] = mergeQuotaCacheEntry(latest, update);
189
206
  }
190
207
  else if (same(latest, before[key])) {
191
208
  delete current[namespace]?.[key];
@@ -26,7 +26,10 @@ export interface CodexQuotaWindow {
26
26
  resetAtMs?: number;
27
27
  }
28
28
  export interface CodexQuotaSnapshot {
29
+ /** Time quota headers were observed, before consuming the response stream. */
30
+ observedAt?: number;
29
31
  primingCompleted?: boolean;
32
+ primingObservedAt?: number;
30
33
  primingFailure?: FirstUseProbeError["reason"];
31
34
  status: number;
32
35
  planType?: string;
@@ -382,15 +382,16 @@ export async function fetchCodexQuotaSnapshot(options) {
382
382
  }
383
383
  const snapshotBase = parseQuotaSnapshotBase(response.headers, response.status);
384
384
  if (snapshotBase) {
385
- if (options.primeUnusedSubscription && needsSubscriptionFirstUse(snapshotBase, Date.now())) {
385
+ const observedAt = Date.now();
386
+ if (options.primeUnusedSubscription && needsSubscriptionFirstUse(snapshotBase, observedAt)) {
386
387
  try {
387
388
  await finishSubscriptionFirstUse(response, timeoutMs);
388
- return { ...snapshotBase, model, primingCompleted: true };
389
+ return { ...snapshotBase, observedAt, model, primingObservedAt: Date.now(), primingCompleted: true };
389
390
  }
390
391
  catch (error) {
391
392
  // Keep valid quota data without retrying an accepted inference.
392
393
  if (error instanceof FirstUseProbeError)
393
- return { ...snapshotBase, model, primingFailure: error.reason };
394
+ return { ...snapshotBase, observedAt, model, primingObservedAt: Date.now(), primingFailure: error.reason };
394
395
  throw error;
395
396
  }
396
397
  }
@@ -400,7 +401,7 @@ export async function fetchCodexQuotaSnapshot(options) {
400
401
  catch {
401
402
  // Best effort cancellation.
402
403
  }
403
- return { ...snapshotBase, model };
404
+ return { ...snapshotBase, observedAt, model };
404
405
  }
405
406
  if (!response.ok) {
406
407
  const bodyText = await response.text().catch(() => "");
@@ -1,6 +1,6 @@
1
1
  import type { QuotaCacheData, QuotaCacheEntry } from "./quota-cache.js";
2
2
  import type { AccountMetadataV3 } from "./storage.js";
3
- export type QuotaCacheAccountRef = Pick<AccountMetadataV3, "accountId" | "email" | "recordId" | "workspaces" | "currentWorkspaceIndex"> & Partial<Pick<AccountMetadataV3, "refreshToken" | "addedAt">>;
3
+ export type QuotaCacheAccountRef = Pick<AccountMetadataV3, "accountId" | "email" | "recordId" | "workspaces" | "currentWorkspaceIndex"> & Partial<Pick<AccountMetadataV3, "refreshToken" | "addedAt" | "accessToken">>;
4
4
  export declare function normalizeQuotaAccountId(value: string | undefined): string | null;
5
5
  export declare function normalizeQuotaEmail(value: string | undefined): string | null;
6
6
  export declare function hasUniqueQuotaAccountId(accounts: readonly QuotaCacheAccountRef[], account: QuotaCacheAccountRef): boolean;
@@ -1,3 +1,4 @@
1
+ import { extractAccountId } from "./auth/token-utils.js";
1
2
  import { createHash } from "node:crypto";
2
3
  import { resolveAccountRecordId } from "./storage/record-identity.js";
3
4
  export function normalizeQuotaAccountId(value) {
@@ -101,7 +102,7 @@ export function quotaWorkspaceKey(account, workspaceId) {
101
102
  export function quotaWorkspaceId(account) {
102
103
  return account.workspaces?.length
103
104
  ? account.workspaces[account.currentWorkspaceIndex ?? 0]?.id.trim()
104
- : account.accountId?.trim();
105
+ : account.accountId?.trim() || extractAccountId(account.accessToken);
105
106
  }
106
107
  /** Read exact-workspace quota, using legacy binding entries only for that binding. */
107
108
  export function findQuotaCacheEntryForAccount(cache, account, accounts, emailFallbackState = buildQuotaEmailFallbackState(accounts), workspaceId = quotaWorkspaceId(account)) {
@@ -110,7 +111,10 @@ export function findQuotaCacheEntryForAccount(cache, account, accounts, emailFal
110
111
  const key = workspaceId && quotaWorkspaceKey(account, workspaceId);
111
112
  const scoped = key ? cache.byWorkspace?.[key] : undefined;
112
113
  // Legacy entries describe only the stored binding, never a sibling workspace.
113
- if (normalizeQuotaAccountId(workspaceId) !== normalizeQuotaAccountId(account.accountId))
114
+ // A workspaces-bearing account whose selection does not resolve (invalid index
115
+ // or blank id) has no valid binding at all — never fall back to legacy keys.
116
+ if (normalizeQuotaAccountId(workspaceId) !== normalizeQuotaAccountId(account.accountId) ||
117
+ (account.workspaces?.length && !normalizeQuotaAccountId(workspaceId)))
114
118
  return scoped ?? null;
115
119
  const accountId = normalizeQuotaAccountId(account.accountId);
116
120
  const newer = (legacy) => scoped && (!legacy || scoped.updatedAt >= legacy.updatedAt) ? scoped : legacy ?? null;