Skip to content

Sawyer-Wu/CodexSwitch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

codex-switch

Terminal-only Codex provider switcher.

It switches Codex live config files without depending on cc-switch, while preserving machine-local settings such as trusted projects and sandbox sections.

Profile names are user-defined aliases. cs does not invent meaning from provider config; whatever you write after [profiles.<alias>] is what you use in commands.

Design

The script works in three layers:

  1. It snapshots your machine-local base config into the local Codex Switch state directory.
  2. It keeps provider definitions in a local ./profiles.toml.
  3. On each switch, it merges base-config.toml + selected profile and writes the live Codex config.

That means provider-specific keys are replaced, while unrelated local settings are preserved.

Tracked vs Local Files

Files committed to git:

  • codex_switch.py
  • install.sh
  • README.md
  • profiles.example.toml
  • tests/

Local-only files not committed:

  • ./profiles.toml
  • local Codex Switch state files
  • local Codex live config files

profiles.toml is ignored by git on purpose because it may contain real API keys.

Deploy On A New Machine

  1. Clone the repository and enter it:
git clone git@github.com:Sawyer-Wu/CodexSwitch.git
cd CodexSwitch
  1. Install the command:
./install.sh
  1. Initialize local files:
cs init
  1. Edit your local profile definitions:
vim ./profiles.toml
  1. Test one profile:
cs test <alias>
  1. Switch to it:
cs switch <alias>

Notes for a fresh machine:

  • If Codex live config already exists on that machine, cs init snapshots the non-provider part into the local base config.
  • If Codex live config does not exist yet, cs init still creates ./profiles.toml and an empty base snapshot. Your first cs switch <profile> will write the live config.

Quick Start

Install the command:

./install.sh

Initialize this machine:

cs init

cs init does two things:

  • creates or refreshes the local base snapshot from your current live Codex config if it exists
  • creates local ./profiles.toml from ./profiles.example.toml if ./profiles.toml does not exist yet

Profile Initialization

Recommended first-time setup:

  1. Run:
cs init
  1. Edit local ./profiles.toml:
vim ./profiles.toml
  1. Choose your own aliases and replace example endpoints and keys:
  • [profiles.work_primary] means the alias is work_primary
  • cs switch work_primary uses that alias
  • aliases are for humans; use names that make sense to you
  1. Choose one of these key styles:
  • api_key = "sk-..." for a direct local key
  • api_key_env = "ENV_NAME" if you prefer reading keys from environment variables
  1. Test before switching:
cs test <alias>
  1. Apply the switch:
cs switch <alias>

If you later change the machine-local shared part of your live Codex config, refresh the base snapshot:

cs init --refresh-base

Profile Format

./profiles.toml is a normal TOML file with these parts:

  • [defaults] is optional. default_profile is the alias used by cs switch with no argument.
  • [profiles.<alias>] defines one switch target.
  • <alias> is chosen by you. It is what cs list, cs show, cs test, and cs switch use.
  • Each profile must contain exactly one key source:
    • api_key = "sk-..."
    • or api_key_env = "ENV_NAME"
  • Each profile must contain config_fragment = '''...'''.
  • config_fragment must be valid TOML.
  • model_provider inside config_fragment is Codex's provider key, not your profile alias.

Example:

[defaults]
default_profile = "work_primary"

[profiles.work_primary]
api_key_env = "CODEX_WORK_PRIMARY_KEY"
config_fragment = '''
model_provider = "relay"
model = "gpt-5.4"

[model_providers.relay]
name = "Work Relay"
base_url = "https://relay-primary.example.com/v1"
wire_api = "responses"
requires_openai_auth = true
'''

In that example:

  • work_primary is your alias
  • relay is the provider key written into Codex config
  • cs switch work_primary switches to that profile

If you have two accounts or two endpoints for the same provider format, create two aliases:

[profiles.work_primary]
api_key_env = "CODEX_WORK_PRIMARY_KEY"
config_fragment = '''
model_provider = "relay"

[model_providers.relay]
name = "Work Relay"
base_url = "https://relay-primary.example.com/v1"
wire_api = "responses"
requires_openai_auth = true
'''

[profiles.work_backup]
api_key_env = "CODEX_WORK_BACKUP_KEY"
config_fragment = '''
model_provider = "relay"

[model_providers.relay]
name = "Work Relay"
base_url = "https://relay-backup.example.com/v1"
wire_api = "responses"
requires_openai_auth = true
'''

This repository includes a sanitized template in ./profiles.example.toml.

Commands

List profiles:

cs list

Show the current live config:

cs current

Show one profile:

cs show <alias>

Test the current live config:

cs test

Test one profile without switching:

cs test <alias>

Test all profiles:

cs test --all

Preview the rendered config:

cs switch <alias> --dry-run

Switch to the default profile:

cs switch

Switch to a specific profile:

cs switch <alias>

Output Style

  • cs list shows a compact table
  • cs current shows the active profile, provider, model, and endpoint
  • cs test shows only result and latency by default
  • cs test --verbose adds endpoint, provider, response id, preview, and retry attempts

Notes

  • Each switch backs up the previous live config.toml and auth.json.
  • cs current matches the live config back to a known profile when possible.
  • cs test sends a minimal real API request.
  • cs test prefers curl when available because some providers block Python default HTTP signatures behind Cloudflare.
  • Non-conflicting local config such as [sandbox_workspace_write] and [projects."..."] is preserved from the base snapshot.
  • Conflicting keys from the selected profile overwrite the base snapshot.
  • cs test supports retries for transient failures; recovered checks are shown as FLAKY.

Tests

python3 -m unittest discover -s tests

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors