Skip to content

Releases: ndycode/oc-codex-multi-auth

v6.5.0

Choose a tag to compare

@ndycode ndycode released this 30 Jun 10:44
755aa46

Added

  • oc-codex-multi-auth warm standalone CLI command runs the account warm-up directly — in plain Node via the package bin, with no agent/model in the loop and therefore no token cost. It opens every enabled account's rolling usage window (one minimal POST /codex/responses each), skips disabled accounts, classifies a quota/usage_limit 429 as a distinct failure rather than "warmed", supports --json, and exits non-zero when any account failed. Run it (or npx -y oc-codex-multi-auth@latest warm) at the start of a session to stagger the rolling quota cooldowns. This addresses the request to run the warm-up as a direct command instead of an agent-invoked tool; the in-conversation codex-warm tool remains for users who want it mid-session. (#182)

Fixed

  • A standalone command's non-zero exit code now propagates to the process exit code instead of being dropped, so oc-codex-multi-auth warm correctly exits 1 when an account fails (useful in scripts and CI) while read-only commands still exit 0.
  • warm no longer hard-fails when the Codex system-prompt file cannot be resolved (offline, cache miss, or a standalone run without the bundled prompt): the warm ping falls back to a minimal instruction, since it only needs a valid request to open the window, not the full prompt.

Notes

  • This is a minor release that adds a new entry point; nothing in the existing request path, rotationStrategy config, or the in-conversation codex-warm tool changes behavior. The standalone warm is the first standalone CLI command that performs network I/O (token refresh + one request per account) — the other standalone commands (status, health, doctor, limits, list) remain read-only and network-free.

v6.4.1

Choose a tag to compare

@ndycode ndycode released this 30 Jun 07:07

