settings-store lists codex accounts as
index 0 = ~/.codex/auth.json (default)
index N = ~/.codex-accounts/{N}/auth.json
but codex-token-rotation only loads ~/.codex-accounts/{N} when those
dirs exist (it ignores ~/.codex/auth.json in that mode), so the
rotation array's indices are off-by-one vs settings indices.
Old buggy behavior:
- "사용중" badge pointed at the wrong account.
- Clicking 전환 on UI #N called setCurrentCodexAccountIndex(N) which
selected rotation array element N — typically a different
~/.codex-accounts/{N+1} entry. Effectively the UI told us a
different account was now active than what the next codex spawn
actually used.
Fix
- New findCodexAccountIndexByAuthPath(path) on the rotation module
exposes a path-based lookup.
- New getActiveCodexSettingsIndex() / setActiveCodexSettingsIndex(idx)
in settings-store translate via codexAuthPath() ↔
findCodexAccountIndexByAuthPath().
- /api/settings/accounts.codexCurrentIndex and PUT
/api/settings/accounts/codex/current both go through the
settings-side translation, so UI indices are now authoritative.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* Settings: clarify Codex 만료=결제, drop Claude expiry badge
- Codex expiry badge now says "결제 만료/까지" so it's unambiguous that
this is the ChatGPT Pro/Team subscription end-date, not an OAuth
access-token TTL.
- Claude rows no longer show an expiry badge: Claude credentials only
expose an OAuth access_token TTL (auto-refreshed every few minutes
by the existing claude token refresh loop), which is meaningless to
the user. Replace it with a static "토큰 자동갱신" tag so the column
alignment stays consistent.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Codex refresh: pull live plan_type from /wham/usage (sidecar override)
OAuth refresh_token grant returns a fresh JWT but auth0 caches the
chatgpt_plan_type and chatgpt_subscription_active_until claims at issue
time. So users who upgrade/downgrade their plan kept seeing the old
plan in the dashboard even after a forced refresh.
After each refreshCodexAccount() call, additionally GET
https://chatgpt.com/backend-api/wham/usage with the freshly-issued
access_token. That endpoint returns the current plan_type and email
from OpenAI's account service. Persist it to a sidecar
plan-status.json next to auth.json (not into auth.json itself, since
codex CLI may rewrite that file). readCodexAccount prefers the live
plan_type and uses the sidecar's checked_at as subscriptionLastChecked,
so the dashboard immediately reflects post-billing-event plan changes.
Confirmed end-to-end: account that was billed-down from Pro to Plus
now shows plus instead of stale pro after one refresh.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>