cmux NEXT Accounts: Sign Out per provider, and logins open in front of Settings

Merged
TE
7d ago
+993-272

In cmux NEXT Settings > Accounts, Re-authenticate typed claude auth login or codex login into a new terminal tab in the main window, which sat behind the Settings window. Nothing seemed to happen, so the page looked read-only (Leo, 2026-10-19). There was also no way to sign out of a provider.

What changes

  • The provider's login, logout and key pages now open in the main window, and the window comes to the front (AppServices.inFrontPane; ReauthPlan.run picks the terminal line or the page). Sign In in Settings > Agents uses the same path.
  • Sign Out on each provider row runs the CLI's own logout: codex logout or claude auth logout. Copilot has none: its detected sign-in is the editor's, and gh auth logout would only sign out the GitHub CLI. It appears only when the sign-in comes from the CLI's own sign-in file (auth.json, .credentials.json) or Keychain item, the ones the logout removes; a Codex config.toml provider, a Claude settings.json key or helper, or an API key saved in .claude.json gets none (AIProvider.signOutRemoves). The logout runs in a cmux tab, so the app never goes inactive. The row checks the sign-in again when the Settings window gets focus or its tab becomes visible (the page sends focus) or when the app becomes active.
  • A sign-in that comes from a shell variable such as $CLAUDE_CODE_OAUTH_TOKEN has no Sign Out. Its row, signed in or expired, says the shell provides the sign-in and it must be removed from the shell setup (the copy names no variable).
  • With no local pane in the main window (only SSH or Cloud panes), Sign Out and Re-authenticate open nothing; the row is freed and says "Open a workspace on this Mac first, then try again.", and the refusal reaches the page, palette or CLI.
  • 3 new strings, translated into all 21 locales.

Tests

CmuxNextAppTests/AccountsSignOutTests covers the logout commands. Sign Out on a saved sign-in runs the logout and marks the row as reauthenticating. Focusing the Settings window frees the row and re-detects once. A shell-variable sign-in has no Sign Out and shows the note. ReauthPlan.run types a command and opens a page. webviews accounts.test.tsx: a window focus sends focus, and nothing after unmount. The first commit adds only these tests (red); the second adds the fix.

This PR does not depend on #22376 (Sign In to cmux in the default browser). Both add cases to AccountsPageAction in AccountsPageState.swift; whichever lands second keeps both (cmux(_:) and signOut(_:), windowFocused).

No confirmation before Sign Out: the CLI's own login brings the sign-in back, and Re-authenticate sits next to it.

Capture

Settings > Accounts in the showcase build at the final head (962f72f5869c): the ChatGPT / Codex row shows Sign Out next to Re-authenticate.

Capture steps-c25135a8da at 962f72f5869c (fleet build, capture mini, text checked for private data)

LightDark
lightdark

🤖 Generated with Claude Code