Add Codex all-accounts menu mode and sorting#633
Add Codex all-accounts menu mode and sorting#633monterrr wants to merge 3 commits intosteipete:mainfrom
Conversation
Co-Authored-By: Craft Agent <agents-noreply@craft.do>
Co-Authored-By: Craft Agent <agents-noreply@craft.do>
Co-Authored-By: Craft Agent <agents-noreply@craft.do>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df30db742e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| guard let model = self.menuCardModel( | ||
| for: context.currentProvider, | ||
| snapshotOverride: cached?.snapshot, | ||
| errorOverride: cached?.error, | ||
| isRefreshingOverride: cached == nil && self.store.codexAllAccountsRefreshInFlight) |
There was a problem hiding this comment.
Avoid falling back to active snapshot in all-account cards
When an account has no cached entry (or only a cached error), this passes nil as snapshotOverride, and menuCardModel then falls back to the global Codex snapshot for the currently selected account. In All mode this makes other account cards temporarily render the active account’s usage/identity data, so users can see duplicated or incorrect quota values until each fetch finishes (or while a fetch error persists). Build the all-accounts card model without provider fallback when cached?.snapshot is missing.
Useful? React with 👍 / 👎.
| let usage = try await context.fetcher.loadLatestUsage(keepCLISessionsAlive: keepAlive) | ||
| var usage = try await context.fetcher.loadLatestUsage(keepCLISessionsAlive: keepAlive) | ||
| if let credentials = try? CodexOAuthCredentialsStore.load(env: context.env) { | ||
| let resolvedWorkspaceIdentity = try? await CodexOpenAIWorkspaceResolver.resolve(credentials: credentials) |
There was a problem hiding this comment.
Keep CLI usage refresh non-blocking for workspace lookup
This now awaits workspace resolution on every CLI fetch, which couples a local usage read to an extra network request. Since the resolver uses an HTTP call with a 20-second timeout, slow/offline environments can have each refresh delayed even when usage data is already available. Workspace identity enrichment should be best-effort (cache-first / background update) so a transient account-lookup failure does not stall normal Codex usage polling.
Useful? React with 👍 / 👎.
Context
This is the remaining follow-up to the Codex multi-account work around #545, first proposed in #588 and partially landed in #613.
The same-email / workspace correctness gap is being handled in #629. This PR focuses on the remaining menu-side work: a simple all-accounts overview, cached loading, and the old sort modes.
Once multiple Codex accounts are available, the current menu still makes you inspect them one by one. In practice that means repeated switching just to answer simple questions like which account still has room left, which one resets first, and which one is already close to empty.
Screenshots
All mode: compact passive quota cards with sort control.

Single mode: the detailed card stays in place, with the new

All | Singlecontrol above it.Summary
This PR adds a simple
All | Singlemode for Codex.Without an all-accounts view, multi-account support still leaves a practical gap: the data exists, but the user still has to hop through accounts one at a time to compare them.
What this adds
All | Singlemode toggle for Codex, hidden when only one visible account existsValidation
corepack pnpm check./Scripts/compile_and_run.shswift test --filter StatusMenuCodexSwitcherTestsswift test --filter CodexManagedOpenAIWebTestsswift test --filter CodexManagedRoutingTestsswift test --filter CodexAccountScopedRefreshTests