Fixed

  • Local token-bucket depletion no longer leaks into persisted, cross-process state. 6.4.0 made a depleted account rotate by writing a synthetic window into rateLimitResetTimes — but that field is saved to the shared accounts file and reloaded by every process, so one process exhausting its own in-memory proactive limiter could spuriously mark a server-healthy account as rate-limited in other concurrent processes (the multi-process / PID-offset deployment this tool targets). Account selection (sticky, hybrid, round-robin) and getMinWaitTimeForFamily are now token-bucket-aware directly: a locally-depleted account is skipped in-memory with no persisted state, and an all-depleted pool waits for token refill instead of returning a spurious 503. (#183)
  • A locally-depleted account no longer accrues a server-429-style health penalty. The depletion path previously called recordRateLimit, mis-attributing a purely-local proactive throttle as an upstream rejection and deprioritizing a perfectly healthy account in hybrid scoring for hours. (#183)
  • codex-warm no longer reports a quota-exhausted account as "warmed". A 429 is now classified by reason: a quota/usage_limit 429 (the window is already spent) is surfaced as a distinct failure, while a transient tokens/concurrent 429 (window active) still counts as warmed. (#182)

Notes

  • This is a patch release that corrects a regression introduced in 6.4.0; the rotationStrategy config (#183) and codex-warm tool (#182) added in 6.4.0 are unchanged in behavior except for the fixes above. Single-process usage was unaffected by the regression — the leak only manifested across concurrent processes sharing one accounts file.
  • The local token bucket is intentionally in-memory and per-process; only real server 429s belong in the persisted rateLimitResetTimes. Selectors now consult the bucket in-memory rather than encoding local back-pressure into shared state.

v6.3.4

Choose a tag to compare

@ndycode ndycode released this 19 Jun 14:07

Fixed

  • A dark account pool now recovers without hand-editing JSON. When a stored account is left with a stale auth-failure/network-error cooldown or stale rateLimitResetTimes (future-dated reset), it stays ineligible for rotation even though the credential is alive — so every account can go dark and normal requests fail while --pure works. codex-doctor --fix now clears that stale state on accounts whose token refresh succeeds, clears the stale TUI quota cache, and the recovery self-heals across restarts. (#173, fixes #171)
  • codex-doctor --fix no longer fails silently when a credential is genuinely dead: a failed token refresh now reports N account(s) need re-login and points at opencode auth login, instead of leaving an all-dark pool unrepaired with no surfaced cause. (#177)
  • codex-health now surfaces the same recovery diagnostics as codex-doctor (read-only): accounts blocked only by a stale cooldown/rate-limit (→ codex-doctor --fix) and disabled duplicate entries (→ codex-remove), plus staleRecoverableSlots / disabledDuplicateSlots in JSON output. (#177)
  • A disabled accountIdSource: "token" duplicate (a re-login artifact) merging into the real org account by email no longer disables the canonical account. Storage dedup lets the org account's own enabled state govern the merge, so a single-account pool can no longer end up dark and unrecoverable; fail-closed is preserved for genuinely user-disabled accounts. (#180, fixes #171)
  • Storage dedup now compares account emails case-insensitively, matching the codex-doctor/codex-health detectors. Previously User@Example.com and user@example.com escaped dedup yet were still flagged as removable, so the two layers disagreed on identity. (#181)
  • codex-doctor and codex-health now surface a disabled account that holds a fresh login credential — the fingerprint of a recent re-login that landed on a disabled slot — so the user is told to re-enable it if intended instead of getting no signal. (#181)
  • Caller-cancellation during a retry/backoff wait now surfaces as a proper AbortError carrying the caller's signal.reason, instead of an opaque new Error("Aborted") that dropped the cause. (#178)

Security

  • Bumped hono to 4.12.26, resolving a high-severity Windows serve-static path traversal via encoded backslash (%5C) and four moderate advisories. This also clears the transitive @openauthjs/openauth advisory. (#173)
  • Overrode vite to ^7.3.5 (high + moderate, dev/test toolchain), @babel/core to ^7.29.6 (low, no major bump), and brace-expansion 5.x to ^5.0.6 (moderate). npm audit now reports 0 vulnerabilities. (#173)

Notes

  • The recovery is repaired via codex-doctor --fix (now also surfaced by codex-health), not automatic self-heal in the request path — a future-dated cooldown/rate-limit is only cleared on an explicit repair, since auto-clearing would undermine the legitimate 401/429 backoff.
  • The Error: Aborted symptom reported on a clean pool (#176) had its sleep/backoff cancellation typed as a real AbortError, but the underlying root trigger is still being investigated and is tracked separately in #176.

v6.3.3

Choose a tag to compare

@ndycode ndycode released this 17 Jun 05:30

Fixed

  • A stored OAuth account whose access token is invalidated server-side returns HTTP 401 (Your authentication token has been invalidated. Please try signing in again.), but the request pipeline had no 401 handler, so persisted family routing kept pinning every request to the dead account slot. A request-path 401 is now treated as an account-health failure: the consumed token is refunded, the auth-failure counter is incremented, the refresh-token group is cooled down (or removed past MAX_AUTH_FAILURES_BEFORE_REMOVAL), and the request rotates to the next healthy account. The counter is cleared on a successful request so a recovered account does not accumulate stale failures. (#172, fixes #171)
  • codex-health/codex-doctor now flag token-invalid on an invalidated-token error (including a generic 401 Unauthorized body), so codex-doctor --fix repairs the active routing without manual activeIndex JSON edits. (#172)

Notes

  • Once the bad slot is cooled down, the next successful rotation persists the updated family routing, so the failure self-heals across restarts — no more manual activeIndex editing.
  • Single-account pools: a 401 cannot fail over (nowhere to rotate); the account is cooled down and the request surfaces "no other account available."

v6.3.2

Choose a tag to compare

@ndycode ndycode released this 10 Jun 15:18

Bug Fixes

  • Preserve versioned Codex model IDs — \gpt-5.3-codex-spark, \gpt-5.3-codex, and \gpt-5.2-codex\ are no longer collapsed to \gpt-5-codex\ before sending requests. Accounts where only the versioned model is available no longer receive \model_not_supported_with_chatgpt_account\ errors. (#170, fixes #169)
  • Added \gpt-5.4-fast\ and \gpt-5.4-mini-fast\ as explicit model map entries so OpenCode fast-variant selectors resolve correctly.

Notes

  • Reasoning effort -none\ is intentionally absent for the three Codex families above; requests with
    one\ effort are coerced to \low\ as the backend rejects
    one\ for these models.
  • \getReasoningConfig(), \getModelFamily(), and the fallback chain are unaffected — all three families continue to default to \xhigh\ reasoning and fall back correctly through the chain.

v6.3.1

Choose a tag to compare

@ndycode ndycode released this 06 Jun 07:09
0cc1912

What's Changed

Security

  • Bump hono 4.12.18 → 4.12.23 (#168) to clear four moderate advisories (GHSA-f577-qrjj-4474, GHSA-3hrh-pfw6-9m5x, GHSA-xrhx-7g5j-rcj5, GHSA-2gcr-mfcq-wcc3), all fixed upstream in 4.12.21. hono is a transitive dependency of @openauthjs/openauth (peer ^4.0.0), pinned via overrides.
    • npm audit --omit=dev: 0 vulnerabilities (was 2 moderate).
    • No source change — hono is used only inside @openauthjs/openauth's OAuth flow.

Full test suite: 2487 passing. Build / typecheck / lint clean.

v6.3.0

Choose a tag to compare

@ndycode ndycode released this 06 Jun 07:08
258cba8

What's Changed

Added

  • Mask account emails across all display surfaces (#164) — maskEmail now applies to command output, the interactive auth menu, delete/refresh confirmations, the standalone login menu, the interactive account picker, and runtime rotation/auth-failure messages, not just the TUI quota status. Raw emails remain only in opt-in --includeSensitive JSON.

Fixed

  • 16 deep-audit findings (#165) — data-loss, rotation, redaction, and concurrency bugs:
    • Transient refresh failures (network/5xx) no longer trigger permanent account removal.
    • Keychain load no longer swallows forward-compat (UNSUPPORTED_SCHEMA_VERSION / V2) errors.
    • Workspace-deactivation removes only the deactivated workspace, not refresh-token siblings.
    • Refresh-token rotation propagates to sibling org-variant accounts.
    • runAccountCheck / email hydration writes are transactional (no lost updates).
    • Health/token-bucket/backoff trackers remap on account removal (no misattributed rotation state).
    • Token-bucket depletion rotates instead of aborting the whole pool.
    • Empty-response retry actually retries (was a no-op 503 for single-account).
    • retry_after_ms vs retry_after scaled correctly.
    • Stream-stall/SSE exceptions refund the token and rotate.
    • codex-diff redaction is key-aware (opaque tokens no longer leak).
    • Flagged storage uses the keychain when CODEX_KEYCHAIN=1.
    • Logger masks emails domain-preserving and adds cookie headers to the sensitive set.

Internal

  • Deep stress suite (#166) — property-based and concurrency tests for the audited subsystems, each mutation-verified.

Full test suite: 2487 passing.

v6.2.0

Choose a tag to compare

@ndycode ndycode released this 30 May 12:55
22e7823

Minor release bundling two feature PRs plus review polish.

Added

  • TUI email masking (#160) — opt-in masking of the active account email in the prompt quota status and the quota details dialog. Config keys: maskEmail, maskEmailInQuotaDetails. Env overrides: CODEX_TUI_MASK_EMAIL, CODEX_TUI_MASK_EMAIL_DETAILS. Both default to off, so existing output is unchanged.

Fixed

  • Workspace-specific usage quotas (#161) — codex-limits and the TUI now deduplicate usage accounts by workspace identity (accountId + organizationId) before falling back to the refresh token, so multiple ChatGPT workspaces sharing a single login each show their own quota row. The freshest credential per workspace is queried; disabled and identity-less accounts are skipped; resolveCodexUsageActiveAccount no longer throws on sparse account slots.
  • Test isolation (#161) — rotation integration tests flush and dispose their managers before teardown, so debounced saves can no longer leak fixture accounts into the real local account store.

Internal

  • Corrected inverted dedupe-direction comments; the #161 marker-recovery test now genuinely exercises the deduped-out-active path; added explicit maskEmail: false coverage for formatPromptStatusText.
  • Synced the stale .release-please-manifest.json (6.0.06.2.0).

Full Changelog: v6.1.10...v6.2.0

v6.1.10

Choose a tag to compare

@ndycode ndycode released this 21 May 00:21
5a28241

v6.1.10

Added

  • Added marketplace-ready plugin icon metadata via .codex-plugin/plugin.json interface.composerIcon.
  • Added packaged assets/icon.svg for Codex marketplace display.
  • Added standalone terminal diagnostics under the existing oc-codex-multi-auth bin:
    • doctor
    • status
    • list
    • limits
    • dashboard
    • health --json
    • diag

Fixed

  • Fixed OAuth scope gating so normal OpenAI OAuth accounts only require baseline scopes: openid, profile, email, and offline_access.
  • Stopped connector-specific scopes from disabling otherwise valid OAuth logins.
  • Collapsed duplicate personal workspace/token account entries from the same login identity.
  • Preserved safe installer behavior while making unknown standalone commands fail with help instead of silently installing.

Validation

  • npm run typecheck
  • npm run lint
  • Focused Vitest suite: 302 tests passed
  • Full Vitest suite: 85 files passed, 2381 passed, 1 skipped
  • npm run build
  • npm run audit:ci
  • npm pack --dry-run
  • npm publish --dry-run
  • Packed tarball install smoke against real local account state
  • Real OpenCode plugin session verified codex-status tool execution

npm

  • Published: oc-codex-multi-auth@6.1.10
  • Dist tag: latest

v6.1.9

Choose a tag to compare

@ndycode ndycode released this 11 May 15:19

v6.1.9 - 2026-05-11

Fixed

  • Legacy Codex selectors such as gpt-5.2-codex, gpt-5.3-codex, and Spark now recover from entitlement-gated gpt-5-codex responses by falling back through the GPT-5.4 family.
  • Default fallback now continues from gpt-5.4 to gpt-5.4-mini and gpt-5.4-nano only when the chain started from gpt-5.5 or canonical gpt-5-codex, preserving strict behavior for direct GPT-5.4 selections.
  • Unsupported-model troubleshooting and configuration docs now document the canonical Codex fallback path and the CODEX_AUTH_DISABLE_CODEX_AUTO_FALLBACK=1 opt-out.
  • Current dependency security alert follow-ups are resolved.