codex-multi-auth 2.16.0 → 2.17.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 (256) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +22 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +8 -3
  5. package/dist/lib/account-policy.d.ts +4 -0
  6. package/dist/lib/account-policy.d.ts.map +1 -1
  7. package/dist/lib/account-policy.js +8 -0
  8. package/dist/lib/accounts/rate-limits.d.ts.map +1 -1
  9. package/dist/lib/accounts/rate-limits.js +2 -0
  10. package/dist/lib/accounts.d.ts +21 -3
  11. package/dist/lib/accounts.d.ts.map +1 -1
  12. package/dist/lib/accounts.js +229 -17
  13. package/dist/lib/api-route-store.d.ts +24 -0
  14. package/dist/lib/api-route-store.d.ts.map +1 -0
  15. package/dist/lib/api-route-store.js +145 -0
  16. package/dist/lib/auth/account-access.d.ts +115 -0
  17. package/dist/lib/auth/account-access.d.ts.map +1 -0
  18. package/dist/lib/auth/account-access.js +214 -0
  19. package/dist/lib/auth/token-utils.d.ts +54 -1
  20. package/dist/lib/auth/token-utils.d.ts.map +1 -1
  21. package/dist/lib/auth/token-utils.js +92 -7
  22. package/dist/lib/cli.d.ts +1 -1
  23. package/dist/lib/cli.d.ts.map +1 -1
  24. package/dist/lib/cli.js +4 -0
  25. package/dist/lib/codex-cli/state.d.ts +7 -0
  26. package/dist/lib/codex-cli/state.d.ts.map +1 -1
  27. package/dist/lib/codex-cli/state.js +18 -0
  28. package/dist/lib/codex-cli/writer.d.ts.map +1 -1
  29. package/dist/lib/codex-cli/writer.js +60 -8
  30. package/dist/lib/codex-manager/account-manager-commands.d.ts.map +1 -1
  31. package/dist/lib/codex-manager/account-manager-commands.js +1 -0
  32. package/dist/lib/codex-manager/account-pool-write.d.ts +3 -1
  33. package/dist/lib/codex-manager/account-pool-write.d.ts.map +1 -1
  34. package/dist/lib/codex-manager/account-pool-write.js +4 -0
  35. package/dist/lib/codex-manager/api-login-menu.d.ts +14 -0
  36. package/dist/lib/codex-manager/api-login-menu.d.ts.map +1 -0
  37. package/dist/lib/codex-manager/api-login-menu.js +224 -0
  38. package/dist/lib/codex-manager/commands/account.d.ts.map +1 -1
  39. package/dist/lib/codex-manager/commands/account.js +27 -0
  40. package/dist/lib/codex-manager/commands/best.d.ts.map +1 -1
  41. package/dist/lib/codex-manager/commands/best.js +6 -2
  42. package/dist/lib/codex-manager/commands/check.d.ts +7 -1
  43. package/dist/lib/codex-manager/commands/check.d.ts.map +1 -1
  44. package/dist/lib/codex-manager/commands/check.js +24 -3
  45. package/dist/lib/codex-manager/commands/forecast.d.ts.map +1 -1
  46. package/dist/lib/codex-manager/commands/forecast.js +5 -1
  47. package/dist/lib/codex-manager/commands/report.d.ts.map +1 -1
  48. package/dist/lib/codex-manager/commands/report.js +5 -1
  49. package/dist/lib/codex-manager/commands/resets.d.ts +2 -0
  50. package/dist/lib/codex-manager/commands/resets.d.ts.map +1 -0
  51. package/dist/lib/codex-manager/commands/resets.js +67 -0
  52. package/dist/lib/codex-manager/commands/rotation.d.ts +2 -2
  53. package/dist/lib/codex-manager/commands/rotation.d.ts.map +1 -1
  54. package/dist/lib/codex-manager/commands/rotation.js +63 -12
  55. package/dist/lib/codex-manager/commands/status.d.ts +12 -1
  56. package/dist/lib/codex-manager/commands/status.d.ts.map +1 -1
  57. package/dist/lib/codex-manager/commands/status.js +166 -22
  58. package/dist/lib/codex-manager/commands/uninstall.js +1 -1
  59. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts.map +1 -1
  60. package/dist/lib/codex-manager/formatters/quota-formatters.js +3 -2
  61. package/dist/lib/codex-manager/health-check.d.ts +3 -0
  62. package/dist/lib/codex-manager/health-check.d.ts.map +1 -1
  63. package/dist/lib/codex-manager/health-check.js +56 -6
  64. package/dist/lib/codex-manager/help.d.ts.map +1 -1
  65. package/dist/lib/codex-manager/help.js +4 -2
  66. package/dist/lib/codex-manager/login-flow.d.ts.map +1 -1
  67. package/dist/lib/codex-manager/login-flow.js +69 -7
  68. package/dist/lib/codex-manager/login-menu-data.d.ts.map +1 -1
  69. package/dist/lib/codex-manager/login-menu-data.js +14 -5
  70. package/dist/lib/codex-manager/login-oauth.d.ts +3 -0
  71. package/dist/lib/codex-manager/login-oauth.d.ts.map +1 -1
  72. package/dist/lib/codex-manager/login-oauth.js +6 -1
  73. package/dist/lib/codex-manager/login-workspace-choice.d.ts +11 -0
  74. package/dist/lib/codex-manager/login-workspace-choice.d.ts.map +1 -0
  75. package/dist/lib/codex-manager/login-workspace-choice.js +37 -0
  76. package/dist/lib/codex-manager/persist-selected-account.d.ts.map +1 -1
  77. package/dist/lib/codex-manager/persist-selected-account.js +2 -1
  78. package/dist/lib/codex-manager/repair-commands.d.ts +13 -0
  79. package/dist/lib/codex-manager/repair-commands.d.ts.map +1 -1
  80. package/dist/lib/codex-manager/repair-commands.js +143 -8
  81. package/dist/lib/codex-manager.d.ts.map +1 -1
  82. package/dist/lib/codex-manager.js +25 -6
  83. package/dist/lib/concurrency.d.ts +3 -0
  84. package/dist/lib/concurrency.d.ts.map +1 -0
  85. package/dist/lib/concurrency.js +31 -0
  86. package/dist/lib/model-route-policy.d.ts +52 -0
  87. package/dist/lib/model-route-policy.d.ts.map +1 -0
  88. package/dist/lib/model-route-policy.js +159 -0
  89. package/dist/lib/policy/runtime-policy.d.ts +1 -0
  90. package/dist/lib/policy/runtime-policy.d.ts.map +1 -1
  91. package/dist/lib/policy/runtime-policy.js +3 -0
  92. package/dist/lib/preemptive-quota-scheduler.d.ts +2 -0
  93. package/dist/lib/preemptive-quota-scheduler.d.ts.map +1 -1
  94. package/dist/lib/preemptive-quota-scheduler.js +4 -0
  95. package/dist/lib/quota-probe.d.ts +5 -0
  96. package/dist/lib/quota-probe.d.ts.map +1 -1
  97. package/dist/lib/quota-probe.js +26 -2
  98. package/dist/lib/request/client-cancellation.d.ts +5 -0
  99. package/dist/lib/request/client-cancellation.d.ts.map +1 -0
  100. package/dist/lib/request/client-cancellation.js +7 -0
  101. package/dist/lib/request/response-outcome.d.ts +25 -0
  102. package/dist/lib/request/response-outcome.d.ts.map +1 -0
  103. package/dist/lib/request/response-outcome.js +49 -0
  104. package/dist/lib/request/stream-failover-runtime.d.ts +2 -1
  105. package/dist/lib/request/stream-failover-runtime.d.ts.map +1 -1
  106. package/dist/lib/request/stream-failover-runtime.js +29 -10
  107. package/dist/lib/runtime/account-check.d.ts.map +1 -1
  108. package/dist/lib/runtime/account-check.js +2 -8
  109. package/dist/lib/runtime/account-model-catalog.d.ts +64 -0
  110. package/dist/lib/runtime/account-model-catalog.d.ts.map +1 -0
  111. package/dist/lib/runtime/account-model-catalog.js +154 -0
  112. package/dist/lib/runtime/account-pool.d.ts +3 -1
  113. package/dist/lib/runtime/account-pool.d.ts.map +1 -1
  114. package/dist/lib/runtime/account-pool.js +4 -0
  115. package/dist/lib/runtime/account-reset-credits.d.ts +42 -0
  116. package/dist/lib/runtime/account-reset-credits.d.ts.map +1 -0
  117. package/dist/lib/runtime/account-reset-credits.js +82 -0
  118. package/dist/lib/runtime/api-model-capabilities.d.ts +30 -0
  119. package/dist/lib/runtime/api-model-capabilities.d.ts.map +1 -0
  120. package/dist/lib/runtime/api-model-capabilities.js +434 -0
  121. package/dist/lib/runtime/api-model-runtime.d.ts +42 -0
  122. package/dist/lib/runtime/api-model-runtime.d.ts.map +1 -0
  123. package/dist/lib/runtime/api-model-runtime.js +358 -0
  124. package/dist/lib/runtime/app-bind.d.ts +19 -1
  125. package/dist/lib/runtime/app-bind.d.ts.map +1 -1
  126. package/dist/lib/runtime/app-bind.js +79 -9
  127. package/dist/lib/runtime/automatic-account-checks.d.ts +31 -0
  128. package/dist/lib/runtime/automatic-account-checks.d.ts.map +1 -0
  129. package/dist/lib/runtime/automatic-account-checks.js +113 -0
  130. package/dist/lib/runtime/automatic-subscription-checks.d.ts +7 -0
  131. package/dist/lib/runtime/automatic-subscription-checks.d.ts.map +1 -0
  132. package/dist/lib/runtime/automatic-subscription-checks.js +57 -0
  133. package/dist/lib/runtime/catalog-capabilities.d.ts +8 -0
  134. package/dist/lib/runtime/catalog-capabilities.d.ts.map +1 -0
  135. package/dist/lib/runtime/catalog-capabilities.js +61 -0
  136. package/dist/lib/runtime/inference-activity.d.ts +15 -0
  137. package/dist/lib/runtime/inference-activity.d.ts.map +1 -0
  138. package/dist/lib/runtime/inference-activity.js +95 -0
  139. package/dist/lib/runtime/model-discovery-status.d.ts +100 -0
  140. package/dist/lib/runtime/model-discovery-status.d.ts.map +1 -0
  141. package/dist/lib/runtime/model-discovery-status.js +387 -0
  142. package/dist/lib/runtime/native-account-storage.d.ts +11 -0
  143. package/dist/lib/runtime/native-account-storage.d.ts.map +1 -0
  144. package/dist/lib/runtime/native-account-storage.js +50 -0
  145. package/dist/lib/runtime/native-account-sync.d.ts +19 -0
  146. package/dist/lib/runtime/native-account-sync.d.ts.map +1 -0
  147. package/dist/lib/runtime/native-account-sync.js +62 -0
  148. package/dist/lib/runtime/native-binding-lock.d.ts +3 -0
  149. package/dist/lib/runtime/native-binding-lock.d.ts.map +1 -0
  150. package/dist/lib/runtime/native-binding-lock.js +5 -0
  151. package/dist/lib/runtime/native-client-auth.d.ts +3 -0
  152. package/dist/lib/runtime/native-client-auth.d.ts.map +1 -0
  153. package/dist/lib/runtime/native-client-auth.js +42 -0
  154. package/dist/lib/runtime/native-provider-config.d.ts +4 -0
  155. package/dist/lib/runtime/native-provider-config.d.ts.map +1 -0
  156. package/dist/lib/runtime/native-provider-config.js +52 -0
  157. package/dist/lib/runtime/native-rate-limits.d.ts +18 -0
  158. package/dist/lib/runtime/native-rate-limits.d.ts.map +1 -0
  159. package/dist/lib/runtime/native-rate-limits.js +135 -0
  160. package/dist/lib/runtime/reset-credit-routing.d.ts +41 -0
  161. package/dist/lib/runtime/reset-credit-routing.d.ts.map +1 -0
  162. package/dist/lib/runtime/reset-credit-routing.js +66 -0
  163. package/dist/lib/runtime/reset-credits.d.ts +101 -0
  164. package/dist/lib/runtime/reset-credits.d.ts.map +1 -0
  165. package/dist/lib/runtime/reset-credits.js +162 -0
  166. package/dist/lib/runtime/response-output-history.d.ts +17 -0
  167. package/dist/lib/runtime/response-output-history.d.ts.map +1 -0
  168. package/dist/lib/runtime/response-output-history.js +85 -0
  169. package/dist/lib/runtime/responses-websocket.d.ts +31 -0
  170. package/dist/lib/runtime/responses-websocket.d.ts.map +1 -0
  171. package/dist/lib/runtime/responses-websocket.js +636 -0
  172. package/dist/lib/runtime/resume-picker.d.ts +41 -0
  173. package/dist/lib/runtime/resume-picker.d.ts.map +1 -0
  174. package/dist/lib/runtime/resume-picker.js +169 -0
  175. package/dist/lib/runtime/rotation-account-selection.d.ts +6 -0
  176. package/dist/lib/runtime/rotation-account-selection.d.ts.map +1 -1
  177. package/dist/lib/runtime/rotation-account-selection.js +63 -0
  178. package/dist/lib/runtime/rotation-proxy-state.d.ts +33 -0
  179. package/dist/lib/runtime/rotation-proxy-state.d.ts.map +1 -1
  180. package/dist/lib/runtime/rotation-server-types.d.ts +18 -0
  181. package/dist/lib/runtime/rotation-server-types.d.ts.map +1 -1
  182. package/dist/lib/runtime/runtime-capability-failures.d.ts +14 -0
  183. package/dist/lib/runtime/runtime-capability-failures.d.ts.map +1 -0
  184. package/dist/lib/runtime/runtime-capability-failures.js +76 -0
  185. package/dist/lib/runtime/runtime-observability.d.ts +7 -0
  186. package/dist/lib/runtime/runtime-observability.d.ts.map +1 -1
  187. package/dist/lib/runtime/runtime-observability.js +42 -2
  188. package/dist/lib/runtime/subscription-first-use.d.ts +10 -0
  189. package/dist/lib/runtime/subscription-first-use.d.ts.map +1 -0
  190. package/dist/lib/runtime/subscription-first-use.js +64 -0
  191. package/dist/lib/runtime/subscription-quota-event.d.ts +6 -0
  192. package/dist/lib/runtime/subscription-quota-event.d.ts.map +1 -0
  193. package/dist/lib/runtime/subscription-quota-event.js +31 -0
  194. package/dist/lib/runtime/subscription-quota-order.d.ts +17 -0
  195. package/dist/lib/runtime/subscription-quota-order.d.ts.map +1 -0
  196. package/dist/lib/runtime/subscription-quota-order.js +31 -0
  197. package/dist/lib/runtime/workspace-model-scopes.d.ts +15 -0
  198. package/dist/lib/runtime/workspace-model-scopes.d.ts.map +1 -0
  199. package/dist/lib/runtime/workspace-model-scopes.js +34 -0
  200. package/dist/lib/runtime-constants.d.ts +3 -0
  201. package/dist/lib/runtime-constants.d.ts.map +1 -1
  202. package/dist/lib/runtime-constants.js +5 -0
  203. package/dist/lib/runtime-paths.d.ts.map +1 -1
  204. package/dist/lib/runtime-paths.js +4 -1
  205. package/dist/lib/runtime-rotation-proxy.d.ts.map +1 -1
  206. package/dist/lib/runtime-rotation-proxy.js +852 -42
  207. package/dist/lib/schemas.d.ts +20 -0
  208. package/dist/lib/schemas.d.ts.map +1 -1
  209. package/dist/lib/schemas.js +3 -0
  210. package/dist/lib/storage/credential-sidecars.d.ts +13 -0
  211. package/dist/lib/storage/credential-sidecars.d.ts.map +1 -0
  212. package/dist/lib/storage/credential-sidecars.js +52 -0
  213. package/dist/lib/storage/file-lock.d.ts +9 -0
  214. package/dist/lib/storage/file-lock.d.ts.map +1 -0
  215. package/dist/lib/storage/file-lock.js +186 -0
  216. package/dist/lib/storage/flagged-storage.d.ts.map +1 -1
  217. package/dist/lib/storage/flagged-storage.js +12 -0
  218. package/dist/lib/storage/path-state.d.ts +2 -0
  219. package/dist/lib/storage/path-state.d.ts.map +1 -1
  220. package/dist/lib/storage/path-state.js +9 -0
  221. package/dist/lib/storage/paths.js +4 -4
  222. package/dist/lib/storage/pending-auth.d.ts +17 -0
  223. package/dist/lib/storage/pending-auth.d.ts.map +1 -0
  224. package/dist/lib/storage/pending-auth.js +153 -0
  225. package/dist/lib/storage/public-types.d.ts +13 -0
  226. package/dist/lib/storage/public-types.d.ts.map +1 -1
  227. package/dist/lib/storage/snapshot-merge.d.ts +16 -0
  228. package/dist/lib/storage/snapshot-merge.d.ts.map +1 -0
  229. package/dist/lib/storage/snapshot-merge.js +206 -0
  230. package/dist/lib/storage/transactions.d.ts.map +1 -1
  231. package/dist/lib/storage/transactions.js +5 -4
  232. package/dist/lib/storage.d.ts +6 -0
  233. package/dist/lib/storage.d.ts.map +1 -1
  234. package/dist/lib/storage.js +77 -7
  235. package/dist/lib/ui/auth-menu-builder.d.ts +2 -0
  236. package/dist/lib/ui/auth-menu-builder.d.ts.map +1 -1
  237. package/dist/lib/ui/auth-menu-builder.js +1 -0
  238. package/dist/lib/ui/auth-menu.d.ts.map +1 -1
  239. package/dist/lib/ui/auth-menu.js +1 -0
  240. package/dist/lib/ui/check-progress.d.ts +8 -0
  241. package/dist/lib/ui/check-progress.d.ts.map +1 -0
  242. package/dist/lib/ui/check-progress.js +30 -0
  243. package/dist/lib/ui/format.d.ts +3 -1
  244. package/dist/lib/ui/format.d.ts.map +1 -1
  245. package/dist/lib/ui/format.js +8 -0
  246. package/dist/lib/ui/ui-copy.d.ts +2 -2
  247. package/dist/lib/ui/ui-copy.js +2 -2
  248. package/dist/lib/usage/pricing.js +2 -2
  249. package/dist/lib/usage/usage-extraction.d.ts +3 -1
  250. package/dist/lib/usage/usage-extraction.d.ts.map +1 -1
  251. package/dist/lib/usage/usage-extraction.js +46 -9
  252. package/package.json +7 -4
  253. package/scripts/codex-app-router.js +7 -0
  254. package/scripts/codex-bin-resolver.js +40 -8
  255. package/scripts/codex-routing.js +1 -0
  256. package/scripts/codex.js +100 -22
@@ -0,0 +1,2 @@
1
+ export declare function runResetsCommand(args: string[]): Promise<number>;
2
+ //# sourceMappingURL=resets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resets.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/resets.ts"],"names":[],"mappings":"AAMA,wBAAsB,gBAAgB,CAAC,IAAI,EAAC,MAAM,EAAE,GAAE,OAAO,CAAC,MAAM,CAAC,CA8BpE"}
@@ -0,0 +1,67 @@
1
+ import { AccountManager } from '../../accounts.js';
2
+ import { loadAccounts } from '../../storage.js';
3
+ import { runWithGlobalStoragePath } from '../../storage/path-state.js';
4
+ import { createResetCreditService, resetTargetForStoredAccount, resetAccountLabel } from '../../runtime/account-reset-credits.js';
5
+ import { withCheckProgress } from '../../ui/check-progress.js';
6
+ const usage = 'Usage: codex-multi-auth resets list [--refresh] | redeem <account-number> | auto manual|last-resort';
7
+ export async function runResetsCommand(args) {
8
+ const [command = 'list', value, ...extra] = args;
9
+ if (command === '--help' || command === '-h') {
10
+ console.log(usage);
11
+ return 0;
12
+ }
13
+ if (extra.length || !['list', 'redeem', 'auto'].includes(command) || (command === 'list' && value !== undefined && value !== '--refresh') || (command === 'redeem' && !/^[1-9][0-9]*$/.test(value ?? '')) || (command === 'auto' && value !== 'manual' && value !== 'last-resort')) {
14
+ console.error(usage);
15
+ return 1;
16
+ }
17
+ return runWithGlobalStoragePath(async () => {
18
+ const storage = await loadAccounts();
19
+ const manager = new AccountManager(undefined, storage);
20
+ const service = createResetCreditService(manager);
21
+ try {
22
+ if (command === 'auto') {
23
+ await service.setPolicy(value);
24
+ console.log(`Automatic reset redemption: ${value}`);
25
+ return 0;
26
+ }
27
+ if (command === 'redeem') {
28
+ const index = Number(value) - 1;
29
+ const account = storage?.accounts[index];
30
+ const target = account && resetTargetForStoredAccount(account);
31
+ if (!target) {
32
+ console.error('Choose a configured, enabled subscription account/workspace.');
33
+ return 1;
34
+ }
35
+ const outcome = await withCheckProgress(`Redeeming a reset for account ${index + 1}`, () => service.redeem(target));
36
+ console.log(`Account ${index + 1}: ${outcome}. Usage was re-read.`);
37
+ return 0;
38
+ }
39
+ const targets = (storage?.accounts ?? []).map(resetTargetForStoredAccount).filter(t => t !== null);
40
+ const refreshed = value === '--refresh' ? await withCheckProgress('Refreshing reset-credit availability', () => service.refresh(targets)) : null;
41
+ const state = await service.status();
42
+ console.log(`Automatic redemption: ${state.policy}`);
43
+ if (state.lastRedemption) {
44
+ const index = (storage?.accounts ?? []).findIndex(a => resetTargetForStoredAccount(a)?.key === state.lastRedemption?.key);
45
+ console.log(`Last confirmed reset: ${index >= 0 ? `account ${index + 1}` : "removed account"}; ${state.lastRedemption.outcome}; ${state.lastRedemption.automatic ? "automatic" : "explicit"}`);
46
+ }
47
+ (storage?.accounts ?? []).forEach((a, i) => { const target = resetTargetForStoredAccount(a); const snapshot = target ? (refreshed ?? state.snapshots)[target.key] : undefined; console.log(`${resetAccountLabel(a, i)}: ${snapshot?.availableCount ?? 'unknown'} reset credits${snapshot ? ` (checked ${Math.max(0, Math.floor((Date.now() - snapshot.updatedAt) / 1000))}s ago)` : ''}${target?.key === state.pending?.key ? ' [redemption pending; retry this account]' : ''}`); });
48
+ return 0;
49
+ }
50
+ catch {
51
+ // Only a consume whose result is unknown leaves a pending record; guard,
52
+ // pre-read and unknown-availability failures stop before spending anything.
53
+ const pending = command === 'redeem' ? await service.status().then(s => s.pending ?? null, () => ({ key: undefined })) : null;
54
+ // The pending record can belong to another account (a redeem is refused while
55
+ // any result is pending); point at the account that actually needs the retry.
56
+ const owner = pending?.key ? (storage?.accounts ?? []).findIndex(a => resetTargetForStoredAccount({ ...a, enabled: true, workspaces: undefined })?.key === pending.key) : -1;
57
+ const pendingAccount = owner >= 0 ? storage?.accounts[owner] : undefined;
58
+ const disabled = pendingAccount ? resetTargetForStoredAccount(pendingAccount) === null : false;
59
+ const retry = disabled ? `account ${owner + 1} or its workspace is disabled; re-enable it before retrying the pending result` : pending?.key && owner < 0 ? 'check it there (the pending account was removed)' : owner >= 0 && owner !== Number(value) - 1 ? `retry account ${owner + 1}, which holds the pending result` : 'retry the same account';
60
+ console.error(command === 'list' ? 'Reset-credit availability could not be refreshed. No credits were redeemed.' : command === 'auto' ? 'Reset-credit settings could not be updated.' : pending ? `Reset operation could not be confirmed. No new automatic redemption will be attempted while a result is pending; use resets list and ${retry}.` : 'No reset credit was redeemed. Availability could not be confirmed or a reset was just redeemed; run resets list --refresh and try again.');
61
+ return 1;
62
+ }
63
+ finally {
64
+ await manager.flushPendingSave();
65
+ }
66
+ });
67
+ }
@@ -1,4 +1,4 @@
1
- import { type AppBindResult, type AppBindStatus } from "../../runtime/app-bind.js";
1
+ import { type AppBindOptions, type AppBindResult, type AppBindStatus } from "../../runtime/app-bind.js";
2
2
  import type { QuotaCacheData } from "../../quota-cache.js";
3
3
  import { type RuntimeObservabilitySnapshot } from "../../runtime/runtime-observability.js";
4
4
  import type { PluginConfig } from "../../types.js";
@@ -13,7 +13,7 @@ export interface RotationCommandDeps {
13
13
  resolveActiveIndex: (storage: AccountStorageV3) => number;
14
14
  getStoragePath: () => string | null;
15
15
  setStoragePath: (path: string | null) => void;
16
- bindCodexApp?: () => Promise<AppBindResult>;
16
+ bindCodexApp?: (options?: AppBindOptions) => Promise<AppBindResult>;
17
17
  unbindCodexApp?: () => Promise<AppBindResult>;
18
18
  getCodexAppBindStatus?: () => Promise<AppBindStatus>;
19
19
  loadRuntimeObservabilitySnapshot?: () => Promise<RuntimeObservabilitySnapshot | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/rotation.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEN,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wCAAwC,CAAC;AAahD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAoB7C,MAAM,WAAW,mBAAmB;IACnC,gBAAgB,EAAE,MAAM,YAAY,CAAC;IACrC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,4BAA4B,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC1D,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA4pBD,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAkFjB"}
1
+ {"version":3,"file":"rotation.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/rotation.ts"],"names":[],"mappings":"AA2BA,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,2BAA2B,CAAC;AAMnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAEN,KAAK,4BAA4B,EACjC,MAAM,wCAAwC,CAAC;AAahD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAqB,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAG5E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAoB7C,MAAM,WAAW,mBAAmB;IACnC,gBAAgB,EAAE,MAAM,YAAY,CAAC;IACrC,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,4BAA4B,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;IAChE,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC1D,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACpE,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAkqBD,wBAAsB,kBAAkB,CACvC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,mBAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAyHjB"}
@@ -30,7 +30,7 @@ function printRotationUsage(logInfo) {
30
30
  " codex-multi-auth rotation enable",
31
31
  " codex-multi-auth rotation disable",
32
32
  " codex-multi-auth rotation status",
33
- " codex-multi-auth rotation bind-app",
33
+ " codex-multi-auth rotation bind-app [--native [--catalog-account <idx>] | --custom-provider]",
34
34
  " codex-multi-auth rotation unbind-app",
35
35
  " codex-multi-auth rotation reset-rate-limits [--all | --account <idx>] [--dry-run] [--json]",
36
36
  " codex-multi-auth rotation reset-runtime [--json]",
@@ -64,8 +64,14 @@ async function runResetRuntime(args, deps) {
64
64
  let appBindRestarted = false;
65
65
  if (deps.unbindCodexApp && deps.bindCodexApp) {
66
66
  try {
67
+ const previous = await deps.getCodexAppBindStatus?.();
67
68
  unbind = await deps.unbindCodexApp();
68
- bind = await deps.bindCodexApp();
69
+ bind = previous?.state?.nativeOpenai
70
+ ? await deps.bindCodexApp({
71
+ nativeOpenai: true,
72
+ catalogAccount: previous.state.catalogAccount,
73
+ })
74
+ : await deps.bindCodexApp(...(previous?.state ? [{ nativeOpenai: false }] : []));
69
75
  appBindRestarted = true;
70
76
  }
71
77
  catch (error) {
@@ -630,6 +636,61 @@ export async function runRotationCommand(args, deps) {
630
636
  if (subcommand === "reset-runtime") {
631
637
  return runResetRuntime(rest, deps);
632
638
  }
639
+ if (subcommand === "bind-app") {
640
+ if (!deps.bindCodexApp) {
641
+ logError("Codex app bind is unavailable in this build.");
642
+ return 1;
643
+ }
644
+ const options = {};
645
+ let catalogIndex;
646
+ for (let i = 0; i < rest.length; i += 1) {
647
+ const arg = rest[i];
648
+ if (arg === "--native" || arg === "--custom-provider") {
649
+ if (options.nativeOpenai !== undefined) {
650
+ logError("Choose one app bind mode.");
651
+ return 1;
652
+ }
653
+ options.nativeOpenai = arg === "--native";
654
+ }
655
+ else if (arg === "--catalog-account" && catalogIndex === undefined) {
656
+ const value = rest[++i] ?? "";
657
+ if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value))) {
658
+ logError("Catalog account must be a positive account index.");
659
+ return 1;
660
+ }
661
+ catalogIndex = Number(value) - 1;
662
+ }
663
+ else {
664
+ logError(`Unknown app bind option: ${arg}`);
665
+ return 1;
666
+ }
667
+ }
668
+ if (catalogIndex !== undefined) {
669
+ if (options.nativeOpenai !== true) {
670
+ logError("--catalog-account requires --native.");
671
+ return 1;
672
+ }
673
+ const previousStoragePath = deps.getStoragePath();
674
+ deps.setStoragePath(null);
675
+ let catalogStorage;
676
+ try {
677
+ catalogStorage = await deps.loadAccounts();
678
+ }
679
+ finally {
680
+ deps.setStoragePath(previousStoragePath);
681
+ }
682
+ const account = catalogStorage?.accounts[catalogIndex];
683
+ if (!account?.email || !account.accountId || account.enabled === false) {
684
+ logError("Catalog account must be an enabled account with an email and account ID.");
685
+ return 1;
686
+ }
687
+ options.catalogAccount = { email: account.email, accountId: account.accountId };
688
+ }
689
+ const result = rest.length ? await deps.bindCodexApp(options) : await deps.bindCodexApp();
690
+ logInfo(result.message);
691
+ logInfo(formatAppBindStatus(result.status));
692
+ return 0;
693
+ }
633
694
  if (rest.length > 0) {
634
695
  logError(`Unknown rotation option: ${rest[0]}`);
635
696
  return 1;
@@ -669,16 +730,6 @@ export async function runRotationCommand(args, deps) {
669
730
  }
670
731
  return 0;
671
732
  }
672
- if (subcommand === "bind-app") {
673
- if (!deps.bindCodexApp) {
674
- logError("Codex app bind is unavailable in this build.");
675
- return 1;
676
- }
677
- const result = await deps.bindCodexApp();
678
- logInfo(result.message);
679
- logInfo(formatAppBindStatus(result.status));
680
- return 0;
681
- }
682
733
  if (subcommand === "unbind-app") {
683
734
  if (!deps.unbindCodexApp) {
684
735
  logError("Codex app bind is unavailable in this build.");
@@ -1,3 +1,7 @@
1
+ import { type loadResetCreditState } from "../../runtime/account-reset-credits.js";
2
+ import type { ApiRouteCredential } from "../../api-route-store.js";
3
+ import { loadAccountPolicyStore } from "../../account-policy.js";
4
+ import { type ModelInventory } from "../../runtime/model-discovery-status.js";
1
5
  import type { ModelFamily } from "../../prompts/codex.js";
2
6
  import type { QuotaCacheData } from "../../quota-cache.js";
3
7
  import type { AppBindRouterStatus } from "../../runtime/app-bind.js";
@@ -6,14 +10,21 @@ import type { RuntimeObservabilitySnapshot } from "../../runtime/runtime-observa
6
10
  import type { AccountStorageV3, StorageHealthSummary } from "../../storage.js";
7
11
  type LoadedStorage = AccountStorageV3 | null;
8
12
  export interface StatusCommandDeps {
13
+ loadResetCreditState?: typeof loadResetCreditState;
9
14
  setStoragePath: (path: string | null) => void;
10
15
  getStoragePath: () => string | null;
11
16
  loadAccounts: () => Promise<LoadedStorage>;
12
17
  resolveActiveIndex: (storage: AccountStorageV3, family?: ModelFamily) => number;
13
18
  formatRateLimitEntry: (account: AccountStorageV3["accounts"][number], now: number, family: ModelFamily) => string | null;
14
19
  loadRuntimeObservabilitySnapshot?: () => Promise<RuntimeObservabilitySnapshot | null>;
15
- loadAppBindStatus?: () => Promise<AppBindRouterStatus | null>;
20
+ loadAppBindStatus?: () => Promise<(AppBindRouterStatus & {
21
+ nativeOpenai?: boolean;
22
+ }) | null>;
23
+ loadAccountPolicies?: typeof loadAccountPolicyStore;
16
24
  loadAppHelperStatus?: () => RuntimeAccountSignal | null;
25
+ loadModelInventory?: () => Promise<ModelInventory | null>;
26
+ loadApiRoutes?: () => Promise<ApiRouteCredential[]>;
27
+ loadInferenceRequestTimes?: (keys: string[]) => Promise<Record<string, number>>;
17
28
  loadQuotaCache?: () => Promise<QuotaCacheData | null>;
18
29
  inspectStorageHealth?: () => Promise<StorageHealthSummary>;
19
30
  getNow?: () => number;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/status.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAG7C,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,kBAAkB,EAAE,CACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,WAAW,KAChB,MAAM,CAAC;IACZ,oBAAoB,EAAE,CACrB,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,KACf,MAAM,GAAG,IAAI,CAAC;IACnB,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAC9D,mBAAmB,CAAC,EAAE,MAAM,oBAAoB,GAAG,IAAI,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AA2ED,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,CAAC,CAwOjB;AAED,MAAM,WAAW,mBAAmB;IACnC,mBAAmB,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQpE"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAIhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EAAE,sBAAsB,EAAuB,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAYpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAK1D,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAGN,KAAK,oBAAoB,EACzB,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAC3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,KAAK,aAAa,GAAG,gBAAgB,GAAG,IAAI,CAAC;AAG7C,MAAM,WAAW,iBAAiB;IACjC,oBAAoB,CAAC,EAAE,OAAO,oBAAoB,CAAC;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IAC3C,kBAAkB,EAAE,CACnB,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,WAAW,KAChB,MAAM,CAAC;IACZ,oBAAoB,EAAE,CACrB,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAC7C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,WAAW,KACf,MAAM,GAAG,IAAI,CAAC;IACnB,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IACtF,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC,mBAAmB,GAAG;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7F,mBAAmB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACpD,mBAAmB,CAAC,EAAE,MAAM,oBAAoB,GAAG,IAAI,CAAC;IACxD,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1D,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACpD,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtD,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAiFD,wBAAsB,gBAAgB,CACrC,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,MAAM,CAAC,CA2VjB;AAED,MAAM,WAAW,mBAAmB;IACnC,mBAAmB,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAQpE"}
@@ -1,3 +1,11 @@
1
+ import { resetSnapshotQuota } from "../../runtime/reset-credits.js";
2
+ import { resetTargetForStoredAccount } from "../../runtime/account-reset-credits.js";
3
+ import { subscriptionQuotaPreference, compareSubscriptionQuota, usesSubscriptionReserve, SUBSCRIPTION_RESERVE_PERCENT } from "../../runtime/subscription-quota-order.js";
4
+ import { styleReportText as paint } from "../../ui/format.js";
5
+ import { inferenceAccountKey } from "../../runtime/inference-activity.js";
6
+ import { modelScopeId } from "../../runtime/workspace-model-scopes.js";
7
+ import { loadAccountPolicyStore, getAccountPolicyKey } from "../../account-policy.js";
8
+ import { formatModelInventory } from "../../runtime/model-discovery-status.js";
1
9
  import { AUTH_INVALIDATION_MARKER, formatAccountLabel, formatCooldown, formatWaitTime, formatWorkspaceLines, } from "../../accounts.js";
2
10
  import { evaluateForecastAccounts, recommendForecastAccount, } from "../../forecast.js";
3
11
  import { findQuotaCacheEntryForAccount, isQuotaCacheEntryExhausted, } from "../../quota-readiness.js";
@@ -60,13 +68,30 @@ function formatRuntimeLastAccount(runtimeSnapshot) {
60
68
  }
61
69
  return null;
62
70
  }
71
+ /** Expired observations must not impose pressure after their window has reset. */
72
+ function forecastQuotaWindow(window, updatedAt, now) {
73
+ const expiresAt = window.resetAtMs ?? (window.windowMinutes && window.windowMinutes > 0 ? updatedAt + window.windowMinutes * 60_000 : null);
74
+ return expiresAt !== null && now >= expiresAt ? {} : window;
75
+ }
63
76
  export async function runStatusCommand(deps) {
64
77
  deps.setStoragePath(null);
65
- const storage = await deps.loadAccounts();
78
+ let apiConfigurationUnavailable = false;
79
+ const apiRoutes = await deps.loadApiRoutes?.().catch(() => { apiConfigurationUnavailable = true; return []; }) ?? [];
80
+ const loadedStorage = await deps.loadAccounts();
81
+ const storage = loadedStorage ?? (apiRoutes.length ? { version: 3, activeIndex: 0, accounts: [] } : null);
66
82
  const path = deps.getStoragePath();
67
83
  const storageHealth = await deps.inspectStorageHealth?.();
68
84
  const logInfo = deps.logInfo ?? console.log;
69
- if (!storage || storage.accounts.length === 0) {
85
+ if (apiConfigurationUnavailable && !deps.json)
86
+ logInfo("API configuration unavailable; subscription status remains available.");
87
+ const modelInventory = await deps.loadModelInventory?.();
88
+ const resetCredits = await deps.loadResetCreditState?.().catch(() => null);
89
+ const resetSnapshot = (account) => { const target = resetTargetForStoredAccount(account); return target ? resetCredits?.snapshots[target.key] : undefined; };
90
+ const accountPolicies = await (deps.loadAccountPolicies ?? loadAccountPolicyStore)().catch(() => ({ version: 1, accounts: {} }));
91
+ if (!deps.json && deps.loadModelInventory)
92
+ for (const line of formatModelInventory(modelInventory ?? null))
93
+ logInfo(line);
94
+ if (!storage || (storage.accounts.length === 0 && apiRoutes.length === 0)) {
70
95
  const restoreReason = storage ? readRestoreReason(storage) : undefined;
71
96
  const effectiveState = restoreReason === "intentional-reset"
72
97
  ? "intentional-reset"
@@ -78,8 +103,12 @@ export async function runStatusCommand(deps) {
78
103
  if (deps.json) {
79
104
  logInfo(JSON.stringify({
80
105
  storagePath: path,
106
+ ...(apiConfigurationUnavailable ? { warnings: ["api_configuration_unavailable"] } : {}),
81
107
  storageHealth: effectiveState ?? null,
82
108
  accountCount: 0,
109
+ totalAccountCount: 0,
110
+ apiAccounts: [],
111
+ modelInventory: modelInventory ?? null,
83
112
  // Emit the same keys the populated branch does (as null) so a
84
113
  // --json consumer sees one stable shape regardless of account count.
85
114
  activeIndex: null,
@@ -98,37 +127,84 @@ export async function runStatusCommand(deps) {
98
127
  : effectiveState === "corrupt"
99
128
  ? "No accounts configured. Storage appears corrupted."
100
129
  : "No accounts configured.");
101
- logInfo(`Storage: ${path}`);
130
+ logInfo(paint(`Storage: ${path}`, "muted"));
102
131
  if (effectiveState) {
103
132
  logInfo(`Storage health: ${effectiveState}`);
104
133
  }
105
134
  return 0;
106
135
  }
107
136
  const now = deps.getNow?.() ?? Date.now();
108
- const activeIndex = deps.resolveActiveIndex(storage, "codex");
137
+ const activeIndex = storage.accounts.length ? deps.resolveActiveIndex(storage, "codex") : -1;
138
+ const quotaCache = await deps.loadQuotaCache?.() ?? null;
139
+ const forecastQuotas = storage.accounts.map(account => {
140
+ const cached = findQuotaCacheEntryForAccount(quotaCache, account, storage.accounts);
141
+ const reset = resetSnapshot(account);
142
+ const entry = reset && reset.updatedAt > (cached?.updatedAt ?? 0) && reset.updatedAt <= now && now - reset.updatedAt <= 60000 ? resetSnapshotQuota(reset) : cached;
143
+ if (!entry)
144
+ return null;
145
+ const primary = forecastQuotaWindow(entry.primary, entry.updatedAt, now);
146
+ const secondary = forecastQuotaWindow(entry.secondary, entry.updatedAt, now);
147
+ if (![primary, secondary].some(window => typeof window.usedPercent === "number" && Number.isFinite(window.usedPercent)))
148
+ return null;
149
+ return { ...entry, primary, secondary };
150
+ });
109
151
  const forecastResults = evaluateForecastAccounts(storage.accounts.map((account, index) => ({
110
152
  index,
111
153
  account,
112
154
  isCurrent: index === activeIndex,
113
155
  now,
156
+ quotaCache,
157
+ allAccounts: storage.accounts,
158
+ liveQuota: forecastQuotas[index] ?? undefined,
114
159
  })));
115
160
  const recommendation = recommendForecastAccount(forecastResults);
116
161
  if (!deps.json) {
117
- logInfo(`Accounts (${storage.accounts.length})`);
118
- logInfo(`Storage: ${path}`);
162
+ logInfo(paint(apiRoutes.length ? `Accounts (${storage.accounts.length + apiRoutes.length}: ${storage.accounts.length} subscription, ${apiRoutes.length} API/ZDR)` : `Accounts (${storage.accounts.length})`, "heading"));
163
+ logInfo(paint(`Storage: ${path}`, "muted"));
119
164
  if (recommendation.recommendedIndex !== null) {
120
- logInfo(`Selection reason: account ${recommendation.recommendedIndex + 1} (${recommendation.reason})`);
165
+ logInfo(paint(`Forecast suggestion: account ${recommendation.recommendedIndex + 1} (${recommendation.reason})`, "accent"));
121
166
  }
122
167
  if (storageHealth) {
123
- logInfo(`Storage health: ${storageHealth.state}`);
168
+ logInfo(paint(`Storage health: ${storageHealth.state}`, storageHealth.state === "healthy" ? "success" : "warning"));
124
169
  }
125
170
  }
126
171
  const appHelperStatus = deps.loadAppHelperStatus?.() ?? null;
127
- const [runtimeSnapshot, appBindStatus, quotaCache] = await Promise.all([
172
+ const [runtimeSnapshot, appBindStatus] = await Promise.all([
128
173
  deps.loadRuntimeObservabilitySnapshot?.() ?? Promise.resolve(null),
129
174
  deps.loadAppBindStatus?.() ?? Promise.resolve(null),
130
- deps.loadQuotaCache?.() ?? Promise.resolve(null),
131
175
  ]);
176
+ const quotaPreferences = forecastQuotas.map(quota => subscriptionQuotaPreference(quota, now));
177
+ const automaticOrder = new Map();
178
+ if (appBindStatus?.nativeOpenai) {
179
+ const candidates = storage.accounts.map((account, index) => ({ account, index, quota: quotaPreferences[index] ?? subscriptionQuotaPreference(null, now), tier: accountPolicies.accounts[getAccountPolicyKey(account, index)]?.priority ?? 1 }))
180
+ .filter(a => forecastResults[a.index]?.availability === "ready" && !a.quota.exhausted);
181
+ candidates.sort((a, b) => Number(usesSubscriptionReserve(a.quota)) - Number(usesSubscriptionReserve(b.quota)) ||
182
+ a.tier - b.tier || compareSubscriptionQuota(a.quota, b.quota) || Number(b.index === activeIndex) - Number(a.index === activeIndex) || a.index - b.index);
183
+ // A switch pin is strict in native mode too: no other account is tried, so none gets an order.
184
+ const pinned = typeof storage.pinnedAccountIndex === "number" ? candidates.filter(a => a.index === storage.pinnedAccountIndex) : candidates;
185
+ pinned.forEach((a, index) => { automaticOrder.set(a.index, index + 1); });
186
+ }
187
+ const activityKeys = [...storage.accounts.map(inferenceAccountKey), ...apiRoutes.map(route => `sha256:${modelScopeId(route.kind, route.id)}`)];
188
+ const persistedActivity = await deps.loadInferenceRequestTimes?.(activityKeys) ?? {};
189
+ const inferenceTimes = { ...runtimeSnapshot?.lastInferenceRequestAtByAccount };
190
+ for (const [key, at] of Object.entries(persistedActivity))
191
+ inferenceTimes[key] = Math.max(inferenceTimes[key] ?? 0, at);
192
+ const apiAccounts = apiRoutes.map((route, index) => ({
193
+ index, label: route.label, kind: route.kind, enabled: route.enabled, priority: route.priority,
194
+ visibleModelCount: route.visibleModels.length,
195
+ lastInferenceRequestAt: inferenceTimes[`sha256:${modelScopeId(route.kind, route.id)}`] ?? null,
196
+ }));
197
+ const printApiAccounts = () => {
198
+ if (!apiAccounts.length)
199
+ return;
200
+ logInfo("");
201
+ logInfo(paint(`API/ZDR accounts (${apiAccounts.length}; separate privacy pools, lower tier first):`, "heading"));
202
+ for (const account of apiAccounts) {
203
+ const last = account.lastInferenceRequestAt === null ? "inference not yet recorded" : `last inference request ${formatWaitTime(Math.max(0, now - account.lastInferenceRequestAt))} ago`;
204
+ logInfo(`${paint(`${account.kind.toUpperCase()} account ${account.index + 1}: ${account.label}`, "heading")}${account.enabled ? "" : paint(" [disabled]", "warning")} ${paint(last, "muted")}`);
205
+ logInfo(` ${paint(`priority tier: ${account.priority}`, "accent")}; visible models: ${account.visibleModelCount}`);
206
+ }
207
+ };
132
208
  const runtimeCurrent = resolveRuntimeCurrentAccount(storage, {
133
209
  runtimeSnapshot,
134
210
  appBindStatus,
@@ -141,10 +217,23 @@ export async function runStatusCommand(deps) {
141
217
  const markers = buildAccountMarkers(account, i, activeIndex, runtimeCurrent, now, quotaCache, storage.accounts, deps.formatRateLimitEntry);
142
218
  return {
143
219
  index: i,
220
+ resetCreditsAvailable: resetSnapshot(account)?.availableCount ?? null,
221
+ resetCreditsCheckedAt: resetSnapshot(account)?.updatedAt ?? null,
144
222
  label: formatAccountLabel(account, i),
145
223
  enabled: account.enabled !== false,
146
224
  current: i === activeIndex,
225
+ priority: accountPolicies.accounts[getAccountPolicyKey(account, i)]?.priority ?? 1,
226
+ autoPrime: accountPolicies.accounts[getAccountPolicyKey(account, i)]?.autoPrime ?? false,
147
227
  markers,
228
+ selectionPreference: storage.pinnedAccountIndex === i ? "strict-pin" : null,
229
+ forecastRiskScore: forecastResults[i]?.riskScore ?? null,
230
+ forecastRiskLevel: forecastResults[i]?.riskLevel ?? null,
231
+ forecastQuotaUpdatedAt: forecastQuotas[i]?.updatedAt ?? null,
232
+ automaticOrder: automaticOrder.get(i) ?? null,
233
+ subscriptionReserve: usesSubscriptionReserve(quotaPreferences[i]),
234
+ quotaResetAt: quotaPreferences[i]?.resetAtMs ?? null,
235
+ quotaDrainPerHour: quotaPreferences[i]?.urgency ?? null,
236
+ lastInferenceRequestAt: inferenceTimes[inferenceAccountKey(account)] ?? null,
148
237
  lastUsed: typeof account.lastUsed === "number" && account.lastUsed > 0
149
238
  ? account.lastUsed
150
239
  : null,
@@ -153,8 +242,12 @@ export async function runStatusCommand(deps) {
153
242
  });
154
243
  logInfo(JSON.stringify({
155
244
  storagePath: path,
245
+ ...(apiConfigurationUnavailable ? { warnings: ["api_configuration_unavailable"] } : {}),
156
246
  storageHealth: storageHealth?.state ?? null,
157
247
  accountCount: storage.accounts.length,
248
+ apiAccounts,
249
+ totalAccountCount: storage.accounts.length + apiAccounts.length,
250
+ selectionMode: appBindStatus?.nativeOpenai ? "model-priority" : "legacy-pin",
158
251
  activeIndex,
159
252
  pinnedAccountIndex: typeof storage.pinnedAccountIndex === "number"
160
253
  ? storage.pinnedAccountIndex
@@ -162,7 +255,13 @@ export async function runStatusCommand(deps) {
162
255
  recommendedIndex: recommendation.recommendedIndex,
163
256
  recommendationReason: recommendation.reason,
164
257
  runtimeInUseIndex: runtimeCurrent ? runtimeCurrent.index : null,
258
+ modelInventory: modelInventory ?? null,
165
259
  accounts,
260
+ lastRequestedWorkspace: runtimeSnapshot?.lastRequestedWorkspaceId ? {
261
+ id: runtimeSnapshot.lastRequestedWorkspaceId,
262
+ accountIndex: runtimeSnapshot.lastAccountIndex ?? null,
263
+ requestedAt: runtimeSnapshot.lastAccountUpdatedAt ?? null,
264
+ } : null,
166
265
  }, null, 2));
167
266
  return 0;
168
267
  }
@@ -179,8 +278,18 @@ export async function runStatusCommand(deps) {
179
278
  logInfo(`Runtime: responses=${runtimeSnapshot.responsesRequests}, refresh=${runtimeSnapshot.authRefreshRequests}, probes=${runtimeSnapshot.diagnosticProbeRequests}, budgetExhaustions=${runtimeMetrics.requestAttemptBudgetExhaustions}`);
180
279
  const lastRuntimeAccount = formatRuntimeLastAccount(runtimeSnapshot);
181
280
  if (lastRuntimeAccount) {
182
- logInfo(`Last runtime account: ${lastRuntimeAccount}`);
281
+ logInfo(paint(`Last runtime account: ${lastRuntimeAccount}`, "accent"));
282
+ if (typeof runtimeSnapshot.lastAccountUpdatedAt === "number" && runtimeSnapshot.lastAccountUpdatedAt > 0)
283
+ logInfo(`Last runtime request: ${formatWaitTime(Math.max(0, now - runtimeSnapshot.lastAccountUpdatedAt))} ago`);
183
284
  }
285
+ const requestedId = runtimeSnapshot.lastRequestedWorkspaceId;
286
+ if (requestedId) {
287
+ const index = resolveRuntimeCurrentAccount(storage, { runtimeSnapshot }, { now })?.index;
288
+ const workspace = index === undefined ? undefined : storage.accounts[index]?.workspaces?.find(w => w.id === requestedId);
289
+ logInfo(`Last requested workspace: ${index === undefined ? "" : `account ${index + 1} / `}${workspace?.name?.trim() || "unlabelled"} (id:${requestedId.slice(-6)}; outgoing scope, billing plan not verified)`);
290
+ }
291
+ else
292
+ logInfo("Last requested workspace: not recorded");
184
293
  if (poolCooldown || serverCooldown) {
185
294
  logInfo(`Cooldowns: pool=${poolCooldown ?? "none"}, server-burst=${serverCooldown ?? "none"}`);
186
295
  }
@@ -189,8 +298,11 @@ export async function runStatusCommand(deps) {
189
298
  }
190
299
  }
191
300
  if (runtimeCurrent) {
192
- logInfo(`Runtime in use: account ${runtimeCurrent.index + 1} (${runtimeCurrent.source})`);
301
+ logInfo(paint(`Runtime in use: account ${runtimeCurrent.index + 1} (${runtimeCurrent.source})`, "accent"));
193
302
  }
303
+ if (appBindStatus?.nativeOpenai)
304
+ logInfo(paint("Automatic order estimates use the last check; requested model/workspace and live health can change the order.", "muted"));
305
+ logInfo(paint("Account/workspace labels below describe saved settings, not the last routed workspace.", "muted"));
194
306
  const pinnedAccountIndex = storage.pinnedAccountIndex;
195
307
  if (typeof pinnedAccountIndex === "number") {
196
308
  if (!Number.isInteger(pinnedAccountIndex) ||
@@ -199,8 +311,8 @@ export async function runStatusCommand(deps) {
199
311
  logInfo(`Pinned: invalid account index ${pinnedAccountIndex}; run codex-multi-auth unpin`);
200
312
  }
201
313
  else {
202
- logInfo(`Pinned: account ${pinnedAccountIndex + 1} (set by switch)`);
203
- if (runtimeCurrent && runtimeCurrent.index !== pinnedAccountIndex) {
314
+ logInfo(paint(`Pinned: account ${pinnedAccountIndex + 1} (strict; set by switch)`, "accent"));
315
+ if (!appBindStatus?.nativeOpenai && runtimeCurrent && runtimeCurrent.index !== pinnedAccountIndex) {
204
316
  logInfo(` warning: runtime currently using account ${runtimeCurrent.index + 1} but pin requests account ${pinnedAccountIndex + 1}; the proxy will pick up the pin on the next request.`);
205
317
  }
206
318
  }
@@ -212,24 +324,56 @@ export async function runStatusCommand(deps) {
212
324
  continue;
213
325
  const label = formatAccountLabel(account, i);
214
326
  const markers = buildAccountMarkers(account, i, activeIndex, runtimeCurrent, now, quotaCache, storage.accounts, deps.formatRateLimitEntry);
327
+ if (storage.pinnedAccountIndex === i)
328
+ markers.push("strict pin");
215
329
  const markerLabel = markers.length > 0 ? ` [${markers.join(", ")}]` : "";
216
- const lastUsed = typeof account.lastUsed === "number" && account.lastUsed > 0
217
- ? `used ${formatWaitTime(now - account.lastUsed)} ago`
218
- : "never used";
219
- logInfo(`${i + 1}. ${label}${markerLabel} ${lastUsed}`);
330
+ const lastInferenceAt = inferenceTimes[inferenceAccountKey(account)];
331
+ const activity = typeof account.lastUsed === "number" && account.lastUsed > 0
332
+ ? `account activity ${formatWaitTime(Math.max(0, now - account.lastUsed))} ago` : "no account activity recorded";
333
+ const lastUsed = typeof lastInferenceAt === "number" && lastInferenceAt > 0
334
+ ? `last inference request ${formatWaitTime(Math.max(0, now - lastInferenceAt))} ago`
335
+ : `inference not yet recorded; ${activity}`;
336
+ logInfo(`${paint(`${i + 1}. ${label}`, "heading")}${paint(markerLabel, markers.some(m => /disabled|cooldown|exhausted|limited|invalid/.test(m)) ? "warning" : "success")} ${paint(lastUsed, "muted")}`);
337
+ logInfo(` ${paint(`priority tier: ${accountPolicies.accounts[getAccountPolicyKey(account, i)]?.priority ?? 1}`, "accent")}`);
338
+ if (accountPolicies.accounts[getAccountPolicyKey(account, i)]?.autoPrime)
339
+ logInfo(" automatic first-use priming: on (router checks every 15 minutes)");
340
+ if (appBindStatus?.nativeOpenai) {
341
+ const preference = quotaPreferences[i];
342
+ const order = automaticOrder.get(i);
343
+ const reset = preference?.resetAtMs ? `; limiting window resets in ${formatWaitTime(Math.max(0, preference.resetAtMs - now))}` : "; reset ordering unknown; run check";
344
+ const reserve = usesSubscriptionReserve(preference) ? `; ${SUBSCRIPTION_RESERVE_PERCENT}% reserve (last resort)` : "";
345
+ const pinnedElsewhere = typeof storage.pinnedAccountIndex === "number" && storage.pinnedAccountIndex !== i;
346
+ logInfo(paint(` automatic order: ${order ? `#${order}` : pinnedElsewhere ? `none (account ${(storage.pinnedAccountIndex ?? 0) + 1} is pinned)` : "unavailable"}${reset}${reserve}`, reserve ? "warning" : "accent"));
347
+ }
348
+ const quota = forecastQuotas[i];
349
+ if (quota) {
350
+ const windows = ["primary", "secondary"].flatMap(key => {
351
+ const used = quota[key].usedPercent;
352
+ return typeof used === "number" && Number.isFinite(used) ? [paint(`${key} ${Math.max(0, Math.min(100, Math.round(100 - used)))}% left`, used >= 95 ? "danger" : used >= 80 ? "warning" : "success")] : [];
353
+ });
354
+ logInfo(` quota: ${windows.join("; ")} (${paint(`cached quota ${formatWaitTime(Math.max(0, now - quota.updatedAt))} ago`, "muted")})`);
355
+ }
356
+ else
357
+ logInfo(paint(" quota unknown; run check (risk uses other known signals only)", "warning"));
358
+ const forecast = forecastResults[i];
359
+ const resets = resetSnapshot(account);
360
+ logInfo(` subscription resets: ${resets?.availableCount ?? "unknown"}${resets ? ` (cached ${formatWaitTime(Math.max(0, now - resets.updatedAt))} ago)` : "; run check"}`);
361
+ if (forecast)
362
+ logInfo(` ${paint(`forecast risk: ${forecast.riskScore}/100 (${forecast.riskLevel}; lower is better)`, forecast.riskLevel === "high" ? "danger" : forecast.riskLevel === "medium" ? "warning" : "success")}`);
220
363
  const primaryReason = forecastResults[i]?.reasons[0];
221
364
  if (primaryReason) {
222
- logInfo(` reason: ${primaryReason}`);
365
+ logInfo(paint(` reason: ${primaryReason}`, "warning"));
223
366
  }
224
367
  // Surface every workspace a same-email account can rotate between, so
225
368
  // personal Plus vs business/team stay visible at once (issue #491).
226
369
  if ((account.workspaces?.length ?? 0) > 1) {
227
- logInfo(" workspaces:");
228
- for (const workspaceLine of formatWorkspaceLines(account, " ")) {
229
- logInfo(workspaceLine);
370
+ logInfo(paint(" workspaces (saved selection; not live routing):", "muted"));
371
+ for (const workspaceLine of formatWorkspaceLines(account, " ", "saved selection")) {
372
+ logInfo(paint(workspaceLine, workspaceLine.includes("(saved selection)") ? "accent" : "muted"));
230
373
  }
231
374
  }
232
375
  }
376
+ printApiAccounts();
233
377
  return 0;
234
378
  }
235
379
  export function runFeaturesCommand(deps) {
@@ -44,7 +44,7 @@ function printUninstallUsage() {
44
44
  "Options:",
45
45
  " --dry-run Show what would be removed without making changes",
46
46
  " --json Print machine-readable JSON output",
47
- " --clear-accounts Also remove stored account credentials (irreversible)",
47
+ " --clear-accounts Also remove stored account credentials and API keys (irreversible)",
48
48
  "",
49
49
  "Behavior:",
50
50
  " Reverses all first-run setup changes: unbinds Codex app, removes OS launchers,",
@@ -1 +1 @@
1
- {"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,EAGvB,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,EAC7D,QAAQ,EAAE,wBAAwB,EAClC,GAAG,SAAa,GACd,MAAM,CAIR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,GACpB,kBAAkB,CAgBpB;AA8BD;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAgCD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,EACtB,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR"}
1
+ {"version":3,"file":"quota-formatters.d.ts","sourceRoot":"","sources":["../../../../lib/codex-manager/formatters/quota-formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACN,KAAK,kBAAkB,EACvB,uBAAuB,EAGvB,MAAM,sBAAsB,CAAC;AAY9B,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmCzD;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC,EAC7D,QAAQ,EAAE,wBAAwB,EAClC,GAAG,SAAa,GACd,MAAM,CAKR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,GACpB,kBAAkB,CAgBpB;AA8BD;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAgCD,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR;AAED,wBAAgB,yBAAyB,CACxC,KAAK,EAAE,eAAe,EACtB,GAAG,SAAa,EAChB,OAAO,GAAE,yBAA8B,GACrC,MAAM,CA6CR"}
@@ -41,10 +41,11 @@ export function styleQuotaSummary(summary) {
41
41
  * absolute reset clock for each quota window.
42
42
  */
43
43
  export function formatQuotaSnapshotForDashboard(snapshot, settings, now = Date.now()) {
44
+ const status = snapshot.primingFailure ? `quota read OK; first-use probe unconfirmed (${snapshot.primingFailure})` : snapshot.primingCompleted ? "live session OK; first-use probe completed" : "live session OK";
44
45
  if (!settings.showQuotaDetails)
45
- return "live session OK";
46
+ return status;
46
47
  const summary = formatCompactQuotaSnapshot(snapshot, now, { showReset: true });
47
- return summary ? `live session OK (${summary})` : "live session OK";
48
+ return summary ? `${status} (${summary})` : status;
48
49
  }
49
50
  export function quotaCacheEntryToSnapshot(entry) {
50
51
  return {
@@ -6,7 +6,10 @@ import { type DashboardDisplaySettings } from "../dashboard-settings.js";
6
6
  */
7
7
  export interface HealthCheckOptions {
8
8
  forceRefresh?: boolean;
9
+ discoverModels?: boolean;
9
10
  liveProbe?: boolean;
11
+ /** Explicit `check --prime` only: may start an unused subscription's quota windows. */
12
+ primeUnusedSubscription?: boolean;
10
13
  model?: string;
11
14
  display?: DashboardDisplaySettings;
12
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"AAQA,OAAO,EACN,KAAK,wBAAwB,EAE7B,MAAM,0BAA0B,CAAC;AA2ClC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,wBAAsB,cAAc,CACnC,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA4Uf"}
1
+ {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../../lib/codex-manager/health-check.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,KAAK,wBAAwB,EAE7B,MAAM,0BAA0B,CAAC;AA2ClC;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uFAAuF;IACvF,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,wBAAsB,cAAc,CACnC,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CA6Wf"}