v2.1.2
Highlights
- Codex multi-account support.
aistat usagenow reports per-account rows for Codex (mirroring Claude's nested format), andaistat switch codexrewrites the live~/.codex/auth.jsonbetween stored ChatGPT accounts without a browser round-trip. Identity is resolved from theid_tokensubclaim (JWT decode, no network). - Slot-vs-duration window labeling. Codex windows are labeled by
limit_window_seconds, not slot position — so free-account windows (including OpenAI's recent weekly→monthly quota change) are correctly labeledthirty_dayinstead of being assumed to be the primary 5-hour window. - Provider-scoped
switch/accountsCLI with bulk-on-omission:aistat switch [provider] [--to <id>],aistat accounts list|remove [provider]. Omitting the provider fans out to every provider with ≥2 stored accounts (auto-pick best by headroom).
Codex UX
- Tighter, actionable errors for upstream OAuth failures matched to the real upstream bodies: the refresh-token rotation race (
codex loginto recover) and same-client token revocation (token_revoked/token_invalidated).
Fixes
- fsync the live-credential write on Linux; fail closed on resolver error in
accounts remove(#13).
Internal
- Test suite migrated to table-driven
t.Runsubtests with sharedtestutilhelpers and externalized golden output — no behavior change. SeeTESTING.md.
Full changelog: v2.1.1...v2.1.2