codex-multi-auth 2.17.2 → 2.17.3

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 (394) hide show
  1. package/.codex-plugin/plugin.json +1 -1
  2. package/README.md +83 -428
  3. package/dist/index.d.ts +0 -1
  4. package/dist/lib/account-policy.d.ts +18 -2
  5. package/dist/lib/account-policy.js +97 -40
  6. package/dist/lib/accounts/rate-limits.d.ts +0 -1
  7. package/dist/lib/accounts.d.ts +0 -1
  8. package/dist/lib/accounts.js +4 -5
  9. package/dist/lib/api-route-store.d.ts +0 -1
  10. package/dist/lib/audit.d.ts +0 -1
  11. package/dist/lib/audit.js +43 -12
  12. package/dist/lib/auth/account-access.d.ts +0 -1
  13. package/dist/lib/auth/account-access.js +5 -1
  14. package/dist/lib/auth/auth.d.ts +4 -3
  15. package/dist/lib/auth/auth.js +220 -28
  16. package/dist/lib/auth/browser.d.ts +0 -1
  17. package/dist/lib/auth/callback-guidance.d.ts +0 -1
  18. package/dist/lib/auth/device-auth.d.ts +0 -1
  19. package/dist/lib/auth/index.d.ts +0 -1
  20. package/dist/lib/auth/org-override.d.ts +0 -1
  21. package/dist/lib/auth/server.d.ts +1 -2
  22. package/dist/lib/auth/server.js +100 -53
  23. package/dist/lib/auth/token-utils.d.ts +0 -1
  24. package/dist/lib/auth-rate-limit.d.ts +0 -1
  25. package/dist/lib/budget-guard.d.ts +16 -2
  26. package/dist/lib/budget-guard.js +123 -43
  27. package/dist/lib/capability-policy.d.ts +0 -1
  28. package/dist/lib/circuit-breaker.d.ts +20 -1
  29. package/dist/lib/circuit-breaker.js +24 -5
  30. package/dist/lib/cli.d.ts +0 -1
  31. package/dist/lib/codex-cli/index.d.ts +0 -1
  32. package/dist/lib/codex-cli/observability.d.ts +0 -1
  33. package/dist/lib/codex-cli/state.d.ts +0 -1
  34. package/dist/lib/codex-cli/sync.d.ts +0 -1
  35. package/dist/lib/codex-cli/writer.d.ts +0 -1
  36. package/dist/lib/codex-manager/account-credentials.d.ts +0 -1
  37. package/dist/lib/codex-manager/account-manager-commands.d.ts +0 -1
  38. package/dist/lib/codex-manager/account-pool-write.d.ts +0 -1
  39. package/dist/lib/codex-manager/active-account-sync.d.ts +6 -0
  40. package/dist/lib/codex-manager/active-account-sync.js +336 -0
  41. package/dist/lib/codex-manager/api-login-menu.d.ts +0 -1
  42. package/dist/lib/codex-manager/backend-category-entry.d.ts +0 -1
  43. package/dist/lib/codex-manager/backend-category-helpers.d.ts +0 -1
  44. package/dist/lib/codex-manager/backend-category-prompt.d.ts +0 -1
  45. package/dist/lib/codex-manager/backend-settings-controller.d.ts +0 -1
  46. package/dist/lib/codex-manager/backend-settings-entry.d.ts +0 -1
  47. package/dist/lib/codex-manager/backend-settings-helpers.d.ts +0 -1
  48. package/dist/lib/codex-manager/backend-settings-prompt.d.ts +0 -1
  49. package/dist/lib/codex-manager/backend-settings-schema.d.ts +0 -1
  50. package/dist/lib/codex-manager/behavior-settings-panel.d.ts +0 -1
  51. package/dist/lib/codex-manager/commands/account.d.ts +8 -3
  52. package/dist/lib/codex-manager/commands/account.js +46 -34
  53. package/dist/lib/codex-manager/commands/best.d.ts +0 -1
  54. package/dist/lib/codex-manager/commands/bridge.d.ts +0 -1
  55. package/dist/lib/codex-manager/commands/budget.d.ts +8 -3
  56. package/dist/lib/codex-manager/commands/budget.js +6 -4
  57. package/dist/lib/codex-manager/commands/check.d.ts +0 -1
  58. package/dist/lib/codex-manager/commands/config-explain.d.ts +0 -1
  59. package/dist/lib/codex-manager/commands/debug-bundle.d.ts +0 -1
  60. package/dist/lib/codex-manager/commands/forecast.d.ts +0 -1
  61. package/dist/lib/codex-manager/commands/history.d.ts +0 -1
  62. package/dist/lib/codex-manager/commands/init-config.d.ts +0 -1
  63. package/dist/lib/codex-manager/commands/integrations.d.ts +0 -1
  64. package/dist/lib/codex-manager/commands/limits.d.ts +0 -1
  65. package/dist/lib/codex-manager/commands/models.d.ts +0 -1
  66. package/dist/lib/codex-manager/commands/monitor.d.ts +0 -1
  67. package/dist/lib/codex-manager/commands/report.d.ts +0 -1
  68. package/dist/lib/codex-manager/commands/resets.d.ts +0 -1
  69. package/dist/lib/codex-manager/commands/resets.js +9 -1
  70. package/dist/lib/codex-manager/commands/rotation.d.ts +0 -1
  71. package/dist/lib/codex-manager/commands/status.d.ts +0 -1
  72. package/dist/lib/codex-manager/commands/switch.d.ts +0 -1
  73. package/dist/lib/codex-manager/commands/uninstall.d.ts +0 -1
  74. package/dist/lib/codex-manager/commands/unpin.d.ts +0 -1
  75. package/dist/lib/codex-manager/commands/usage.d.ts +0 -1
  76. package/dist/lib/codex-manager/commands/verify.d.ts +0 -1
  77. package/dist/lib/codex-manager/commands/why-selected.d.ts +0 -1
  78. package/dist/lib/codex-manager/commands/workspace.d.ts +0 -1
  79. package/dist/lib/codex-manager/dashboard-display-panel.d.ts +0 -1
  80. package/dist/lib/codex-manager/dashboard-formatters.d.ts +0 -1
  81. package/dist/lib/codex-manager/dashboard-settings-controller.d.ts +0 -1
  82. package/dist/lib/codex-manager/dashboard-settings-data.d.ts +0 -1
  83. package/dist/lib/codex-manager/dashboard-settings-entry.d.ts +0 -1
  84. package/dist/lib/codex-manager/experimental-settings-entry.d.ts +0 -1
  85. package/dist/lib/codex-manager/experimental-settings-prompt.d.ts +0 -1
  86. package/dist/lib/codex-manager/experimental-settings-schema.d.ts +0 -1
  87. package/dist/lib/codex-manager/experimental-sync-target-entry.d.ts +0 -1
  88. package/dist/lib/codex-manager/experimental-sync-target.d.ts +0 -1
  89. package/dist/lib/codex-manager/forecast-report-shared.d.ts +0 -1
  90. package/dist/lib/codex-manager/formatters/account-formatters.d.ts +0 -1
  91. package/dist/lib/codex-manager/formatters/index.d.ts +0 -1
  92. package/dist/lib/codex-manager/formatters/model-formatters.d.ts +0 -1
  93. package/dist/lib/codex-manager/formatters/quota-formatters.d.ts +0 -1
  94. package/dist/lib/codex-manager/formatters/text-style.d.ts +0 -1
  95. package/dist/lib/codex-manager/health-check.d.ts +0 -1
  96. package/dist/lib/codex-manager/help.d.ts +0 -1
  97. package/dist/lib/codex-manager/login-action-panel.d.ts +0 -1
  98. package/dist/lib/codex-manager/login-flow.d.ts +0 -1
  99. package/dist/lib/codex-manager/login-menu-actions.d.ts +0 -1
  100. package/dist/lib/codex-manager/login-menu-data.d.ts +0 -1
  101. package/dist/lib/codex-manager/login-oauth.d.ts +0 -1
  102. package/dist/lib/codex-manager/login-workspace-choice.d.ts +0 -1
  103. package/dist/lib/codex-manager/manual-callback.d.ts +0 -1
  104. package/dist/lib/codex-manager/persist-selected-account.d.ts +0 -1
  105. package/dist/lib/codex-manager/quota-cache-helpers.d.ts +0 -1
  106. package/dist/lib/codex-manager/rate-limit-markers.d.ts +0 -1
  107. package/dist/lib/codex-manager/repair-commands.d.ts +0 -1
  108. package/dist/lib/codex-manager/settings-hub/backend.d.ts +0 -1
  109. package/dist/lib/codex-manager/settings-hub/dashboard.d.ts +0 -1
  110. package/dist/lib/codex-manager/settings-hub/experimental.d.ts +0 -1
  111. package/dist/lib/codex-manager/settings-hub/index.d.ts +0 -1
  112. package/dist/lib/codex-manager/settings-hub/shared.d.ts +0 -1
  113. package/dist/lib/codex-manager/settings-hub-entry.d.ts +0 -1
  114. package/dist/lib/codex-manager/settings-hub-menu.d.ts +0 -1
  115. package/dist/lib/codex-manager/settings-hub-prompt.d.ts +0 -1
  116. package/dist/lib/codex-manager/settings-hub.d.ts +0 -1
  117. package/dist/lib/codex-manager/settings-panels.d.ts +0 -1
  118. package/dist/lib/codex-manager/settings-persist-utils.d.ts +0 -1
  119. package/dist/lib/codex-manager/settings-preview.d.ts +0 -1
  120. package/dist/lib/codex-manager/settings-write-queue.d.ts +0 -1
  121. package/dist/lib/codex-manager/statusline-settings-panel.d.ts +0 -1
  122. package/dist/lib/codex-manager/theme-settings-panel.d.ts +0 -1
  123. package/dist/lib/codex-manager/unified-settings-controller.d.ts +0 -1
  124. package/dist/lib/codex-manager/unified-settings-entry.d.ts +0 -1
  125. package/dist/lib/codex-manager.d.ts +1 -2
  126. package/dist/lib/codex-manager.js +5 -95
  127. package/dist/lib/concurrency.d.ts +0 -1
  128. package/dist/lib/config-schema.d.ts +0 -1
  129. package/dist/lib/config.d.ts +0 -1
  130. package/dist/lib/config.js +46 -241
  131. package/dist/lib/constants.d.ts +0 -1
  132. package/dist/lib/context-budget/model-context-windows.d.ts +0 -1
  133. package/dist/lib/context-budget-guard.d.ts +0 -1
  134. package/dist/lib/context-budget-response.d.ts +0 -1
  135. package/dist/lib/context-overflow.d.ts +0 -1
  136. package/dist/lib/dashboard-settings.d.ts +0 -1
  137. package/dist/lib/entitlement-cache.d.ts +0 -1
  138. package/dist/lib/env-parsing.d.ts +13 -1
  139. package/dist/lib/env-parsing.js +21 -0
  140. package/dist/lib/errors.d.ts +0 -1
  141. package/dist/lib/forecast.d.ts +0 -1
  142. package/dist/lib/fs-retry.d.ts +0 -1
  143. package/dist/lib/health.d.ts +0 -1
  144. package/dist/lib/index.d.ts +0 -1
  145. package/dist/lib/integration-generators.d.ts +0 -1
  146. package/dist/lib/live-account-sync.d.ts +0 -1
  147. package/dist/lib/local-bridge.d.ts +0 -1
  148. package/dist/lib/local-bridge.js +4 -1
  149. package/dist/lib/local-client-tokens.d.ts +0 -1
  150. package/dist/lib/local-client-tokens.js +125 -30
  151. package/dist/lib/logger.d.ts +0 -1
  152. package/dist/lib/logger.js +11 -1
  153. package/dist/lib/model-capability-matrix.d.ts +0 -1
  154. package/dist/lib/model-route-policy.d.ts +1 -2
  155. package/dist/lib/named-backup-export.d.ts +0 -1
  156. package/dist/lib/oc-chatgpt-import-adapter.d.ts +0 -1
  157. package/dist/lib/oc-chatgpt-orchestrator.d.ts +0 -1
  158. package/dist/lib/oc-chatgpt-target-detection.d.ts +0 -1
  159. package/dist/lib/parallel-probe.d.ts +0 -1
  160. package/dist/lib/policy/runtime-policy-cache.d.ts +80 -0
  161. package/dist/lib/policy/runtime-policy-cache.js +310 -0
  162. package/dist/lib/policy/runtime-policy.d.ts +1 -2
  163. package/dist/lib/policy/runtime-policy.js +46 -19
  164. package/dist/lib/preemptive-quota-scheduler.d.ts +0 -1
  165. package/dist/lib/proactive-refresh.d.ts +0 -1
  166. package/dist/lib/prompts/codex-host-bridge.d.ts +0 -1
  167. package/dist/lib/prompts/codex.d.ts +0 -1
  168. package/dist/lib/prompts/fetch-utils.d.ts +0 -1
  169. package/dist/lib/prompts/host-codex-prompt.d.ts +0 -1
  170. package/dist/lib/quota-cache.d.ts +0 -1
  171. package/dist/lib/quota-cache.js +60 -36
  172. package/dist/lib/quota-probe.d.ts +0 -1
  173. package/dist/lib/quota-probe.js +5 -2
  174. package/dist/lib/quota-readiness.d.ts +0 -1
  175. package/dist/lib/recovery/constants.d.ts +0 -1
  176. package/dist/lib/recovery/storage.d.ts +0 -1
  177. package/dist/lib/recovery/types.d.ts +0 -1
  178. package/dist/lib/recovery.d.ts +0 -1
  179. package/dist/lib/redaction.d.ts +0 -1
  180. package/dist/lib/refresh-guardian.d.ts +0 -1
  181. package/dist/lib/refresh-lease.d.ts +0 -1
  182. package/dist/lib/refresh-queue.d.ts +0 -1
  183. package/dist/lib/request/client-cancellation.d.ts +0 -1
  184. package/dist/lib/request/error-classification.d.ts +0 -1
  185. package/dist/lib/request/failover-config.d.ts +0 -1
  186. package/dist/lib/request/failure-policy.d.ts +0 -1
  187. package/dist/lib/request/fetch-helpers.d.ts +0 -1
  188. package/dist/lib/request/headers.d.ts +0 -1
  189. package/dist/lib/request/helpers/input-utils.d.ts +0 -1
  190. package/dist/lib/request/helpers/input-utils.js +88 -34
  191. package/dist/lib/request/helpers/model-map.d.ts +0 -1
  192. package/dist/lib/request/helpers/tool-utils.d.ts +0 -1
  193. package/dist/lib/request/helpers/tool-utils.js +421 -4
  194. package/dist/lib/request/index.d.ts +0 -1
  195. package/dist/lib/request/rate-limit-backoff.d.ts +0 -1
  196. package/dist/lib/request/rate-limit-decision.d.ts +0 -1
  197. package/dist/lib/request/request-attempt-budget.d.ts +0 -1
  198. package/dist/lib/request/request-init.d.ts +0 -1
  199. package/dist/lib/request/request-resilience.d.ts +0 -1
  200. package/dist/lib/request/request-transformer.d.ts +0 -1
  201. package/dist/lib/request/request-transformer.js +50 -25
  202. package/dist/lib/request/response-compaction.d.ts +0 -1
  203. package/dist/lib/request/response-handler.d.ts +0 -1
  204. package/dist/lib/request/response-metadata.d.ts +0 -1
  205. package/dist/lib/request/response-outcome.d.ts +0 -1
  206. package/dist/lib/request/stream-failover-runtime.d.ts +0 -1
  207. package/dist/lib/request/stream-failover.d.ts +0 -1
  208. package/dist/lib/request/stream-failover.js +28 -4
  209. package/dist/lib/request/token-refresh.d.ts +0 -1
  210. package/dist/lib/request/url-rewriting.d.ts +0 -1
  211. package/dist/lib/request/wait-utils.d.ts +0 -1
  212. package/dist/lib/rotation.d.ts +0 -1
  213. package/dist/lib/routing-mutex.d.ts +0 -1
  214. package/dist/lib/routing-profiles.d.ts +16 -2
  215. package/dist/lib/routing-profiles.js +119 -44
  216. package/dist/lib/runtime/account-check-helpers.d.ts +0 -1
  217. package/dist/lib/runtime/account-check-types.d.ts +0 -1
  218. package/dist/lib/runtime/account-check.d.ts +0 -1
  219. package/dist/lib/runtime/account-manager-cache-entry.d.ts +0 -1
  220. package/dist/lib/runtime/account-manager-cache.d.ts +0 -1
  221. package/dist/lib/runtime/account-model-catalog.d.ts +1 -2
  222. package/dist/lib/runtime/account-pool.d.ts +0 -1
  223. package/dist/lib/runtime/account-reset-credits.d.ts +0 -1
  224. package/dist/lib/runtime/account-reset-credits.js +8 -2
  225. package/dist/lib/runtime/account-scope.d.ts +0 -1
  226. package/dist/lib/runtime/account-select-event.d.ts +0 -1
  227. package/dist/lib/runtime/account-selection.d.ts +0 -1
  228. package/dist/lib/runtime/account-state.d.ts +0 -1
  229. package/dist/lib/runtime/account-status.d.ts +0 -1
  230. package/dist/lib/runtime/account-storage-scope-entry.d.ts +0 -1
  231. package/dist/lib/runtime/api-model-capabilities.d.ts +0 -1
  232. package/dist/lib/runtime/api-model-runtime.d.ts +0 -1
  233. package/dist/lib/runtime/app-bind.d.ts +0 -1
  234. package/dist/lib/runtime/app-helper-selection.d.ts +0 -1
  235. package/dist/lib/runtime/auth-facade.d.ts +0 -1
  236. package/dist/lib/runtime/automatic-account-checks.d.ts +0 -1
  237. package/dist/lib/runtime/automatic-subscription-checks.d.ts +0 -1
  238. package/dist/lib/runtime/browser-oauth-flow.d.ts +0 -1
  239. package/dist/lib/runtime/capability-boost.d.ts +0 -1
  240. package/dist/lib/runtime/catalog-capabilities.d.ts +0 -1
  241. package/dist/lib/runtime/config-toml.d.ts +0 -1
  242. package/dist/lib/runtime/context-budget-settings.d.ts +0 -1
  243. package/dist/lib/runtime/event-handler.d.ts +0 -1
  244. package/dist/lib/runtime/first-run.d.ts +0 -1
  245. package/dist/lib/runtime/flagged-verify-types.d.ts +0 -1
  246. package/dist/lib/runtime/hydrate-emails.d.ts +0 -1
  247. package/dist/lib/runtime/inference-activity.d.ts +0 -1
  248. package/dist/lib/runtime/live-sync-entry.d.ts +0 -1
  249. package/dist/lib/runtime/live-sync.d.ts +0 -1
  250. package/dist/lib/runtime/loader-setup.d.ts +0 -1
  251. package/dist/lib/runtime/login-menu-accounts.d.ts +0 -1
  252. package/dist/lib/runtime/manual-oauth-flow.d.ts +0 -1
  253. package/dist/lib/runtime/model-discovery-status.d.ts +2 -3
  254. package/dist/lib/runtime/native-account-storage.d.ts +0 -1
  255. package/dist/lib/runtime/native-account-sync.d.ts +0 -1
  256. package/dist/lib/runtime/native-binding-lock.d.ts +0 -1
  257. package/dist/lib/runtime/native-client-auth.d.ts +0 -1
  258. package/dist/lib/runtime/native-provider-config.d.ts +0 -1
  259. package/dist/lib/runtime/native-rate-limits.d.ts +2 -1
  260. package/dist/lib/runtime/native-rate-limits.js +23 -6
  261. package/dist/lib/runtime/preemptive-quota.d.ts +0 -1
  262. package/dist/lib/runtime/quota-headers.d.ts +0 -1
  263. package/dist/lib/runtime/quota-probe.d.ts +0 -1
  264. package/dist/lib/runtime/quota-settings.d.ts +0 -1
  265. package/dist/lib/runtime/refresh-guardian-entry.d.ts +0 -1
  266. package/dist/lib/runtime/refresh-guardian.d.ts +0 -1
  267. package/dist/lib/runtime/request-init.d.ts +0 -1
  268. package/dist/lib/runtime/reset-credit-routing.d.ts +0 -1
  269. package/dist/lib/runtime/reset-credits.d.ts +0 -1
  270. package/dist/lib/runtime/response-output-history.d.ts +0 -1
  271. package/dist/lib/runtime/responses-websocket.d.ts +0 -1
  272. package/dist/lib/runtime/resume-picker.d.ts +0 -1
  273. package/dist/lib/runtime/rotation-account-selection.d.ts +0 -1
  274. package/dist/lib/runtime/rotation-proxy-state.d.ts +0 -1
  275. package/dist/lib/runtime/rotation-server-types.d.ts +0 -1
  276. package/dist/lib/runtime/rotation-storage-meta.d.ts +0 -1
  277. package/dist/lib/runtime/rotation-token-refresh.d.ts +0 -1
  278. package/dist/lib/runtime/runtime-capability-failures.d.ts +0 -1
  279. package/dist/lib/runtime/runtime-current-account.d.ts +0 -1
  280. package/dist/lib/runtime/runtime-observability.d.ts +0 -1
  281. package/dist/lib/runtime/runtime-services.d.ts +0 -1
  282. package/dist/lib/runtime/session-affinity-entry.d.ts +0 -1
  283. package/dist/lib/runtime/session-recovery.d.ts +0 -1
  284. package/dist/lib/runtime/status-marker.d.ts +0 -1
  285. package/dist/lib/runtime/storage-scope.d.ts +0 -1
  286. package/dist/lib/runtime/subscription-first-use.d.ts +0 -1
  287. package/dist/lib/runtime/subscription-quota-event.d.ts +0 -1
  288. package/dist/lib/runtime/subscription-quota-order.d.ts +0 -1
  289. package/dist/lib/runtime/toast.d.ts +0 -1
  290. package/dist/lib/runtime/ui-runtime-entry.d.ts +0 -1
  291. package/dist/lib/runtime/ui-runtime.d.ts +0 -1
  292. package/dist/lib/runtime/verify-flagged.d.ts +0 -1
  293. package/dist/lib/runtime/workspace-model-scopes.d.ts +0 -1
  294. package/dist/lib/runtime-constants.d.ts +0 -1
  295. package/dist/lib/runtime-paths.d.ts +0 -1
  296. package/dist/lib/runtime-rotation-proxy.d.ts +1 -1
  297. package/dist/lib/runtime-rotation-proxy.js +133 -0
  298. package/dist/lib/schemas.d.ts +35 -13
  299. package/dist/lib/schemas.js +19 -2
  300. package/dist/lib/session-affinity.d.ts +0 -1
  301. package/dist/lib/shutdown.d.ts +0 -1
  302. package/dist/lib/storage/account-clear-entry.d.ts +0 -1
  303. package/dist/lib/storage/account-clear.d.ts +0 -1
  304. package/dist/lib/storage/account-match-utils.d.ts +0 -1
  305. package/dist/lib/storage/account-persistence.d.ts +0 -1
  306. package/dist/lib/storage/account-port.d.ts +0 -1
  307. package/dist/lib/storage/account-save-entry.d.ts +0 -1
  308. package/dist/lib/storage/account-save.d.ts +9 -2
  309. package/dist/lib/storage/account-save.js +4 -1
  310. package/dist/lib/storage/account-snapshot.d.ts +0 -1
  311. package/dist/lib/storage/backup-metadata-builder.d.ts +0 -1
  312. package/dist/lib/storage/backup-metadata.d.ts +0 -1
  313. package/dist/lib/storage/backup-paths.d.ts +0 -1
  314. package/dist/lib/storage/backup-restore.d.ts +0 -1
  315. package/dist/lib/storage/cache-artifacts.d.ts +0 -1
  316. package/dist/lib/storage/credential-sidecars.d.ts +0 -1
  317. package/dist/lib/storage/error-hints.d.ts +0 -1
  318. package/dist/lib/storage/file-lock.d.ts +0 -1
  319. package/dist/lib/storage/file-lock.js +33 -1
  320. package/dist/lib/storage/file-paths.d.ts +0 -1
  321. package/dist/lib/storage/fixture-guards.d.ts +0 -1
  322. package/dist/lib/storage/flagged-entry.d.ts +0 -1
  323. package/dist/lib/storage/flagged-load-entry.d.ts +0 -1
  324. package/dist/lib/storage/flagged-save-entry.d.ts +0 -1
  325. package/dist/lib/storage/flagged-storage-file.d.ts +0 -1
  326. package/dist/lib/storage/flagged-storage-io.d.ts +0 -1
  327. package/dist/lib/storage/flagged-storage.d.ts +0 -1
  328. package/dist/lib/storage/gitignore.d.ts +0 -1
  329. package/dist/lib/storage/hash.d.ts +0 -1
  330. package/dist/lib/storage/health.d.ts +0 -1
  331. package/dist/lib/storage/identity.d.ts +0 -1
  332. package/dist/lib/storage/import-export.d.ts +0 -1
  333. package/dist/lib/storage/json-store-lock.d.ts +105 -0
  334. package/dist/lib/storage/json-store-lock.js +259 -0
  335. package/dist/lib/storage/metadata-section.d.ts +0 -1
  336. package/dist/lib/storage/migrations.d.ts +0 -1
  337. package/dist/lib/storage/migrations.js +31 -18
  338. package/dist/lib/storage/named-backup-entry.d.ts +0 -1
  339. package/dist/lib/storage/named-backups-entry.d.ts +0 -1
  340. package/dist/lib/storage/named-backups.d.ts +0 -1
  341. package/dist/lib/storage/path-state.d.ts +0 -1
  342. package/dist/lib/storage/paths.d.ts +0 -1
  343. package/dist/lib/storage/pending-auth.d.ts +9 -3
  344. package/dist/lib/storage/pending-auth.js +30 -8
  345. package/dist/lib/storage/project-migration.d.ts +0 -1
  346. package/dist/lib/storage/public-types.d.ts +0 -1
  347. package/dist/lib/storage/record-identity.d.ts +0 -1
  348. package/dist/lib/storage/record-utils.d.ts +0 -1
  349. package/dist/lib/storage/restore-assessment.d.ts +0 -1
  350. package/dist/lib/storage/restore-backup-entry.d.ts +0 -1
  351. package/dist/lib/storage/restore-metadata.d.ts +0 -1
  352. package/dist/lib/storage/save-retry.d.ts +0 -1
  353. package/dist/lib/storage/snapshot-inspectors.d.ts +0 -1
  354. package/dist/lib/storage/snapshot-merge.d.ts +0 -1
  355. package/dist/lib/storage/storage-parser.d.ts +2 -1
  356. package/dist/lib/storage/storage-parser.js +10 -2
  357. package/dist/lib/storage/transactions.d.ts +0 -1
  358. package/dist/lib/storage.d.ts +15 -2
  359. package/dist/lib/storage.js +612 -25
  360. package/dist/lib/synthetic-response.d.ts +0 -1
  361. package/dist/lib/table-formatter.d.ts +0 -1
  362. package/dist/lib/temp-path.d.ts +0 -1
  363. package/dist/lib/tools/hashline-tools.d.ts +0 -1
  364. package/dist/lib/types.d.ts +0 -1
  365. package/dist/lib/ui/ansi.d.ts +0 -1
  366. package/dist/lib/ui/auth-menu-builder.d.ts +0 -1
  367. package/dist/lib/ui/auth-menu.d.ts +0 -1
  368. package/dist/lib/ui/check-progress.d.ts +0 -1
  369. package/dist/lib/ui/confirm.d.ts +0 -1
  370. package/dist/lib/ui/display-width.d.ts +0 -1
  371. package/dist/lib/ui/format.d.ts +0 -1
  372. package/dist/lib/ui/index.d.ts +0 -1
  373. package/dist/lib/ui/runtime.d.ts +0 -1
  374. package/dist/lib/ui/select.d.ts +0 -1
  375. package/dist/lib/ui/theme.d.ts +0 -1
  376. package/dist/lib/ui/ui-copy.d.ts +0 -1
  377. package/dist/lib/unified-settings.d.ts +13 -11
  378. package/dist/lib/unified-settings.js +22 -14
  379. package/dist/lib/update-notice.d.ts +0 -1
  380. package/dist/lib/usage/index.d.ts +0 -1
  381. package/dist/lib/usage/ledger.d.ts +0 -1
  382. package/dist/lib/usage/pricing.d.ts +0 -1
  383. package/dist/lib/usage/redaction.d.ts +0 -1
  384. package/dist/lib/usage/stream-usage-deferral.d.ts +0 -1
  385. package/dist/lib/usage/types.d.ts +0 -1
  386. package/dist/lib/usage/usage-extraction.d.ts +0 -1
  387. package/dist/lib/utils.d.ts +21 -1
  388. package/dist/lib/utils.js +31 -0
  389. package/dist/lib/wsl.d.ts +0 -1
  390. package/package.json +11 -5
  391. package/scripts/codex-bin-resolver.js +20 -1
  392. package/scripts/codex-multi-auth.js +7 -1
  393. package/scripts/codex.js +288 -7
  394. package/skills/codex-auth-setup/SKILL.md +73 -0
