Skip to content

Repository files navigation

CodexSwitcher

Build

CodexSwitcher is a native macOS menu bar app for managing Codex CLI and ChatGPT Desktop accounts.

The app keeps saved profiles separate, switches the active Codex credentials atomically, and shows usage limits for every saved plan.

Status: beta candidate. An unsigned ZIP can be distributed for public preview testing. Trusted Gatekeeper distribution still requires an Apple Developer signing identity and notarization credentials.

Screenshots

Profiles

CodexSwitcher profile list

Current profile list with grouped plans, quota windows, reset times, token totals, and update time.

Settings

CodexSwitcher settings

Menu bar display and appearance settings.

Menu bar

CodexSwitcher menu bar

Compact account and quota display. The account name is anonymised.

Features

  • Add accounts through an isolated Codex browser login.
  • Dismiss login status notices manually or let them disappear automatically.
  • Keep the current account active while a new login is in progress.
  • Cancel or time out an incomplete browser login without leaving the app stuck.
  • Save profile credentials in the macOS Keychain.
  • Switch between saved profiles without running a logout flow.
  • Replace auth.json atomically to avoid partial credentials.
  • Group multiple plans under one email account.
  • Rename the displayed email group without changing the email or credentials.
  • Show usage limits and token activity for the active account and saved profiles.
  • Show the account name, plan type, token total, and quota bars in the menu bar.
  • Quit CodexSwitcher from the menu bar popover.
  • Choose light, dark, or system appearance.
  • Detect ChatGPT Desktop and offer a restart after an account switch.

Requirements

  • macOS 14 or newer
  • Codex CLI or ChatGPT Desktop with Codex support
  • Xcode 16 or newer
  • XcodeGen

The app looks for Codex in these locations:

  • /opt/homebrew/bin/codex
  • /usr/local/bin/codex
  • /Applications/ChatGPT.app/Contents/Resources/codex

Build from source

brew install xcodegen
xcodegen generate
xcodebuild \
  -project CodexSwitcher.xcodeproj \
  -scheme CodexSwitcher \
  -configuration Debug \
  -destination platform=macOS \
  CODE_SIGNING_ALLOWED=NO \
  SWIFT_ENABLE_EXPLICIT_MODULES=NO \
  build

The generated Xcode project is ignored. Run xcodegen generate after changing project.yml.

Build a beta archive

The beta script generates a Release archive, verifies the bundle version, creates a zip file, and writes a SHA-256 checksum.

For a local or unsigned public preview build without Apple credentials:

./scripts/build_beta.sh --unsigned --skip-notarization

This creates dist/CodexSwitcher-0.1.0-unsigned.zip and matching metadata files. The -unsigned label must remain when the archive is shared publicly.

Users may need to choose Open Anyway in macOS Privacy & Security. Share the checksum with the archive and tell users to download it only from the official release page.

For a public beta, install a Developer ID Application certificate and configure a notarytool keychain profile first:

CODEXSWITCHER_DEVELOPMENT_TEAM=TEAMID \
CODEXSWITCHER_NOTARY_PROFILE=CodexSwitcher-notary \
CODEXSWITCHER_VERSION=0.1.0 \
CODEXSWITCHER_BUILD_NUMBER=1 \
./scripts/build_beta.sh

The public beta tag should be v0.1.0-beta.1. The numeric bundle version remains 0.1.0 because macOS bundle metadata does not use the tag suffix.

See docs/RELEASING.md for the complete release checklist.

Local configuration

CodexSwitcher uses ~/.codex by default. Set CODEX_HOME to use another absolute directory:

CODEX_HOME=/path/to/codex-home open /path/to/CodexSwitcher.app

The app does not copy the current auth.json into the repository.

Account and credential behavior

Add account

Add Account starts codex login with an isolated temporary CODEX_HOME. The browser login does not replace the current account. The new profile is saved only after the login succeeds.

Switch account

Switch replaces the active Codex auth.json atomically. Saved credentials remain in the macOS Keychain. If ChatGPT Desktop is running, the app shows a restart action so the desktop app can load the new account.

Rename email group

The Rename action is on the parent email row. It changes only a local display label stored in UserDefaults. It does not change the email, plan type, auth.json, or Keychain credentials.

Usage refresh behavior

Usage is fetched when the app starts, when the user presses Refresh, after account changes, and automatically every 60 seconds while the app is running. The app queries the Codex app server for account details, rate limits, and token activity.

The status-bar timer only updates local display text and relative-time labels. It does not fetch quota data every few seconds.

Each usage request has a 20-second timeout. A failed request shows Quota unavailable and does not change the saved credentials.

Local data

Data Location Purpose
Active Codex auth $CODEX_HOME/auth.json or ~/.codex/auth.json Credentials used by Codex
Saved profile credentials macOS Keychain service com.ahikmah.codexswitcher.profiles Credentials for account switching
Profile metadata UserDefaults key codexswitcher.profiles.v1 Profile identity and timestamps
Email display labels UserDefaults key codexswitcher.email-labels.v1 Local parent-account names
Login and usage temporary homes Temporary directories Isolated CLI operations; removed after use

CodexSwitcher does not print credential values in logs. Do not share auth.json, Keychain exports, or screenshots that contain account information.

Limitations

  • The app requires a working Codex CLI or the Codex executable inside ChatGPT Desktop.
  • Usage fields depend on the Codex app-server response. Some accounts may return no usage or token data.
  • An unsigned public beta may trigger a Gatekeeper warning and requires a manual user override.
  • Trusted public beta distribution requires an Apple Developer signing identity and a configured notarytool profile.
  • The beta packaging path creates a zip archive. Sparkle updates and a DMG installer are not configured.
  • The repository currently has build validation but no automated UI test suite.

Development workflow

  1. Change project.yml or files under CodexSwitcher/.
  2. Run xcodegen generate.
  3. Run the Debug build command above.
  4. Launch the generated app from DerivedData.
  5. Test account actions with a non-critical Codex account.

For a beta archive, use scripts/build_beta.sh and follow docs/RELEASING.md.

Before submitting a change, check:

  • Add Account success, cancel, timeout, and browser-abandon flows.
  • Switch between two profiles and verify the active email.
  • Usage display for the active and inactive profiles.
  • Parent email rename without an auth-file change.
  • Light, dark, and system appearance.
  • Menu bar settings and quota display.
  • ChatGPT Desktop restart behavior when the app is running.

See CONTRIBUTING.md for contribution rules and docs/ARCHITECTURE.md for the module boundaries.

Credits and origin

The account-switching workflow and menu bar product direction were inspired by CCSwitcher by XueshiQiao.

CodexSwitcher is a separate Codex implementation for Codex CLI and ChatGPT Desktop. This repository contains only CodexSwitcher source files and assets. It does not include the original CCSwitcher source or assets.

This project is not affiliated with OpenAI, Anthropic, or XueshiQiao.

License

This project is licensed under the MIT License. See LICENSE.

About

Native macOS menu bar app for managing Codex CLI and ChatGPT Desktop accounts.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages