Releases: 4LAU/codex-profile-switcher
Releases · 4LAU/codex-profile-switcher
Release list
v0.5.0
What's new in 0.5.0
Added
codex-profile leasecommand for warm-session account rotation.lease begin|swap|end|gcreserves the best-quota profile and seeds a private throwawayCODEX_HOMEfor a long-lived (warm) Codex session, recording a TTL reservation so two concurrent runs never pick the same account.lease swaphot-rotates the credential to a fresh account in place when the current one hits a usage limit — without losing the warm session;lease endwrites the refreshed credential back and tears the lease down (idempotent, trap-safe);lease gcreclaims expired or orphaned lease homes.import-auth --non-interactiveand--timeout <seconds>— the headless-safe credential write-back path used bylease end.
Fixed
- Lease credential-safety under concurrency. Every read-modify-write of the shared usage cache now runs inside a cross-process lock, so a concurrent writer can no longer drop a just-committed lease.
swap/end/gcpreserve refreshed credentials, never strand a rotated token, and never resurrect or clobber a concurrent lease.
The notarized DMG is attached below. Homebrew users get the update automatically.
v0.4.1
Changed
- Unsigned (ad-hoc) builds of the app and CLI no longer touch the macOS Keychain. Every rebuild of an unsigned binary has a new code identity, which made macOS show a consent prompt per saved profile after each rebuild. Unsigned builds now automatically use a separate file-based dev vault at
~/.codex-switcher/dev-auth-storewith a one-line notice; signed builds (releases,make install-cli) keep using the Keychain unchanged.
See CHANGELOG.md for details.
v0.4.0
Added
- New
codex-profile exec -- <command> [args...]command: runs any command withCODEX_HOMEpointed at the best profile's credentials and automatically rotates to the next best profile when the command fails with a usage-limit error (--max-attempts, default 3). The exhausted profile is marked unavailable for an hour, refreshed tokens are written back to the profile afterwards, and the live~/.codexis never touched. stdin/stdout pass through untouched; the child's exit code is passed through on non-retryable failures.
See CHANGELOG.md for details.
v0.3.0
Added
best-authnow fetches live usage (Codex app-server, bounded concurrency) before ranking, instead of relying on the menu bar app's cached usage file. When the app isn't running it no longer silently picks alphabetically off a stale/empty cache. Per-profile fetch failures fall back to the cached snapshot, and fresh snapshots are merged back into the cache.best-auth --jsonemits a stable machine-readable report (selected,tier,score,candidates[],fetched).status --jsonandlist --jsonemit structured output too. Default (non-JSON)best-authoutput is unchanged: the bare selected profile ID.best-authnow has documented, stable exit codes: 0 selected, 2 no eligible profile, 3 no profiles configured, 4 usage data unavailable, 6 keychain interaction required, 7 watchdog timeout.
Changed
- Usage polling now uses Codex's app-server exclusively; removes the reverse-engineered usage API client and OAuth refresh-on-poll.
best-authandimport-authare now official supported commands.import-authexits 5 only on an identity mismatch (a refreshed credential belonging to a different account) and 1 for other failures.
Fixed
- Fixed false "re-auth needed" status for profiles with valid tokens (bare
401/403substrings false-positived on unrelated error messages such as port numbers). - Fixed
best-authreporting a different tier/score from what was used for selection when a rate-limit reset boundary was crossed between the ranking and report steps. - Fixed a potential data race between background usage refreshes and profile state.
best-authno longer hangs forever in non-interactive shells (CI, command substitution, background tasks). When stdin is not a terminal (or--non-interactiveis passed), a Keychain read that needs interactive consent now exits with a clear message (code 6) instead of blocking on a modal prompt with no UI. A global watchdog (--timeout, default 30s, exit 7) guarantees the command always terminates.
v0.2.1
Fixed
- Reduced Keychain password prompts from 36 to 12 (one per profile, one-time after binary change) by eliminating redundant reads during save and refresh
- ACL repair now retries on next launch if any profiles were denied — previously a partial failure was treated as complete
- Added crash-window recovery files so credentials survive a process kill during repair
- CLI auto-repair runs before auth-reading commands (
best-auth,status,import-auth,login,app) — no longer requires explicitkeychain-repair
v0.2.0
Breaking
- Existing profiles stored in the data protection Keychain are no longer accessible — re-login each profile with
codex-profile login <name>
Changed
- Switched from data protection Keychain to legacy ACL Keychain —
swift buildnow produces a fully working binary without entitlements or provisioning profiles - Removed
migrateCLI command and all migration machinery
Removed
- Data protection Keychain backend (
DataProtectionKeychainAuthVault) - Dual-backend migration wrapper (
MigratingAuthVault) - Provisioning profile discovery and embedding
- "Migration needed" profile status in the UI
v0.1.12
Added
best-authCLI command — selects the least-used configured profile and exports its credentials to a temp directory forcodex exec --ephemeralmark-exhaustedCLI command — flags a profile as rate-limited sobest-authskips itimport-authCLI command — imports refreshed credentials back from a temp directory with identity verification
Fixed
- GUI app now preserves CLI-written exhaustion overrides when saving the usage cache
- Profile removal and auth clearing now clean up exhaustion overrides