@@ -0,0 +1,336 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { extractAccountEmail, extractAccountId, sanitizeEmail, } from "../accounts.js";
4
+ import { codexCliAccountIdFor } from "../auth/token-utils.js";
5
+ import { getCodexCliAccountsPath, getCodexCliAuthPath, getCodexCliConfigPath, } from "../codex-cli/state.js";
6
+ import { setCodexCliActiveSelection } from "../codex-cli/writer.js";
7
+ import { queuedRefresh } from "../refresh-queue.js";
8
+ import { resolveActiveIndex } from "../runtime/account-status.js";
9
+ import { findMatchingAccountIndex, getStoragePath, loadAccounts, setStoragePath, withAccountStorageTransaction, } from "../storage.js";
10
+ import { applyTokenAccountIdentity, hasUsableAccessToken, } from "./account-credentials.js";
11
+ // Keyed by absolute storage path, mirroring lib/runtime/rotation-storage-meta.ts:
12
+ // the same process can host multiple wrappers/test workers pointed at different
13
+ // storage files, and none may corrupt another's snapshot.
14
+ const ACTIVE_SYNC_FINGERPRINTS = new Map();
15
+ // A cached mtime+size match is only trusted once the file has been quiescent
16
+ // long enough that no *subsequent* write could share the same coarse mtime
17
+ // tick (see rotation-storage-meta.ts / issue #474 — atomic-rename writers can
18
+ // land two rapid bumps on an identical mtimeMs). Inside the window we fall
19
+ // back to the read + sha1 comparison, which stays the source of truth.
20
+ const ACTIVE_SYNC_MTIME_SETTLE_MS = 2_000;
21
+ function hashStorageBytes(bytes) {
22
+ return createHash("sha1").update(bytes).digest("hex");
23
+ }
24
+ function statFingerprint(storagePath) {
25
+ if (typeof storagePath !== "string" || storagePath.length === 0) {
26
+ return null;
27
+ }
28
+ try {
29
+ const stats = statSync(storagePath);
30
+ return {
31
+ mtimeMs: stats.mtimeMs,
32
+ size: stats.size,
33
+ contentHash: hashStorageBytes(readFileSync(storagePath)),
34
+ };
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ /**
41
+ * The official-CLI files `setCodexCliActiveSelection` mirrors into: auth.json
42
+ * and accounts.json carry the selection/tokens, config.toml carries the
43
+ * credential-store pin. Resolved per call — every one is env-overridable and
44
+ * may move between calls. The state module is already in this graph via
45
+ * `../codex-cli/writer.js`, so these imports add no cold-start weight.
46
+ */
47
+ function codexCliMirrorPaths() {
48
+ return [
49
+ ...new Set([
50
+ getCodexCliAuthPath(),
51
+ getCodexCliAccountsPath(),
52
+ getCodexCliConfigPath(),
53
+ ]),
54
+ ];
55
+ }
56
+ function statFingerprints(paths) {
57
+ const map = new Map();
58
+ for (const path of paths) {
59
+ map.set(path, statFingerprint(path));
60
+ }
61
+ return map;
62
+ }
63
+ /**
64
+ * mtime+size(+settle)/sha1 ladder for one file, same contract as
65
+ * `lib/runtime/rotation-storage-meta.ts`: a stat match is only trusted once
66
+ * the cached mtime has settled past ACTIVE_SYNC_MTIME_SETTLE_MS (atomic-rename
67
+ * writers can land two bumps on the same coarse tick — issue #474); anything
68
+ * else falls back to a content hash, which stays the source of truth. When
69
+ * the bytes match despite a stat change (same-content rewrite) the cached
70
+ * stat fields are refreshed in place so the next check can take the fast path.
71
+ */
72
+ function fingerprintMatchesCurrent(path, cached) {
73
+ let stats;
74
+ try {
75
+ stats = statSync(path);
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ if (cached.mtimeMs === stats.mtimeMs &&
81
+ cached.size === stats.size &&
82
+ Date.now() - stats.mtimeMs > ACTIVE_SYNC_MTIME_SETTLE_MS) {
83
+ return true;
84
+ }
85
+ let contentHash;
86
+ try {
87
+ contentHash = hashStorageBytes(readFileSync(path));
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ if (contentHash !== cached.contentHash) {
93
+ return false;
94
+ }
95
+ cached.mtimeMs = stats.mtimeMs;
96
+ cached.size = stats.size;
97
+ return true;
98
+ }
99
+ /**
100
+ * Returns true only when the whole synced state is unchanged: the on-disk
101
+ * accounts file is byte-identical to the one we last mirrored AND every Codex
102
+ * CLI mirror file still matches what our write left behind. The mirror side is
103
+ * what lets the post-forward call keep working — a forwarded `codex login`
104
+ * rewrites auth.json without touching the accounts file, so an input-only
105
+ * check would skip the very pass that re-asserts the canonical selection.
106
+ */
107
+ function isActiveSelectionSyncCurrent(storagePath) {
108
+ if (typeof storagePath !== "string" || storagePath.length === 0) {
109
+ return false;
110
+ }
111
+ if (!existsSync(storagePath)) {
112
+ ACTIVE_SYNC_FINGERPRINTS.delete(storagePath);
113
+ return false;
114
+ }
115
+ const cached = ACTIVE_SYNC_FINGERPRINTS.get(storagePath);
116
+ if (!cached) {
117
+ return false;
118
+ }
119
+ if (!fingerprintMatchesCurrent(storagePath, cached.storage)) {
120
+ return false;
121
+ }
122
+ const mirrorPaths = codexCliMirrorPaths();
123
+ if (mirrorPaths.length !== cached.mirror.size) {
124
+ return false;
125
+ }
126
+ for (const path of mirrorPaths) {
127
+ const expected = cached.mirror.get(path);
128
+ if (expected === undefined) {
129
+ // Mirror path set changed between calls (env override moved).
130
+ return false;
131
+ }
132
+ if (expected === null) {
133
+ // Recorded as absent — e.g. `codex logout` deleted it. Any file now
134
+ // present is drift the sync pass must reconcile.
135
+ if (existsSync(path)) {
136
+ return false;
137
+ }
138
+ continue;
139
+ }
140
+ if (!fingerprintMatchesCurrent(path, expected)) {
141
+ return false;
142
+ }
143
+ }
144
+ return true;
145
+ }
146
+ /**
147
+ * Cache the synced state, but only when the bytes on disk are still the exact
148
+ * bytes this pass mirrored (`syncedContentHash`). A concurrent switch or
149
+ * migration landing between our load and this record would otherwise leave the
150
+ * cache describing file content the mirror never saw, and the next call would
151
+ * skip the sync that corrects it. Mirror outputs are fingerprinted the same
152
+ * way; an output that existed before this pass (`preMirrorFingerprints`) or
153
+ * that the writer must have produced (`requiredMirrorPaths`) but is now absent
154
+ * means the mirror was torn down mid-pass — that state is never blessed.
155
+ */
156
+ function recordActiveSelectionSync(storagePath, syncedContentHash, preMirrorFingerprints, requiredMirrorPaths) {
157
+ const storage = statFingerprint(storagePath);
158
+ if (!storage || storage.contentHash !== syncedContentHash) {
159
+ ACTIVE_SYNC_FINGERPRINTS.delete(storagePath);
160
+ return;
161
+ }
162
+ const mirror = new Map();
163
+ for (const path of codexCliMirrorPaths()) {
164
+ const fingerprint = statFingerprint(path);
165
+ const fingerprintBeforePass = preMirrorFingerprints.get(path);
166
+ const existedBeforePass = fingerprintBeforePass !== undefined && fingerprintBeforePass !== null;
167
+ if (fingerprint === null &&
168
+ (existedBeforePass || requiredMirrorPaths.has(path))) {
169
+ ACTIVE_SYNC_FINGERPRINTS.delete(storagePath);
170
+ return;
171
+ }
172
+ mirror.set(path, fingerprint);
173
+ }
174
+ ACTIVE_SYNC_FINGERPRINTS.set(storagePath, { storage, mirror });
175
+ }
176
+ /**
177
+ * Test-only: clear the storage-fingerprint cache so each test re-reads from
178
+ * disk instead of inheriting a previous scenario's "already synced" state.
179
+ */
180
+ export function resetActiveAccountSyncMetaForTests() {
181
+ ACTIVE_SYNC_FINGERPRINTS.clear();
182
+ }
183
+ export async function autoSyncActiveAccountToCodex() {
184
+ setStoragePath(null);
185
+ // Fast path: the wrapper calls this before AND after every forwarded
186
+ // command — skip the load/refresh/write pass when neither the canonical
187
+ // accounts file nor the mirror files the last pass produced have moved.
188
+ // Only ever recorded after a successful mirror write over the fingerprinted
189
+ // bytes, so a transient refresh failure, a torn mirror, or a mid-pass
190
+ // mutation is retried on the next call.
191
+ const storagePath = getStoragePath();
192
+ if (isActiveSelectionSyncCurrent(storagePath)) {
193
+ return true;
194
+ }
195
+ // Snapshot the inputs before loading: the record step only caches when the
196
+ // file at record time is byte-identical to what this pass mirrored, so a
197
+ // concurrent switch landing mid-pass can never produce a cache entry that
198
+ // claims the mirror reflects content it does not.
199
+ const prePassFingerprint = statFingerprint(storagePath);
200
+ const preMirrorFingerprints = statFingerprints(codexCliMirrorPaths());
201
+ const storage = await loadAccounts();
202
+ if (!storage || storage.accounts.length === 0) {
203
+ return false;
204
+ }
205
+ const activeIndex = resolveActiveIndex(storage, "codex");
206
+ if (activeIndex < 0 || activeIndex >= storage.accounts.length) {
207
+ return false;
208
+ }
209
+ const account = storage.accounts[activeIndex];
210
+ if (!account) {
211
+ return false;
212
+ }
213
+ const accountMatch = {
214
+ accountId: account.accountId,
215
+ email: account.email,
216
+ refreshToken: account.refreshToken,
217
+ };
218
+ const now = Date.now();
219
+ let syncAccessToken = account.accessToken;
220
+ let syncRefreshToken = account.refreshToken;
221
+ let syncExpiresAt = account.expiresAt;
222
+ let syncIdToken;
223
+ let syncEmail = account.email;
224
+ let changed = false;
225
+ let nextStoredAccount = null;
226
+ let selectionDrifted = false;
227
+ if (!hasUsableAccessToken(account, now)) {
228
+ const refreshResult = await queuedRefresh(account.refreshToken);
229
+ if (refreshResult.type !== "success") {
230
+ return false;
231
+ }
232
+ nextStoredAccount = structuredClone(account);
233
+ const tokenAccountId = extractAccountId(refreshResult.access);
234
+ const nextEmail = sanitizeEmail(extractAccountEmail(refreshResult.access, refreshResult.idToken));
235
+ if (nextStoredAccount.refreshToken !== refreshResult.refresh) {
236
+ nextStoredAccount.refreshToken = refreshResult.refresh;
237
+ changed = true;
238
+ }
239
+ if (nextStoredAccount.accessToken !== refreshResult.access) {
240
+ nextStoredAccount.accessToken = refreshResult.access;
241
+ changed = true;
242
+ }
243
+ if (nextStoredAccount.expiresAt !== refreshResult.expires) {
244
+ nextStoredAccount.expiresAt = refreshResult.expires;
245
+ changed = true;
246
+ }
247
+ if (nextEmail && nextEmail !== nextStoredAccount.email) {
248
+ nextStoredAccount.email = nextEmail;
249
+ changed = true;
250
+ }
251
+ if (applyTokenAccountIdentity(nextStoredAccount, tokenAccountId)) {
252
+ changed = true;
253
+ }
254
+ syncAccessToken = refreshResult.access;
255
+ syncRefreshToken = refreshResult.refresh;
256
+ syncExpiresAt = refreshResult.expires;
257
+ syncIdToken = refreshResult.idToken;
258
+ syncEmail = nextStoredAccount.email;
259
+ }
260
+ let persistedFingerprint = null;
261
+ if (changed && nextStoredAccount) {
262
+ let persisted = false;
263
+ persistedFingerprint = await withAccountStorageTransaction(async (loadedStorage, persist) => {
264
+ if (!loadedStorage) {
265
+ return null;
266
+ }
267
+ const nextStorage = structuredClone(loadedStorage);
268
+ const targetIndex = findMatchingAccountIndex(nextStorage.accounts, accountMatch, {
269
+ allowUniqueAccountIdFallbackWithoutEmail: true,
270
+ }) ??
271
+ findMatchingAccountIndex(nextStorage.accounts, nextStoredAccount, {
272
+ allowUniqueAccountIdFallbackWithoutEmail: true,
273
+ });
274
+ if (targetIndex === undefined) {
275
+ return null;
276
+ }
277
+ // This under-lock re-read is the first point that sees a selection a
278
+ // concurrent process may have switched to since our loadAccounts().
279
+ // Persisting the refreshed tokens is still correct, but the mirror
280
+ // write below would re-select the stale account — skip it and let
281
+ // the next call mirror the selection that won the race.
282
+ if (resolveActiveIndex(nextStorage, "codex") !== targetIndex) {
283
+ selectionDrifted = true;
284
+ }
285
+ nextStorage.accounts[targetIndex] = structuredClone(nextStoredAccount);
286
+ await persist(nextStorage);
287
+ persisted = true;
288
+ // Still inside the file lock: this fingerprint is provably the exact
289
+ // bytes this pass persisted, i.e. what the mirror is built from.
290
+ return statFingerprint(storagePath);
291
+ });
292
+ if (!persisted) {
293
+ return false;
294
+ }
295
+ }
296
+ if (selectionDrifted) {
297
+ ACTIVE_SYNC_FINGERPRINTS.delete(storagePath);
298
+ return false;
299
+ }
300
+ // The mirrored selection is derived from `baseContentHash` bytes: the
301
+ // pre-pass content when storage was untouched, or the under-lock post-persist
302
+ // content when this pass refreshed tokens. If the file moved past that in
303
+ // between (concurrent switch, restore, migration), writing the mirror now
304
+ // would re-select a stale account — skip it and keep the cache cold so the
305
+ // next call re-reads and corrects.
306
+ const baseContentHash = changed
307
+ ? (persistedFingerprint?.contentHash ?? null)
308
+ : (prePassFingerprint?.contentHash ?? null);
309
+ const liveFingerprint = statFingerprint(storagePath);
310
+ if ((liveFingerprint?.contentHash ?? null) !== baseContentHash) {
311
+ ACTIVE_SYNC_FINGERPRINTS.delete(storagePath);
312
+ return false;
313
+ }
314
+ const synced = await setCodexCliActiveSelection({
315
+ accountId: codexCliAccountIdFor(nextStoredAccount ?? account, syncAccessToken, syncIdToken),
316
+ email: syncEmail,
317
+ accessToken: syncAccessToken,
318
+ refreshToken: syncRefreshToken,
319
+ expiresAt: syncExpiresAt,
320
+ ...(syncIdToken ? { idToken: syncIdToken } : {}),
321
+ });
322
+ if (synced) {
323
+ // The writer always (re)writes auth.json when the selection carries a
324
+ // token pair; treat its disappearance before the record as a torn
325
+ // mirror rather than a cacheable "absent" state.
326
+ const requiredMirrorPaths = new Set();
327
+ if (typeof syncAccessToken === "string" &&
328
+ syncAccessToken.trim().length > 0 &&
329
+ typeof syncRefreshToken === "string" &&
330
+ syncRefreshToken.trim().length > 0) {
331
+ requiredMirrorPaths.add(getCodexCliAuthPath());
332
+ }
333
+ recordActiveSelectionSync(storagePath, baseContentHash, preMirrorFingerprints, requiredMirrorPaths);
334
+ }
335
+ return synced;
336
+ }
@@ -11,4 +11,3 @@ interface MenuDeps {
11
11
  }
12
12
  export declare function runApiLoginMenu(overrides?: Partial<MenuDeps>): Promise<number>;
13
13
  export {};
14
- //# sourceMappingURL=api-login-menu.d.ts.map
@@ -100,4 +100,3 @@ export declare function promptBackendCategorySettingsEntry(params: {
100
100
  draft: PluginConfig;
101
101
  focusKey: BackendSettingFocusKey;
102
102
  }>;
103
- //# sourceMappingURL=backend-category-entry.d.ts.map
@@ -7,4 +7,3 @@ export declare function applyBackendCategoryDefaults(draft: PluginConfig, catego
7
7
  backendDefaults: PluginConfig;
8
8
  numberOptionByKey: ReadonlyMap<BackendNumberSettingKey, BackendNumberSettingOption>;
9
9
  }): PluginConfig;
10
- //# sourceMappingURL=backend-category-helpers.d.ts.map
@@ -52,4 +52,3 @@ export declare function promptBackendCategorySettingsMenu(params: {
52
52
  draft: PluginConfig;
53
53
  focusKey: BackendSettingFocusKey;
54
54
  }>;
55
- //# sourceMappingURL=backend-category-prompt.d.ts.map
@@ -8,4 +8,3 @@ export declare function configureBackendSettingsController(currentConfig: Plugin
8
8
  isInteractive: () => boolean;
9
9
  writeLine: (message: string) => void;
10
10
  }): Promise<PluginConfig>;
11
- //# sourceMappingURL=backend-settings-controller.d.ts.map
@@ -17,4 +17,3 @@ export declare function configureBackendSettingsEntry(currentConfig: PluginConfi
17
17
  isInteractive: () => boolean;
18
18
  writeLine: (message: string) => void;
19
19
  }): Promise<PluginConfig>;
20
- //# sourceMappingURL=backend-settings-entry.d.ts.map
@@ -12,4 +12,3 @@ export declare function buildBackendSettingsPreview(config: PluginConfig, ui: Re
12
12
  };
13
13
  export declare function buildBackendConfigPatch(config: PluginConfig): Partial<PluginConfig>;
14
14
  export declare function clampBackendNumberForTests(settingKey: string, value: number): number;
15
- //# sourceMappingURL=backend-settings-helpers.d.ts.map
@@ -46,4 +46,3 @@ export declare function promptBackendSettingsMenu(params: {
46
46
  backendHelp: string;
47
47
  };
48
48
  }): Promise<PluginConfig | null>;
49
- //# sourceMappingURL=backend-settings-prompt.d.ts.map
@@ -70,4 +70,3 @@ export declare const BACKEND_CATEGORY_OPTIONS: BackendCategoryOption[];
70
70
  export declare const BACKEND_DEFAULTS: PluginConfig;
71
71
  export declare const BACKEND_TOGGLE_OPTION_BY_KEY: Map<BackendToggleSettingKey, BackendToggleSettingOption>;
72
72
  export declare const BACKEND_NUMBER_OPTION_BY_KEY: Map<BackendNumberSettingKey, BackendNumberSettingOption>;
73
- //# sourceMappingURL=backend-settings-schema.d.ts.map
@@ -11,4 +11,3 @@ export interface BehaviorSettingsPanelDeps {
11
11
  UI_COPY: typeof UI_COPY;
12
12
  }
13
13
  export declare function promptBehaviorSettingsPanel(initial: DashboardDisplaySettings, deps: BehaviorSettingsPanelDeps): Promise<DashboardDisplaySettings | null>;
14
- //# sourceMappingURL=behavior-settings-panel.d.ts.map
@@ -1,13 +1,18 @@
1
- import { loadAccountPolicyStore, saveAccountPolicyStore } from "../../account-policy.js";
1
+ import { loadAccountPolicyStore, updateAccountPolicyStore } from "../../account-policy.js";
2
2
  import type { AccountStorageV3 } from "../../storage.js";
3
3
  export interface AccountCommandDeps {
4
4
  setStoragePath: (path: string | null) => void;
5
5
  loadAccounts: () => Promise<AccountStorageV3 | null>;
6
6
  loadPolicyStore?: typeof loadAccountPolicyStore;
7
- savePolicyStore?: typeof saveAccountPolicyStore;
7
+ /**
8
+ * Mutation seam: each mutation re-applies under the cross-process lock
9
+ * against the freshest store, so concurrent commands editing different
10
+ * fields of the same policy both land. Defaults to the real
11
+ * updateAccountPolicyStore.
12
+ */
13
+ updatePolicyStore?: typeof updateAccountPolicyStore;
8
14
  logInfo?: (message: string) => void;
9
15
  logError?: (message: string) => void;
10
16
  getNow?: () => number;
11
17
  }
12
18
  export declare function runAccountCommand(args: string[], deps: AccountCommandDeps): Promise<number>;
13
- //# sourceMappingURL=account.d.ts.map
@@ -1,4 +1,4 @@
1
- import { getAccountPolicyKey, loadAccountPolicyStore, normalizeAccountPolicyTag, saveAccountPolicyStore, upsertAccountPolicy, } from "../../account-policy.js";
1
+ import { getAccountPolicyKey, loadAccountPolicyStore, normalizeAccountPolicyTag, updateAccountPolicyStore, upsertAccountPolicy, } from "../../account-policy.js";
2
2
  function printAccountUsage(logInfo) {
3
3
  logInfo([
4
4
  "Usage:",
@@ -54,9 +54,9 @@ export async function runAccountCommand(args, deps) {
54
54
  deps.setStoragePath(null);
55
55
  const storage = await deps.loadAccounts();
56
56
  const loadStore = deps.loadPolicyStore ?? loadAccountPolicyStore;
57
- const saveStore = deps.savePolicyStore ?? saveAccountPolicyStore;
58
- const store = await loadStore();
57
+ const updateStore = deps.updatePolicyStore ?? updateAccountPolicyStore;
59
58
  if (command === "policy") {
59
+ const store = await loadStore();
60
60
  const [subcommand, ...policyArgs] = rest;
61
61
  if (subcommand !== "list") {
62
62
  logError(`Unknown account policy command: ${subcommand ?? "(missing)"}`);
@@ -107,14 +107,16 @@ export async function runAccountCommand(args, deps) {
107
107
  logError(`${command} requires a tag value.`);
108
108
  return 1;
109
109
  }
110
- const policy = upsertAccountPolicy(store, accountKey, (next) => {
111
- if (command === "tag" && !next.tags.includes(tag))
112
- next.tags.push(tag);
113
- if (command === "untag") {
114
- next.tags = next.tags.filter((existing) => existing !== tag);
115
- }
116
- }, now);
117
- await saveStore(store);
110
+ const policy = await updateStore((store) => ({
111
+ result: upsertAccountPolicy(store, accountKey, (next) => {
112
+ if (command === "tag" && !next.tags.includes(tag))
113
+ next.tags.push(tag);
114
+ if (command === "untag") {
115
+ next.tags = next.tags.filter((existing) => existing !== tag);
116
+ }
117
+ }, now),
118
+ dirty: true,
119
+ }));
118
120
  logInfo(`${command === "tag" ? "Tagged" : "Removed tag from"} account ${resolved.index + 1}: ${policy.tags.join(",") || "none"}`);
119
121
  return 0;
120
122
  }
@@ -123,8 +125,10 @@ export async function runAccountCommand(args, deps) {
123
125
  logError("auto-prime requires on or off.");
124
126
  return 1;
125
127
  }
126
- upsertAccountPolicy(store, accountKey, next => { next.autoPrime = rest[1] === "on"; }, now);
127
- await saveStore(store);
128
+ await updateStore((store) => ({
129
+ result: upsertAccountPolicy(store, accountKey, next => { next.autoPrime = rest[1] === "on"; }, now),
130
+ dirty: true,
131
+ }));
128
132
  logInfo(`Automatic priming ${rest[1]} for account ${resolved.index + 1}. ${rest[1] === "on" ? "The running router checks every 15 minutes; first-use completion consumes subscription quota." : "Future automatic checks are disabled."}`);
129
133
  return 0;
130
134
  }
@@ -134,8 +138,10 @@ export async function runAccountCommand(args, deps) {
134
138
  return 1;
135
139
  }
136
140
  const priority = Number(rest[1]);
137
- upsertAccountPolicy(store, accountKey, next => { next.priority = priority; }, now);
138
- await saveStore(store);
141
+ await updateStore((store) => ({
142
+ result: upsertAccountPolicy(store, accountKey, next => { next.priority = priority; }, now),
143
+ dirty: true,
144
+ }));
139
145
  logInfo(`Set account ${resolved.index + 1} priority to ${priority}.`);
140
146
  return 0;
141
147
  }
@@ -145,34 +151,40 @@ export async function runAccountCommand(args, deps) {
145
151
  logError("weight requires a number from 0 to 10.");
146
152
  return 1;
147
153
  }
148
- upsertAccountPolicy(store, accountKey, (next) => {
149
- next.weight = weight;
150
- }, now);
151
- await saveStore(store);
154
+ await updateStore((store) => ({
155
+ result: upsertAccountPolicy(store, accountKey, (next) => {
156
+ next.weight = weight;
157
+ }, now),
158
+ dirty: true,
159
+ }));
152
160
  logInfo(`Set account ${resolved.index + 1} weight to ${weight}.`);
153
161
  return 0;
154
162
  }
155
163
  if (["pause", "unpause", "drain", "undrain"].includes(command)) {
156
- upsertAccountPolicy(store, accountKey, (next) => {
157
- if (command === "pause")
158
- next.paused = true;
159
- if (command === "unpause")
160
- next.paused = false;
161
- if (command === "drain")
162
- next.drained = true;
163
- if (command === "undrain")
164
- next.drained = false;
165
- }, now);
166
- await saveStore(store);
164
+ await updateStore((store) => ({
165
+ result: upsertAccountPolicy(store, accountKey, (next) => {
166
+ if (command === "pause")
167
+ next.paused = true;
168
+ if (command === "unpause")
169
+ next.paused = false;
170
+ if (command === "drain")
171
+ next.drained = true;
172
+ if (command === "undrain")
173
+ next.drained = false;
174
+ }, now),
175
+ dirty: true,
176
+ }));
167
177
  logInfo(`Updated account ${resolved.index + 1}: ${command}.`);
168
178
  return 0;
169
179
  }
170
180
  if (command === "note") {
171
181
  const note = rest.slice(1).join(" ").trim();
172
- upsertAccountPolicy(store, accountKey, (next) => {
173
- next.note = note.length > 0 ? note.slice(0, 500) : null;
174
- }, now);
175
- await saveStore(store);
182
+ await updateStore((store) => ({
183
+ result: upsertAccountPolicy(store, accountKey, (next) => {
184
+ next.note = note.length > 0 ? note.slice(0, 500) : null;
185
+ }, now),
186
+ dirty: true,
187
+ }));
176
188
  logInfo(`Updated account ${resolved.index + 1} note.`);
177
189
  return 0;
178
190
  }
@@ -92,4 +92,3 @@ export interface BestCommandDeps {
92
92
  }
93
93
  export declare function runBestCommand(args: string[], deps: BestCommandDeps): Promise<number>;
94
94
  export {};
95
- //# sourceMappingURL=best.d.ts.map
@@ -3,4 +3,3 @@ export interface BridgeCommandDeps {
3
3
  logError?: (message: string) => void;
4
4
  }
5
5
  export declare function runBridgeCommand(args: string[], deps?: BridgeCommandDeps): Promise<number>;
6
- //# sourceMappingURL=bridge.d.ts.map
@@ -1,12 +1,17 @@
1
- import { loadBudgetGuardStore, saveBudgetGuardStore } from "../../budget-guard.js";
1
+ import { loadBudgetGuardStore, updateBudgetGuardStore } from "../../budget-guard.js";
2
2
  import { summarizeUsageLedger } from "../../usage/index.js";
3
3
  export interface BudgetCommandDeps {
4
4
  loadStore?: typeof loadBudgetGuardStore;
5
- saveStore?: typeof saveBudgetGuardStore;
5
+ /**
6
+ * Mutation seam: each mutation re-applies under the cross-process lock
7
+ * against the freshest store, so a concurrent `budget limit` on the same
8
+ * key is not silently dropped by the whole-record timestamp merge.
9
+ * Defaults to the real updateBudgetGuardStore.
10
+ */
11
+ updateStore?: typeof updateBudgetGuardStore;
6
12
  summarizeUsage?: typeof summarizeUsageLedger;
7
13
  logInfo?: (message: string) => void;
8
14
  logError?: (message: string) => void;
9
15
  getNow?: () => number;
10
16
  }
11
17
  export declare function runBudgetCommand(args: string[], deps?: BudgetCommandDeps): Promise<number>;
12
- //# sourceMappingURL=budget.d.ts.map
@@ -1,4 +1,4 @@
1
- import { evaluateBudgetGuard, getBudgetWindowStart, loadBudgetGuardStore, normalizeBudgetKey, saveBudgetGuardStore, upsertBudgetLimit, } from "../../budget-guard.js";
1
+ import { evaluateBudgetGuard, getBudgetWindowStart, loadBudgetGuardStore, normalizeBudgetKey, updateBudgetGuardStore, upsertBudgetLimit, } from "../../budget-guard.js";
2
2
  import { summarizeUsageLedger } from "../../usage/index.js";
3
3
  const VALID_WINDOWS = new Set(["hour", "day", "week", "month"]);
4
4
  function printBudgetUsage(logInfo) {
@@ -24,7 +24,7 @@ export async function runBudgetCommand(args, deps = {}) {
24
24
  return 0;
25
25
  }
26
26
  const loadStore = deps.loadStore ?? loadBudgetGuardStore;
27
- const saveStore = deps.saveStore ?? saveBudgetGuardStore;
27
+ const updateStore = deps.updateStore ?? updateBudgetGuardStore;
28
28
  const store = await loadStore();
29
29
  const now = deps.getNow?.() ?? Date.now();
30
30
  if (command === "list") {
@@ -91,8 +91,10 @@ export async function runBudgetCommand(args, deps = {}) {
91
91
  logError("At least one of --requests, --tokens, or --cost is required.");
92
92
  return 1;
93
93
  }
94
- const limit = upsertBudgetLimit(store, { key, window, maxRequests, maxTokens, maxCostUsd }, now);
95
- await saveStore(store);
94
+ const limit = await updateStore((store) => ({
95
+ result: upsertBudgetLimit(store, { key, window, maxRequests, maxTokens, maxCostUsd }, now),
96
+ dirty: true,
97
+ }));
96
98
  logInfo(`Saved budget limit ${limit.key} (${limit.window}).`);
97
99
  return 0;
98
100
  }
@@ -10,4 +10,3 @@ export interface CheckCommandDeps {
10
10
  logError?: (message: string) => void;
11
11
  }
12
12
  export declare function runCheckCommand(deps: CheckCommandDeps, args?: string[]): Promise<number>;
13
- //# sourceMappingURL=check.d.ts.map
@@ -4,4 +4,3 @@ export declare function runConfigExplainCommand(args: string[], deps: {
4
4
  logInfo?: (message: string) => void;
5
5
  logError?: (message: string) => void;
6
6
  }): number;
7
- //# sourceMappingURL=config-explain.d.ts.map
@@ -41,4 +41,3 @@ export declare function runDebugBundleCommand(args: string[], deps: {
41
41
  logInfo?: (message: string) => void;
42
42
  logError?: (message: string) => void;
43
43
  }): Promise<number>;
44
- //# sourceMappingURL=debug-bundle.d.ts.map
@@ -75,4 +75,3 @@ export declare function runForecastCommand(args: string[], deps: ForecastCommand
75
75
  formatQuotaSnapshotLine: (snapshot: CodexQuotaSnapshot) => string;
76
76
  }): Promise<number>;
77
77
  export {};
78
- //# sourceMappingURL=forecast.d.ts.map
@@ -20,4 +20,3 @@ export interface HistoryCommandDeps {
20
20
  logError?: (message: string) => void;
21
21
  }
22
22
  export declare function runHistoryCommand(args: string[], deps?: HistoryCommandDeps): number;
23
- //# sourceMappingURL=history.d.ts.map
@@ -12,4 +12,3 @@ export declare function runInitConfigCommand(args: string[], deps?: {
12
12
  cwd?: () => string;
13
13
  }): Promise<number>;
14
14
  export {};
15
- //# sourceMappingURL=init-config.d.ts.map
@@ -3,4 +3,3 @@ export interface IntegrationsCommandDeps {
3
3
  logError?: (message: string) => void;
4
4
  }
5
5
  export declare function runIntegrationsCommand(args: string[], deps?: IntegrationsCommandDeps): number;
6
- //# sourceMappingURL=integrations.d.ts.map