Skip to content

feat(auth): activate managed accounts in native Codex - #449

Open
RainyPixel wants to merge 1 commit into
SaladDay:mainfrom
RainyPixel:feat/codex-account-use
Open

RainyPixel wants to merge 1 commit into
SaladDay:mainfrom
RainyPixel:feat/codex-account-use

Conversation

@RainyPixel

Copy link
Copy Markdown

auth default selects the managed/proxy account but leaves standalone Codex signed in to its previous account. Add auth use <account-id> and a matching Use in Codex TUI action for the next Codex process.

Activation preserves config.toml, MCP and skills, updates the current official provider's auth snapshot and managed default, and reports the live Codex account separately in status. Existing auth default behavior is unchanged. Validation respects the selected Codex profile and the official unified-history configuration; incompatible routing and credential stores are rejected before activation.

Persist native credential bundles, reuse unexpired access tokens across processes, and serialize credential mutations. OAuth refresh updates copies sharing the rotated credential; credentials accepted from temporary/shared Codex launches are retained for later account switches. Failed activation restores the prior login and provider snapshot. Already-running Codex processes are outside the switching contract: restart Codex or launch a new process; /new does not reload login.

Related to #252 (direct Codex activation; automatic account failover remains separate).

Validation (Rust 1.91.1, isolated HOME/config directories):

  • cargo fmt --check
  • cargo check --locked --lib --no-default-features
  • cargo test --locked --lib --no-default-features --no-run
  • 730 Codex unit tests and 17 managed-account UI tests passed.
  • auth_use, start_codex_shared, and settings_commands: all 11 integration tests passed, including separate-process activation/status, refresh retention, retry after partial publication and capture serialization.
  • cargo clippy --locked --all-targets -- -A clippy::reversed_empty_ranges passed; the allowance covers an unchanged upstream empty-range test at src/cli/tui/ui/home_chart.rs:806.

Six short-timeout tests under proxy::forwarder::tests::error_paths also fail on the unchanged upstream commit 8a5614d in a separate worktree on this machine. They are outside this patch. The final library run passed 4,340 tests (2 ignored), excluding only those six reproduced upstream failures.

Release smoke: synthetic B/A/B account selection was accepted by separate invocations of the installed native codex login status; config.toml remained byte-identical. This checks the native credential format without making requests with real accounts.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3065063713

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +622 to +624
let _state_guard = crate::services::state_coordination::acquire_restore_mutation_guard()
.await
.map_err(CodexOAuthError::IoError)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep proxy request authentication outside the mutation guard

When a Codex-OAuth proxy request reaches either token getter, these new calls wait for the global state-mutation guard. ProxyService::stop_with_restore acquires that same guard before calling stop_server_unlocked, while ProxyServer::stop waits for Axum's graceful-shutdown task; therefore, if shutdown acquires the guard while an in-flight request is entering authentication, the request cannot finish and shutdown cannot release the guard. Avoid acquiring this guard on the request path, or release it before awaiting graceful server shutdown.

Useful? React with 👍 / 👎.


let actions = [
texts::tui_key_set_default().to_string(),
crate::t!("Use in Codex", "在 Codex 中使用").to_string(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Highlight the delete action before executing it

After expanding this menu to three actions, the renderer still selects selected.min(1), although the key handler now permits index 2 and maps it directly to ManagedAuthRemove. Pressing Down twice therefore leaves “Use in Codex” visibly highlighted while Enter immediately deletes the account without confirmation; update the rendered selection bound to include the third row.

Useful? React with 👍 / 👎.

Comment on lines +7 to +9
let auth: Value =
serde_json::from_slice(&std::fs::read(crate::codex_config::get_codex_auth_path()).ok()?)
.ok()?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resolve an absent CODEX_HOME before reporting the active account

When CODEX_HOME points to a directory that has not been created yet, this path lookup ignores the environment override and falls back to ~/.codex; use_account explicitly creates the missing override directory before doing the same lookup, but status does not. Thus auth status --json and the TUI can report an account from the fallback home as active even though the configured Codex home is empty and the next Codex process will not use that login. Resolve the environment path directly or apply the same directory preparation without modifying credentials.

AGENTS.md reference: AGENTS.md:L67-L67

Useful? React with 👍 / 👎.

Comment on lines +474 to +480
let id_token = tokens.id_token.clone().or_else(|| {
account
.codex_auth
.as_ref()
.and_then(|a| a.pointer("/tokens/id_token"))
.and_then(|v| v.as_str())
.map(str::to_owned)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Import provider credentials before refreshing legacy accounts

For an account loaded from the pre-change refresh-token-only store, codex_auth is None, so this fallback cannot preserve its ID token. If that account's complete credentials exist only in a non-live official provider snapshot and a proxy/quota request refreshes it, the refresh path never imports that snapshot; when the OAuth response omits id_token (a case the new tests explicitly support), remember_token_response creates an incomplete bundle and reconcile_native_copies overwrites the previously complete provider snapshot with it. Import the matching provider credentials before refreshing, otherwise existing users can lose the snapshot needed by auth use and be forced to sign in again.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-09T16:03:56.069612Z 3065063 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

social4hyq pushed a commit to social4hyq/homebrew-core that referenced this pull request Sep 20, 2026
cc-switch-cli 5.10.5

Created-by: HarmonybrewBot
Commit-by: HarmonybrewBot
Merged-by: HarmonybrewBot
Description: Created by `brew bump`

---

Created with `brew bump-formula-pr`.<details>
  <summary>release notes</summary>
  <pre># CC Switch CLI v5.10.5

v5.10.5 adds opt-in shared Codex sessions, per-model reasoning controls, local quota reset times, and GPT-6 Astra pricing. It also fixes model-catalog persistence, user-owned catalog paths, Windows session scanning, SQL imports, and Chat Completions compatibility.

## Added

- **Codex / Shared Sessions**: Add opt-in `cc-switch start codex <provider> --shared-sessions` on macOS/Linux. Providers keep separate credentials and configuration while sharing persistent native session history and session locks. Includes [#440](SaladDay/cc-switch-cli#440), addressing [#436](SaladDay/cc-switch-cli#436).
- **Codex / Per-Model Reasoning**: Expose supported reasoning levels and a default for each model in both TUI model-catalog editors, with the existing Auto behavior and contextual help. Includes [#442](SaladDay/cc-switch-cli#442), addressing [#441](SaladDay/cc-switch-cli#441).
- **Providers / PatewayAI**: Add the PatewayAI sponsor preset and its provider setup support.

## Changed

- **Quota / Reset Times**: Show quota reset timestamps in the local timezone, with UTC offsets and remaining time in CLI text; add compact reset countdowns to the TUI. Raw JSON timestamps and upstream quota calculations retain their existing semantics. Includes [#456](SaladDay/cc-switch-cli#456), fixing [#445](SaladDay/cc-switch-cli#445).
- **Pricing / GPT-6 Astra**: Add standard prices per million tokens: $10 input, $50 output, $1 cached input, and $12.50 cache writes. Missing entries are added without replacing user-customized prices or restoring user-deleted entries. Includes [#460](SaladDay/cc-switch-cli#460), fixing [#459](SaladDay/cc-switch-cli#459).

## Fixed

- **Codex / Model Mapping Persistence**: Preserve stored model catalogs and per-model reasoning settings during provider switches and temporary-launch capture. Fixes [#447](SaladDay/cc-switch-cli#447).
- **Codex / User-Owned Catalogs**: Preserve custom `model_catalog_json` paths when generating a cc-switch catalog. Includes [#454](SaladDay/cc-switch-cli#454).
- **Codex / OpenCode Go Reasoning**: Recognize the OpenCode Zen gateway before applying model-vendor reasoning defaults, and constrain effort to the model's catalog settings. Fixes [#443](SaladDay/cc-switch-cli#443).
- **Proxy / Chat Completions Compatibility**: Convert null or missing message content to an empty string when translating Responses requests to Chat Completions, preserving tool payloads and multimodal content. Fixes the Azure compatibility issue in [#448](SaladDay/cc-switch-cli#448).
- **Windows / Session Scanning**: Open existing session-cache files with the access required for synchronization, avoiding `Access denied (os error 5)` without truncating their contents. Includes [#455](SaladDay/cc-switch-cli#455), fixing [#450](SaladDay/cc-switch-cli#450).
- **Configuration / SQL Import**: Acquire the sync lock before synchronous import and live-config projection to avoid a nested-executor panic when importing or restoring SQL backups. Fixes [#453](SaladDay/cc-switch-cli#453).
- **TUI / Claude Quick Config**: Correct the displayed item total in the quick-configuration menu. Fixes [#435](SaladDay/cc-switch-cli#435).

## Upgrade notes

- The database schema remains at v18; upgrading from v5.10.4 requires no schema migration.
- Shared Codex sessions are opt-in and limited to macOS/Linux. Keep the persistent `.cc-switch-launches/` directories, allow only one shared launch per provider, and close a session before continuing it through another provider. See the [shared-session usage notes](https://github.com/SaladDay/cc-switch-cli/blob/v5.10.5/README.md) for argument restrictions and cross-provider limitations.
- GPT-6 Astra uses the existing standard-rate calculator. Long-context and service-tier pricing are outside this release's pricing change.

## Update

```bash
cc-switch update
```

Or use the macOS/Linux installer:

```bash
curl -fsSL https://github.com/SaladDay/cc-switch-cli/releases/latest/download/install.sh | bash
```

## Thank you

Thank you to everyone who opened an issue or pull request, shared diagnostics, reviewed a change, or joined a discussion. This list covers issues and pull requests active since v5.10.4, including participants in their earlier discussions.

| Contributor | Issues and pull requests |
| --- | --- |
| [@6UOOON9](https://github.com/6UOOON9) | [#447](SaladDay/cc-switch-cli#447) |
| [@ChanthMiao](https://github.com/ChanthMiao) | [#409](SaladDay/cc-switch-cli#409) |
| [@Curious-r](https://github.com/Curious-r) | [#441](SaladDay/cc-switch-cli#441), [#443](SaladDay/cc-switch-cli#443) |
| [@czfhhh](https://github.com/czfhhh) | [#454](SaladDay/cc-switch-cli#454) |
| [@Devin-Pi](https://github.com/Devin-Pi) | [#358](SaladDay/cc-switch-cli#358), [#446](SaladDay/cc-switch-cli#446) |
| [@dividduang](https://github.com/dividduang) | [#358](SaladDay/cc-switch-cli#358) |
| [@GMOogway](https://github.com/GMOogway) | [#433](SaladDay/cc-switch-cli#433) |
| [@HappyLiang12](https://github.com/HappyLiang12) | [#448](SaladDay/cc-switch-cli#448) |
| [@jinjiwu](https://github.com/jinjiwu) | [#436](SaladDay/cc-switch-cli#436), [#445](SaladDay/cc-switch-cli#445) |
| [@JounQin](https://github.com/JounQin) | [#457](SaladDay/cc-switch-cli#457) |
| [@kelvkhiu](https://github.com/kelvkhiu) | [#444](SaladDay/cc-switch-cli#444) |
| [@moonjoke001](https://github.com/moonjoke001) | [#358](SaladDay/cc-switch-cli#358) |
| [@netcatty](https://github.com/netcatty) | [#450](SaladDay/cc-switch-cli#450) |
| [@neverdie0710](https://github.com/neverdie0710) | [#451](SaladDay/cc-switch-cli#451) |
| [@odup](https://github.com/odup) | [#453](SaladDay/cc-switch-cli#453) |
| [@paopjian](https://github.com/paopjian) | [#439](SaladDay/cc-switch-cli#439) |
| [@RainyPixel](https://github.com/RainyPixel) | [#449](SaladDay/cc-switch-cli#449) |
| [@SaladDay](https://github.com/SaladDay) | [#440](SaladDay/cc-switch-cli#440), [#442](SaladDay/cc-switch-cli#442), [#455](SaladDay/cc-switch-cli#455), [#456](SaladDay/cc-switch-cli#456), [#460](SaladDay/cc-switch-cli#460) |
| [@suntory1](https://github.com/suntory1) | [#358](SaladDay/cc-switch-cli#358) |
| [@SyaJask](https://github.com/SyaJask) | [#358](SaladDay/cc-switch-cli#358) |
| [@tangjunyi1](https://github.com/tangjunyi1) | [#458](SaladDay/cc-switch-cli#458) |
| [@TheBoYang](https://github.com/TheBoYang) | [#432](SaladDay/cc-switch-cli#432) |
| [@tianzhuwei](https://github.com/tianzhuwei) | [#358](SaladDay/cc-switch-cli#358) |
| [@Tonystarkw12](https://github.com/Tonystarkw12) | [#434](SaladDay/cc-switch-cli#434) |
| [@u1544096979](https://github.com/u1544096979) | [#437](SaladDay/cc-switch-cli#437), [#438](SaladDay/cc-switch-cli#438) |
| [@wangsiqidahaoren](https://github.com/wangsiqidahaoren) | [#459](SaladDay/cc-switch-cli#459) |
| [@wbbo](https://github.com/wbbo) | [#435](SaladDay/cc-switch-cli#435) |
| [@xiaoshidebug](https://github.com/xiaoshidebug) | [#452](SaladDay/cc-switch-cli#452) |

We also thank [@farion1231](https://github.com/farion1231) and upstream CC-Switch contributors, including [@zayokami](https://github.com/zayokami) for the [OpenCode Zen reasoning fix](farion1231/cc-switch#6123), and [@misaka-myu](https://github.com/misaka-myu) for the [user-owned catalog fix](farion1231/cc-switch#6087).

Some acknowledged reports and proposals remain open or are not included in this release; a thank-you does not imply that an issue is fixed or a pull request is merged.

See the [full changelog](https://github.com/SaladDay/cc-switch-cli/blob/v5.10.5/CHANGELOG.md) and [all changes since v5.10.4](SaladDay/cc-switch-cli@v5.10.4...v5.10.5).
</pre>
  <p>View the full release notes at <a href="https://github.com/SaladDay/cc-switch-cli/releases/tag/v5.10.5">https://github.com/SaladDay/cc-switch-cli/releases/tag/v5.10.5</a>.</p>
</details>
<hr>

See merge request: Harmonybrew/homebrew-core!20243
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant